git

git

Git常用操作总结 - 知乎 (zhihu.com)

架构图

在 Git 中,工作流程通常分为三个区域:工作区、暂存区和本地仓库。

  1. 工作区:工作区是你在本地电脑上实际操作文件的区域,包含了你的项目文件和目录。

  2. 暂存区:暂存区是一个临时存储区域,用于存储 Git 要提交到本地仓库的文件列表。当你用 git add 命令将修改过的文件添加到暂存区时,Git 会记录下这些修改,并将其保存在暂存区中。

  3. 本地仓库:本地仓库是 Git 存储所有提交过的文件的位置,包含了项目历史的所有版本。当你使用 git commit 命令将修改提交到本地仓库时,Git 会将当前暂存区中的文件保存为一个新的版本,并且将其记录在本地仓库中。

在这个三个区域中,Git 对于每一次修改都会跟踪它们的状态,并将其记录在提交历史中。当你执行 git add 命令时,Git 会将这些修改添加到暂存区,等待下一次 git commit 命令将其提交到本地仓库中。通过这种方式,Git 能够有效地跟踪每个版本的变化,让你轻松管理你的项目代码。

作用描述

Git 中的三个区域(工作区、暂存区和本地仓库)分别承担了不同的作用,具体如下:

  1. 工作区:工作区是项目实际的工作目录,其中包含了项目的源代码、配置文件等,你可以在工作区中进行文件的修改和添加。

  2. 暂存区:暂存区也称为 Git 的 “Index”,是一个缓存区,它保存了即将提交到本地仓库的内容。你可以使用 git add 命令将工作区的修改添加到暂存区,等待提交到本地仓库。

  3. 本地仓库:本地仓库存储了 Git 所有的版本历史,包括每个版本的代码、提交信息等。你可以使用 git commit 命令将暂存区的修改提交到本地仓库。

在实际使用中,工作区、暂存区和本地仓库通常结合起来进行管理,Git 提供了一系列命令用于操作这些区域:

  1. git add:将修改后的文件添加到暂存区。

  2. git commit:将暂存区的文件提交到本地仓库。

  3. git push:将本地仓库中的代码推送到远程仓库。

  4. git fetch:从远程仓库下载最新的代码,但是不会自动合并代码。

  5. git merge:将某个分支合并到当前分支,自动合并代码。

  6. git pull:从远程仓库下载最新的代码,并且立即将其合并到本地分支。

在实际场景中,你可以在工作区中修改文件,添加/删除文件,使用 git add 命令将修改暂存到暂存区,使用 git commit 命令将暂存区的修改提交到本地仓库。当你想要将本地修改推送到远程仓库时,可以使用 git push 命令将本地仓库的代码推送到远程仓库,也可以使用 git fetchgit merge 命令将最新代码合并到当前分支后再进行推送。当你想要更新本地分支时,可以使用 git fetchgit merge 命令来获取最新代码并合并到当前分支。

常见命令

下面是 Git 中常用的一些命令和它们的作用:

  1. git init:初始化一个新的 Git 仓库。

  2. git clone:从远程仓库克隆代码到本地仓库。

  3. git add:将工作区中的修改添加到暂存区。

  4. git commit:将暂存区中的修改提交到本地仓库。

  5. git status:查看工作区、暂存区和本地仓库的当前状态。

  6. git diff:查看文件的修改差异。

  7. git log:查看本地仓库的提交历史。

  8. git push:将本地仓库中的代码推送到远程仓库。

  9. git fetch:从远程仓库下载最新的代码,但是不会自动合并代码。

  10. git merge:将某个分支合并到当前分支,自动合并代码。

  11. git pull:从远程仓库下载最新的代码,并且立即将其合并到本地分支。

  12. git branch:查看、创建、删除和切换分支。

  13. git checkout:切换分支或还原项目文件。

  14. git stash:将当前修改暂时保存,并回到项目的另一个状态。

  15. git tag:给提交打标签。

  16. git remote:管理远程仓库。

  17. git config:管理 Git 配置。

  18. git revert:还原某个提交的修改。

  19. git reset:回退版本并删除提交。

  20. git rm:删除工作区中的文件。

这些命令是 Git 中的基本命令,涵盖了 Git 中常见的操作,建议你先掌握这些命令,在之后的实践中学习其他更高级的命令。

config 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
[remote "origin"]
url = https://github.com/spring-projects/spring-boot.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master

文件解读

以上示例代码展示了一个 Git 仓库的配置文件,其中方括号内的是配置项名,等号后面是该配置项的值。以下是各个配置项的含义解释:

  1. repositoryformatversion:Git 仓库的格式版本。

  2. filemode:控制 Git 是否记录文件的权限和可执行状态。如果设置为 true,Git 将记录文件的权限和可执行状态;如果设置为 false,Git 将忽略文件的权限和可执行状态。

  3. bare:是否是裸仓库。如果设置为 true,表示这是一个裸仓库,Git 不会在仓库目录中保存工作树,而只保存 Git 数据库。如果设置为 false,表示这是一个非裸仓库,Git 会保存工作树和 Git 数据库。

  4. logallrefupdates:是否记录所有引用的更新日志。如果设置为 true,Git 将记录所有引用的更新日志,包括标签、分支等;如果设置为 false,Git 将只记录 HEAD 引用的更新日志。

  5. symlinks:是否检查符号链接。如果设置为 true,Git 将检查符号链接;如果设置为 false,Git 将忽略符号链接。

  6. ignorecase:是否忽略文件名大小写。如果设置为 true,Git 将忽略文件名大小写;如果设置为 false,Git 将区分文件名大小写。

  7. remote “origin”:定义了一个远程仓库,名称为 origin。

  8. url:远程仓库的 URL 地址,表示该仓库的数据存储在哪个服务器上,通过哪个协议访问。

  9. fetch:拉取远程仓库的分支和标签。代码中的 fetch 值 +refs/heads/*:refs/remotes/origin/* 表示拉取远程仓库中的所有分支,* 表示标记任何分支名称或通配符。

  10. branch “master”:定义了一个本地分支,名称为 master。

  11. remote:指定本地分支对应的远程分支,例如这里的 origin,意味着将本地的 master 分支与远程仓库 origin 上的 master 分支关联起来。

  12. merge:指定从远程分支合并代码到本地分支的方式。代码中的 merge 值 refs/heads/master 表示将远程仓库的 master 分支合并到本地的 master 分支。

这是一个 Git 仓库的基本配置示例,其中远程仓库的 URL、分支关联和合并规则是 Git 中常见的概念。了解这些配置项及其含义,可以帮助我们更好地理解和使用 Git。

解决本地、远程差异过大

当本地代码与远程代码差异较大时,可能会出现版本冲突或无法合并的情况。这通常需要进行一些手动操作来解决。下面是一些可能有助于解决版本冲突的方法:

  1. 把远程仓库的最新代码拉取到本地

首先,需要确保本地仓库与远程仓库的代码历史保持一致,如果本地仓库落后于远程仓库的代码,可能会导致版本冲突。可以使用以下命令将最新的远程代码拉取到本地:

1
git fetch origin
  1. 切换分支

如果本地仓库和远程仓库有不同的分支,需要切换到相应的分支,以确保操作的分支历史一致。例如,切换到本地 master 分支:

1
git checkout master
  1. 使用合适的合并策略

运行 git merge 命令时,可以使用不同的合并策略来处理版本冲突。例如,可以使用 git merge --strategy=recursive 命令来使用递归合并策略,该策略尝试自动解决大多数版本冲突情况。如果自动解决失败,可以使用手动解决或其他适合的策略。

  1. 手动解决冲突

如果自动合并失败,或者需要进行手动解决冲突,则需要打开代码编辑器并编辑包含冲突的文件。冲突标记 <<<<<<<>>>>>>> 会在代码文件中显示冲突部分的起始和结束位置。手动编辑代码以解决冲突,删除标记并保存冲突解决方案。完成冲突修改后,使用以下命令将更改提交到本地仓库中:

1
2
git add <突文件名>
git commit -m "解决版本冲突"
  1. 强制推送到远程仓库

在解决版本冲突后,需要将本地更改推送到远程仓库。如果本地更改与远程历史版本存在冲突,可以使用以下命令强制将本地更改推送到远程仓库:

1
git push -f origin branch-name

该命令将会覆盖远程仓库上的历史版本,并且将本地更改作为新的版本推送到远程仓库上。这将永久删除远程仓库上的历史版本,应该谨慎使用。

强制合并

如果在使用 git pull 命令或 git merge 命令将本地更改合并到远端代码时出现合并冲突或问题,可以使用以下命令强制合并远程仓库:

1
2
3
4
git fetch --all
git reset --hard origin/master
git pull origin master --allow-unrelated-histories
git push --force origin master

上述命令执行的操作如下:

  1. git fetch --all:拉取远程所有分支的最新代码。
  2. git reset --hard origin/master:将本仓库的 master 分支重置为远程仓库的最新代码。
  3. pull origin master --allow-unrelated-histories:强制将最新远程仓库的代码和本地仓库的代码合并。--allow-unrelated-histories 参数可以允许合并两个独立开发的仓库。
  4. git push --force origin master:将强制合并后的本地代码推送到远程仓库。

需要注意的是,强制合并会覆盖原有的提交历史,并且会永久性地删除所有现有的、与最新远程代码不同的提交历史。因此,需谨慎使用此操作,确保对代码进行备份,并且在执行此操作之前先进行评估和测试,以确保不会引入任何不必要的问题或错误。

覆盖

如果远程仓库中的代码需要完全覆盖本地代码,可以使用以下方法:

  1. 备份本地代码

在进行任何更改之前,最好先备份本地代码,以便在需要时可以还原。

  1. 强制拉取最新代码

使用以下命令强制拉取远程仓库中的最新代码:

1
2
git fetch --all
git reset --hard origin/master

这将从远程仓库中拉取最新的代码,并将本地仓库的 master 分支设置为与远程仓库完全相同。所有本地未提交的更改都将被覆盖。

  1. 强制推送到远程仓库

使用以下命令将本地代码强制推送到远程仓库:

1
git push --force origin master

该命令将强制将本地更改覆盖远程仓库中的所有代码。需要注意的是,这将永久删除远程仓库上的历史版本,应该谨慎使用。

需要注意的是,这种操作会对本地未提交的更改造成极大影响,将其覆盖并删除。只有在非常确定进行操作时,才应该使用该方法。如果需要保存原有的本地更改,可以在覆盖之前将其备份并在覆盖后恢复。

进阶业务

img

1. Git 进阶使用

1.1. 版本历史更改

1.1.1. 最近一次 commit 的 message 修改

使用如下命令就可以对最近一次 commit 的 message 进行变更了

1
git commit --amend 

1.1.2. 老旧 commit 的 message 修改 — rebase + reword

输入如下命令

1
git rebase -i hash_value # hash_value,是需要的 commit 的父亲 commit 的 hash_value

之后会发生一系列交互

img

比如你想修改的是 9885fd5 这个 commit 对应的message,那么将 pick 改为 reword 或者 r(看下面的注释信息),然后保存退出。之后就跳到了修改 message 的文档了,在这里输入改变之后的 message 保存退出即可。

img

注意:这种方式修改之后会导致该 commit 及后面 commit 的 hash_value 都被改变掉,所以不适合团队集成开发中使用。

1.1.3. 把连续的多个 commit 合并成一个 — rebase + squash

输入如下命令,

1
git rebase -i hash_value # hash_value 是要合并的 commit 的父亲 commit

输入之后会发生一系列的交互,如下所示,

img

假如我想要把上面两个 commit 合并成一个,需要使用 squash ,版本历史中较早的 commit 在上面,较晚的 commit 在下面,进行合并的话,是把较早的保留,较晚的合并到较早中去,所以要将上述两个 commit 进行合并的话,修改为如下所示,并保存退出

img

之后会进入另一个交互,在下面填写更改之后的 message 信息,保存退出之后即可。

img

1.1.4. 把间隔的几个 commit 合并成一个 — rebase + squash

与上述类似,就是把间隔的 commit 移到一块即可。同样首先是输入如下命令,hash_value 是间隔多个 commit 中的最开始那个 commit 的父亲 commit 的 hash_value

1
git rebase -i hash_value

之后会进入交互界面,

img

比如想要合并 760df21 和 2234131 这两个 commit的话,那么修改为如下内容,保存退出即可

img

之后会进入修改 message 的页面,修改之后保存退出即可

img

1.1.5. rebase 其他操作

上述都使用了 git rebase 的命令,rebase 的意思是说改变基底,把版本历史中的某些 commit 给修改了。

1
2
3
git rebase origin/master # 把当前分支基于 origin/master 做 rebase 操作,也就相当于把当前分支的东西加到 origin/master 中

git rerere # 记录冲突解决的方式,然后可以在 rebase 的时候反复应用,可以和 rebase 结合用

1.1.6. 碎碎念

  1. 上述对 commit 的修改和合并,会导致该 commit 及后面 commit 的 hash_value 都被改变掉,所以不适合团队集成开发中使用。
  2. 假如 commit 修改和合并这一步操作完成之后不是直接进入修改 message 的页面,请根据提示进行进一步操作,比如git rebase --continue
  3. 假如合并的包含了根 commit,那么 hash_value 则是根 commit 的 hash_value,之后在交互文档中把根 commit 填入即可,只需要填入要操作的名称和 hash_value 即可。
  4. 在合并 commit 中,假如一个 commit 没有被 pick 的话,比如注释了或者删除,那么在完成一系列操作中之后,这个 commit 将会被丢弃。如下图所示,275a765 这个 commit 被注释掉了的话,那么在完成之后,这个 commit 将会被丢弃。

img

1.2. 回滚操作 — git reset

1.2.1. 暂存区恢复成和 HEAD 一样

1
2
git reset HEAD
git reset HEAD -- file_name1 file_name2 # 暂存区部分文件变得跟 HEAD 一样

比如一开始的话,HEAD 、暂存区和工作目录都是一样的,都是状态A,并且 readme*.md 文件都已经被跟踪起来了。下面我们修改 readme3.md 文件,之后把它 add 到暂存区。那么这样子工作目录和暂存区都是状态 B,而 HEAD 是状态 A。那么使用上述命令之后,会将暂存区恢复成状态 A。

img

1.2.2. 工作目录恢复为和暂存区一样

1
2
git checkout -- file_name # 工作目录中指定文件恢复为和暂存区一样
git checkout -- *|. ## 工作目录全部文件恢复为和暂存区一样

img

1.2.3. 回滚到某个 commit

1
2
git reset --hard hash_value # 把 HEAD、暂存区、工作目录都回滚到 hash_value 所代表的 commit 中。
git reset --hard # 把暂存区里面的修改去掉,也就是让暂存区、工作目录默认恢复到 HEAD 的位置

img

img

1.2.4. 碎碎念

  • 工作目录内容的修改使用 git checkout
  • 暂存区内容的修改使用 git reset
  • 版本历史的修改使用 git rabase

1.3. 工作目录、暂存区的更改状态保存下来

这个应用在开发中临时加塞了紧急任务的情况,可以把处理了一半,还在工作目录、暂存区的更改状态保存下来。

1
2
3
4
git stash # 把相应的修改内容给存下来,之后 git status 查看的话又变为什么都没改变的了
git stash list # 查看存下来的内容
git stash apply # 存下来的内容又恢复了,但是存下来的内容还在 stash 中
git stash pop # 存下来的内容恢复了,但是存下来的内容也没了

img

1.4. git merge

将两个分支或者两个 commit 进行 merge,merge 之后也会产生一个 commit

1
2
3
git merge branch_name1 branch_name2
git merge hash_value1 hash_value2
git merge --squash # 以 squash 方式进行 merge

在 merge 的过程中有时候会产生冲突,比如两个分支修改或者两个 commit 修改的是同文件的同一区域,那么就会发生冲突,那么会在相应文件冲突的地方有提示,大致如下所示。

1
2
3
4
5
<<<<<<< HEAD
windows
=======
root
>>>>>>> origin/master

通过协商和决定之后,确定文件最终内容,同时把上述内容删除。之后 git addgit commit 即可。

  • 不同人修改了不同文件不会产生冲突。比如说两个人维护一个仓库,一个人修改 A 文件,另一个修改 B 文件,那么 merge 的话不会产生冲突,直接将内容合并在一起。
  • 不同人修改了同文件不同区域不会产生冲突。merge 的话直接将内容合并在一起。
  • 同一文件改成不同的文件名会产生冲突。同上,一个人把文件名改成了 rename1,另一个人把文件名改成了 rename2,那么 merge 会发生冲突,需要进行协商确定最终的文件名。
  • 不同人修改了同文件的同一区域会产生冲突。merge 的话因为不能确定保留谁的内容所以会产生冲突。

1.5. 分离头指针

分离头指针的例子如下所示,上面提到切换到某个分支的用法是

1
$ git checkout branch_name

那么假如把 branch_name 变成了 hash_value,那么这个就相当于“分离头指针”(PS:个人的理解是相当于创建了一个匿名 branch,这个匿名的 branch 是从 hash_value 的地方分出来的)

1
$ git checkout hash_value

之后的 commit 都是基于这个分离头指针的位置开始的,这些 commit 都没有基于某个 branch,相当于都是“游离”状态的。那么当切回到某个分支之后,这些 commit 都会被当成垃圾一样清理掉。如果这些 commit 很重要,那么请把这些 commit 跟某个 branch 绑在一起。

另外分类头指针也是可以用的,比如我们先用分离头指针进行一波修改和测试,如果测试不错,那么就把这些修改的 commit 添加成 branch。

1.6. .gitignore — 指定不需要 git 管理的文件

git 更多是管理代码的版本控制,而代码构建出来的东西可以不用管理,因为这些是可以复现的。那么 .gitignore 这个文件就是告诉 git 哪些文件不需要被纳入版本控制系统的,也就是相当于会被忽视。

1
2
doc  # doc 文件和 doc 目录都不会被管理
doc/ # 只指定 doc 目录不会被管理,但是 doc 文件没被说明,假如 doc 在的话,还是会被管理起来的

上面内容的有效范围是在整个项目中,即包括子目录等

img

img

.gitignore 可以借助 github 创建仓库时生成,常用的 .gitignore 如下所示,自己写的时候也值得参考一波:https://github.com/github/gitignore
另外想要 git 不管理某些文件,只能在 .gitignore 文件中指定;

1.7. 团队合作注意事项

如果你的 git 仓库是跟其他人一起维护的,那么请注意一下几点:

  • git push -f 不能使用
    -f 是 force 的意思,强制性把本地的 push 上去,就相当于本地的内容强制变成了远端的东西
  • 公共的分支严禁拉倒本地做 rebase 操作的,因为一旦做了 rebase 操作之后,历史的 commit 就变了,但是其他人那边还是老旧的 commit,他们是基于老旧的 commit 做事情的,而你是几于新的 commit 做事情了,那么就相当于是两条分支了。所以记住了,不能向集成分支执行变更历史操作,建议的方式是在现在 commit 的基础之上再做调整。
    比如 master 和 temp 分支刚开始指向的地方是一样的,如下所示,有两个用户都是基于 temp 分支做提交的

img

A 在 temp 分支上做 rabase 操作,那么 temp 分支就会和 master 分开。如下图所示,

img

然而在另一个人,还是基于如下情况做的 commit 等,那么这样,就出现问题了

img

2. git 中的对象及其操作

git 中的对象有三种:commit、tree、blob。下面对这三种对象进行阐述。

2.1. commit

每次执行git commit都会创建一个commit对象,一个 commit 对象只包含一个 tree 对象,这个 tree 对象是 .git 所在父目录的对象, 那么这样子的话,一次 commit 就相当于把当前目录的情况给记录下来了。

2.2. tree

目录的对象,那么由于目录中可以包含目录,也可以包含文件,所以 tree 对象可以包含 tree 对象,也可以包含 blob 对象。

2.3. blob

blob 是一个文件的具体对象,比如png图像,css文件,这些文件都会对应一个blob对象,可以说是 git 对象中最基本的。另外,blob 跟文件名一点关系都么有,只要文件内容相同,不管文件名叫什么,blob 只有一份。

新建的Git 仓库中,有且仅有一个 commit,仅仅包含了 /doc/readme,请问内含多少个 tree,多个 blob?
含两个 tree,一个 blob。首先是 git 仓库所在目录是一个 tree (也就是 /doc/readme 的父目录),doc 是一个tree,而 readme 文件是唯一 blob。

2.4. 对象的相关操作

1
2
3
4
git cat-file -t|p|s hash_value # 显示版本库对象的内容,类型及大小信息
git cat-file -t hash_value # 查看版本库对象的类型
git cat-file -p hash_value # 查看版本库对象的内容
git cat-file -s hash_value # 查看版本库对象的大小

3. .git 目录探索

3.1. HEAD 文件

HEAD文件的内容显示了 HEAD 当前所指的分支信息,通过下面的内容可以佐证上面 HEAD 说到的一点:HEAD 指向的是某个分支,但通过查看分支文件内容可以发现里面其实是 commit 的 hash_value,也就是说 HEAD 实际指向的是某个commit。

img

使用 git checkout 命令之后,查看HEAD 文件的内容

img

3.2. config 文件

存放本地仓库(local)相关的配置信息,假如之前设置了 local 下的 user.name ,那么会在这个文件中存储相关的内容等信息。修改 config 文件中 user.name 配置项的内容,使用命令查看到的也是修改之后的。

3.3. refs 目录

3.3.1. heads 子目录

目录中包含的是各分支信息,每一个文件的内容都是 hash value,这个是值是该分支最后一次 commit 的 hash_value 值

1
2
3
4
.../.git/refs/heads# ls
master temp temp2
.../.git/refs/heads# cat master
9ef147d58eb7e09987cf5ce92254b1600ac92cd9

3.3.2. tags 子目录

里面显示的是标签的信息,Git 仓库可以有很多标签,项目开发到一定程度,是一个关键的成果了,比如开发到 v1.0,那可以打上一个标签了。

3.4. objects 目录

存放对象的目录。git 中的对象都是由 40 位字符组成,前两位字符用来当 object 目录中子目录名,后 38 位做文

业务

img

树形结构展示 分支

1
git log --graph --oneline --decorate --all

这个命令将以图形化的方式展示通过rebase合并分支后的提交历史。每个提交记录显示为一行,包括提交的哈希值和提交消息。

–oneline选项将以简洁的单行格式显示提交记录,

–graph选项将以图形化的方式显示分支合并和分支关系,

–decorate选项将显示分支和标签的名称。

请注意,使用rebase操作可能会改变提交历史,因此在进行rebase操作之前,请确保你理解其影响,并在必要时备份你的代码。

如果你需要更详细的信息,可以使用搜索引擎进行进一步的学习和了解,例如搜索”Git rebase”。

git checkout – 未提交修改

在某些情况下,Git允许你在有未提交的修改的情况下切换分支。这是因为Git使用了一种称为”工作树”的机制来管理你的代码库。

工作树是指你当前工作目录中的文件和文件夹。当你在Git中进行修改时,这些修改会反映在工作树中的文件中。当你切换分支时,Git会尝试将工作树中的文件与要切换到的分支中的文件进行合理的合并。

如果你有未提交的修改,Git会尝试将这些修改应用到要切换的分支中。如果这些修改与要切换的分支没有冲突,Git会成功地将你的修改应用到新的分支中。这样,你就可以在切换分支后继续工作,而不会丢失你的修改。

然而,如果你的修改与要切换的分支中的文件发生冲突,Git将会阻止你切换分支,以避免冲突的发生。在这种情况下,你需要先解决冲突,然后再切换分支。

需要注意的是,虽然Git允许你在有未提交的修改的情况下切换分支,但这并不意味着这是一个良好的实践。最好的做法是在切换分支之前,先提交或保存你的修改,以确保代码的完整性和一致性。

如果你对Git的工作原理和分支切换有更深入的疑问,可以使用搜索引擎进行进一步的学习和了解,例如搜索”Git working tree”和”Git switch branch with uncommitted changes”。

强行更新本地分支

要拉取远程分支并强制替换本地分支,可以使用以下命令:

1
2
git fetch --all
git reset --hard origin/<远程分支名>

这两个命令的作用分别是:

git fetch –all:从远程仓库获取最新的分支和提交信息,但不会自动合并或修改本地分支。

git reset –hard origin/<远程分支名>:将本地分支重置为指定的远程分支,并且强制替换本地分支的提交历史和文件内容。

请注意,执行这个命令会丢失本地分支上未提交的更改,所以在执行之前请确保你已经备份了重要的更改。

另外,<远程分支名>是指远程仓库中的分支名称,例如origin/main或origin/feature-branch。你可以根据实际情况替换为你要拉取的远程分支的名称。

如果你需要更详细的信息,可以使用搜索引擎进行进一步的学习和了解,例如搜索”git fetch”和”git reset”。

1. 同一电脑存在多个 Git 账号

假设我们在同一电脑上拥有多个 Git 账号,例如公司内部使用的是 Gitlab,个人使用的是 Github 或者 Gitee。那就会遇到一种情况,上班时想给个人开源项目提交代码,但是 Git 绑定的是公司的账号。

在这种情况下,我们可以让 Git 绑定多个不同的 ssh key,每个 ssh key 对应一个不同的 Git 服务器。

生成第一个 ssh key:

1
ssh-keygen -t rsa -C "xxx@xxx.xx"

生成第二个 ssh key:

1
ssh-keygen -t rsa -f path/to/file  -C "xxx@xxx.xx"

参数 -f 表示指定生成的文件名, path/to/file 是文件名路径,例如 ~/.ssh/id_rsa_github

执行上面两条命令后会得到两对 ssh key。

img

这时还需要在该目录下创建一个 config 文件。写上以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_github # 私钥文件路径

Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_rsa

Host gitee.com
HostName gitee.com
User git
IdentityFile ~/.ssh/id_rsa_github

这个配置文件的作用是指定私钥文件位置。

然后我们可以把第一个密钥配置到公司的 Gitlab 服务器,并把相应的 Git 账号和邮箱设成全局。

1
2
git config --global user.name "xxx"
git config --global user.email "xxx@xxx.xx"

然后把另一对 ssh key 配置到 Github 上,并在电脑上的 Github 项目里单独配置 Git 用户姓名和邮箱。

1
2
git config user.name "xxx"
git config user.email "xxx@xxx.xx"

至此,我们就大功告成了。可以同时在不同的 Gitlab 和 Github 项目上提交代码了。

2. 修改 git commit 记录的用户姓名和邮箱

假设电脑上同时存在 Gitlab 和 Github 项目,其中 Gitlab 用户信息已经全局配置过了。现在新拉了一个 Github 项目,提交了一个 commit 并且已经推送到了远程仓库。这时发现该项目未配置 Github 的用户信息,默认使用的是全局账号 Gitlab 的用户信息。

我们可以通过以下命令来修改最近一次提交的用户信息:

1
git commit --amend --author="username <yyy@ccc.com>" --no-edit

username 是用户名,用户邮箱旁边的 <> 符号不能去掉。修改后再执行 git push -f 推送到远程仓库。

如果要修改多个 commit 的用户信息怎么办? 可以通过以下的代码来修改:

1
2
3
4
5
6
7
8
9
git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_EMAIL" = "tanguangzhi@shiqiao.com" ];
then
GIT_AUTHOR_NAME="woai3c";
GIT_AUTHOR_EMAIL="411020382@qq.com";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD

将上述代码中的用户名和邮箱修改后,保存为 .sh 格式的文件,例如 edit.sh。然后在项目根目录下执行 sh edit.sh(windows 下可右击-> Git Bash Here -> sh edit.sh),再执行 git push -f 强推即可。

3. 修改某个历史记录的消息

假设当前分支有 a b c d 四个 commit 记录:

1
2
3
4
a
b
c
d

如果你想对 c 记录的消息进行修改。可以使用 git rebasec 记录换到最前面,然后使用 git commit --amend 对其消息进行修改。

具体操作步骤

执行以下命令对记录 d 前面的三个 commit 进行编辑:

1
git rebase -i d

进行 vim 编辑界面后,移动光标到 c 记录上,按下 dd 剪切该记录,然后移动光标到第一行,按下 p 粘贴,再输入 :wq 保存。

执行 git commit --amend 对切换顺序后的 c 记录进行修改。进入 vim 编辑界面后,按 i 进行修改,然后按 ESC,再输入 :wq 保存。

最后用前面讲过的 git rebase 操作将 c 记录恢复到原来的位置。

img

这个过程的执行结果就和上图一样,这是当前分支修改后和远程分支上的对比,箭头指向的记录消息就是修改后的消息。

如果想把修改后的记录同步到远程仓库,这时只要执行 git push -f 就可以了。

第二种方式

  1. 使用 git checkout -b <branchName> c 从指定记录切出一个分支
  2. 在新分支使用 git commit --amend 修改提交消息
  3. 使用 git cherry-pickb a 记录,追加到新分支(注意,这里的 b a 提交记录是指原分支上的 commit,也就是选取原分支上的 b a 记录添加到新分支上,这样新分支上的记录就变成了 a b c,并且 c 记录的提交消息在第二步已经修改过)
  4. 使用 git checout 原分支名 切换回原来的分支,再执行 git rebase <branchName> 合并新分支,最后强推到远程分支

4. 挑选指定的 commit 进行合并

假设你切了一个 bugFix 分支来修复线上 bug,经过一段时间的努力后终于将 bug 修复了。但是为了调试(加了很多 debug 代码)或其他原因,bugFix 上多了很多无用的记录消息。

1
2
3
commit3: 修复登录 bug
commit2: 添加 debug 语句
commit1: 添加 console 语句

例如上面的三个记录,前面的两个记录添加了很多调试代码,在最后一个记录终于修复了 bug,并且删除了调试代码。这时如果直接将 bugFix 分支合到 master 分支,就会把调试的记录也合并进来。

这时可以使用 git cherry-pick 只将最后一个记录合并到 master 分支。或者使用 git rebase 将 bugFix 分支另外两个记录抛弃,然后再合并。

5. ^~ 的区别

操作符 ^~ 符一样,后面也可以跟一个数字。 ~ 表示向上返回几代记录。

但是该操作符后面的数字与 ~ 后面的不同,并不是用来指定向上返回几代,而是指定合并提交记录的第几个父记录。

Git 默认选择合并提交的“第一个”父记录,在操作符 ^ 后跟一个数字可以改变这一默认行为。

单看文字可能不太好理解,下面看几个示例。

img

执行命令 git checkout main^ 回到第一个父记录(原来 HEAD 指向 c3,现在指向 c1)。

img

执行命令 git checkout main^2 回到第二个父记录(原来 HEAD 指向 c3,现在指向 c2)。

最后再来一个更复杂的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
G   H   I   J
\ / \ /
D E F
\ | / \
\ | / |
|/ |
B C
\ /
\ /
A
A = = A^0
B = A^ = A^1 = A~1
C = A^2 = A^2
D = A^^ = A^1^1 = A~2
E = B^2 = A^^2
F = B^3 = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2 = B^^2 = A^^^2 = A~2^2
I = F^ = B^3^ = A^^3^
J = F^2 = B^3^2 = A^^3^2

通过这些示例我们还能发现 ~n 等于连续的 n 个 ^

6. git revertgit reset 的区别

git reset 可以回退 Git 的历史记录。例如当前分支有三个记录,并且 HEAD 指向 c 记录:

1
2
3
c <- HEAD
b
a

如果我们想回退到 b 记录,只要执行 git reset b 就可以了:

1
2
b <- HEAD 
a

接着使用 git push -f 将回退版本后的分支强制推送到远程仓库,这样本地分支和远程分支就同步了。

1
git push -f

git revert 也可以撤销记录,只不过它撤销的记录不会消失,这一点和 git reset 不一样。git reset 撤销的记录就跟消失了一样。

现在我们用 git revert 来重新演示下刚才的操作:

1
2
3
c
b
a

如果我们执行 git revert b,则会在当前分支上再生成一个新的 commit 记录,变成 a b c b',这个 b' 的状态和记录 b 是一样的。

也就是说,执行 git reset b 后,当前的分支记录会变成 a b。执行 git revert b 后,当前的分支记录会变成 a b c b'

如果你想让别人知道你撤销过记录,就使用 git revert,因为它会留下撤销的记录,否则用 git reset

本地分支关联远程分支

1
2
3
要将本地新建的分支与远程同名分支进行关联,可以按照以下步骤进行操作:

1. 首先,使用以下命令创建并切换到本地新建的分支:

git checkout -b

1
2
3
4

请将`<branch-name>`替换为你要创建的分支的名称。

2. 接下来,使用以下命令将本地分支与远程同名分支进行关联:

git push -u origin
1
2
3
4
5
6

这个命令会将本地分支推送到远程仓库,并将本地分支与远程同名分支进行关联。`-u`参数会将远程分支设置为本地分支的上游分支,这样在以后的推送和拉取操作中,Git会自动将本地分支与远程分支进行同步。

请确保你已经与远程仓库建立了连接,并且有权限推送到远程仓库。

通过执行以上步骤,你可以将本地新建的分支与远程同名分支进行关联,并在以后的操作中方便地进行推送和拉取。

1
2
3
如果你已经在本地的`master`分支上与远程分支建立了连接,而现在想要在本地的`dev`分支上与远程同名分支进行关联,可以按照以下步骤进行操作:

1. 首先,切换到`dev`分支:

git checkout dev

1
2

2. 然后,使用以下命令将本地`dev`分支与远程同名分支进行关联:

git branch –set-upstream-to=origin/dev dev
1
2
3
4
5
6

这个命令会将本地`dev`分支与远程`dev`分支进行关联,使得在以后的推送和拉取操作中,Git会自动将本地分支与远程分支进行同步。

请确保你已经与远程仓库建立了连接,并且有权限推送到远程仓库。

通过执行以上步骤,你可以将本地的`dev`分支与远程同名分支进行关联,并在以后的操作中方便地进行推送和拉取。

无用提交删除

git revert

分支日志过多,合并

在Git中,可以使用git rebasegit squash命令将多个提交合并为一个提交,以解决日志过度的问题。

以下是一种常见的方法:

  1. 首先,使用以下命令查看当前分支的提交历史:

    1
    git log
  2. 确定你要合并的提交范围。假设你要将最近的3个提交合并为一个提交。

  3. 使用以下命令执行交互式的rebase操作:

    1
    git rebase -i HEAD~3

    这将打开一个交互式的编辑器,显示你要合并的提交列表。

  4. 在编辑器中,将除第一个提交外的其他提交的行前的pick改为squashs。保存并关闭编辑器。

    例如,如果你要将第2个和第3个提交合并到第一个提交中,你可以将第2个和第3个提交的行前的pick改为squashs

  5. 在新的编辑器中,编辑合并后的提交消息。保留第一个提交的消息,删除其他提交的消息。保存并关闭编辑器。

  6. Git会将你的提交合并为一个新的提交,并更新提交历史。

  7. 最后,使用以下命令将合并后的提交推送到远程仓库:

    1
    git push --force origin <分支名>

    请将<分支名>替换为你要推送的分支名称。

请注意,合并提交会修改提交历史,因此在进行此操作之前,请确保与团队成员进行充分的沟通和协调,并确保你了解合并提交的影响。

冲突解决

当您在工作区进行修改时,在执行 Git 中的操作(如合并或拉取)时可能会出现冲突。以下是 Git 中解决本地工作区冲突的详细步骤:

  1. 查看冲突

请使用 git status 命令查看是否存在冲突文件。

1
git status

通常,会出现以下提示语:

1
2
3
4
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
  1. 手动解决冲突

找到导致冲突的文件。使用文本编辑器打开文件,并修复所有括号和标记。将文件修改合并为单个文件,保存您的更改。

通常,解决冲突后文件会包含以下几个元素:

  • 确定您要保留的代码
  • 删除不必要的代码
  • 处理如何合并代码并解决冲突
  • 收集您的代码并使其可以正常工作
  1. 手动合并文件时调用编辑器

如果您正处理的文件是一个长文件,或者是一个包含许多冲突的文件,您可能需要进行更高级的冲突解决策略,比如使用编辑器。请在 Git 中配置一个编辑器,并在解决冲突时调用它。您可以使用以下命令进行全局设置:

1
$ git config --global core.editor "vanilla -w"

这会将 vanilla 编辑器作为您默认的 Git 编辑器,解决冲突时会自动启动编辑器。

  1. 标记文件为已解决(已暂存)

解决代码冲突后,您需要将文件标记为已解决以通知 Git 代码冲突已经被解决。

1
git add <file>
  1. 提交代码

完成所有修改并标记所有文件后,您需要提交代码。

1
git commit

需要注意的是,解决代码冲突是一个经验问题,并且不同的应用场景可能需要不同的决策。要进一步了解如何解决 Git 中的冲突问题,可以参考 Git 官方文档,并尝试使用示例文件进行练习。

进入编译器

如果您在手动解决 Git 冲突时需要启动编辑器,则可以使用以下命令:

1
git mergetool

这个命令会打开您已配置为默认编辑器的工具,帮助您更轻松地理解和解决冲突的位置。在编辑器中,您可以将修改和合并的部分并排放置在一个文件中,以便进行比较和修改。

需要注意的是,使用 git mergetool 命令之前,请先确保您的系统上已经安装了一个 Git 可识别的合适编辑器。如果您希望使用特定的编辑器作为默认编辑器,可以将其通过 git config 命令设置为默认编辑器。

如果您尚未为 Git 设置编辑器,您可以使用以下命令将默认编辑器设置为 vim:

1
git config --global core.editor vim

需要注意的是,vim 是一种高级的编辑器,需要一定的学习曲线和一些命令行知识。如果您不熟悉使用 vim,可以考虑使用其他文本编辑器来代替。不过,在使用 vim 之前,您可以阅读这篇关于 vim 基础的教程,以了解如何进行文件冲突解决。

当您运行 git mergetool 命令且 Git 系统无法识别默认的 Git 工具时,您会看到上面的消息。如果您已经设置了 git difftool,可以使用 git mergetool --tool-diff 命令来尝试调用 Git 明确的 Meld 或您自己的视觉 diff 工具来启动合并工具。

如果您还没有安装 Git 可识别的合适工具,可以使用以下步骤为您的操作系统选择可用于解决 Git 冲突的合适工具:

  1. 对于 Windows 系统,您可以使用 Visula Studio Code、Beyond Compare、WinMerge、TortoiseMerge 或 比较推等编辑器。

  2. 对于 Linux / macOS 系统,您可以使用 Emacs、Meld、Vim 或 KDiff3、p4merge等编辑器。

然后,您可以将您选择的工具添加到您的 Git 配置中。假设您选择的是 Beyond Compare,则可以使用以下命令:

1
2
git config --global merge.tool bc3 
git config --global mergetool.bc3.path "c:/program files/beyond compare 4/bcomp.exe"

以上命令将 Beyond Compare 设置为默认的 Git 工具。

需要注意的是,解决代码冲突是一个经验问题,并且不同的应用场景可能需要不同的决策。要进一步了解如何解决 Git 中的冲突问题,可以参考 Git 官方文档,并尝试使用示例文件进行练习。

git clone 指定文件地址 / 分支

在执行git clone命令时,可以通过使用参数来指定要克隆的文件或目录地址。具体步骤如下:

  1. 打开要克隆的仓库的网页地址,如https://github.com/user/repo,复制该网页地址。

  2. 打开终端,进入要克隆到的目录下。

  3. 执行以下命令,将仓库的指定文件或目录克隆到当前目录下:

    1
    git clone <url> --depth 1 --branch=<branch> --single-branch <path>

    其中,是仓库的网页地址,是仓库的分支名称,是要克隆的文件或目录地址。

    例如,如果要克隆仓库user/repo的master分支下的docs目录,可以使用以下命令:

    1
    git clone https://github.com/user/repo.git --depth 1 --branch=master --single-branch docs
  4. 执行完命令后,会在当前目录下生成一个名为的目录,其中包含了要克隆的文件或目录。

注意事项:

  1. 如果要克隆的文件或目录在仓库的根目录下,可以将减去,直接使用仓库名称作为克隆后的目录名称。

  2. 如果克隆的文件或目录在Git仓库中发生变化,需要重新克隆才能获取更新的内容。

PR提交流程 / MR规范

MR

“MR”规范是Git代码仓库中的一种代码审查(Code Review)方式,全称为“Merge Request”规范。它是GitLab中一种常用的代码协作方式,可以为开发者提交的代码提供审核、评论和修改等功能,以帮助团队更好地协作和管理代码。由于GitLab非常流行,因此”MR”规范也得到了广泛的应用。

“MR” 的基本流程如下:

  1. 开发者在自己的分支(Branch)上完成代码编写之后,将代码推送到Git代码仓库中。

  2. 此时开发者可以发起一个“Merge Request”,用于请求其他成员对其改动进行审核、修改和讨论。

  3. 其他成员可以在“Merge Request”页面对代码进行审查、添加评论,并提供修改建议。

  4. 开发者可以对代码进行修改,并在第3步中与其他成员进行讨论,以最终确定代码是否可以合并到主代码库中。

“MR”规范有助于团队更好地协作和管理代码,促进代码质量的提高,同时也减轻了团队负责人和管理人员的工作负担。

PR

PR(Pull Request)是Git和GitHub中常用的协作方式,而MR(Merge Request)则是GitLab中的一种协作方式。二者的基本流程类似,都用于请求其他开发者或团队成员对自己所做的更改进行查看、审核和合并。但二者的具体实现和用法略有不同,主要区别如下:

  1. 用法不同:PR 是Git/GitHub的一种代码协作方式,而MR 是GitLab的一种代码协作方式。

  2. 实现方式略有不同:PR 是将自己的版本库 clone 下来,在本地进行修改后用命令推送到GitHub上的公共版本库,并在GitHub上发起合并请求。MR 是通过GitLab自带的Web界面,将开发者的新代码分支(branch)提交到GitLab上的公共版本库,并在GitLab的Web界面上发起合并请求。

  3. 用法范围不同:GitHub 包括了码云等国内众多的代码托管服务。而 GitLab 是一个服务端搭建和企业自用的 Git 代码库平台,在国内用户上面并不多。

虽然二者实现方式略有差异,但是其本质上都是代码协作方式,都帮助协作开发者更好地协作和管理代码。开发者可以根据具体情况在Git/GitHub或GitLab中选择合适的方式,以达到更好的协作效果。

分支命名规范

  1. master 分支:代表主分支,包含最新版本的代码。一般情况下,master 分支应该保持稳定,不应该直接进行修改,而是通过其他分支(例如 dev-*)或打标签(Tag)的方式来实现。

  2. dev-* 分支:代表开发分支,是开发者进行开发工作的主要分支。例如,开发者可以在 dev-login 分支上进行登录功能开发,或在 dev-payment 分支上进行支付功能开发。

  3. hotfix-* 分支:代表紧急修复分支,通常用于紧急修复生产环境中的问题。例如,如果出现了一个支付系统崩溃的问题,开发者可以创建 hotfix-payments-crash 分支来进行修复。

  4. feature/* 分支:代表新特性分支,通常用于添加新功能或实现某些新的业务需求。例如,如果需要添加一个新的商品推荐功能,开发者可以在 feature/product-recommendation 分支上进行开发。

  5. release/* 分支:代表发行/发布分支,通常用于准备发布新版本的代码。例如,开发者可以在 release/v1.2.3 分支上进行版本号为 v1.2.3 的代码准备和测试。

注意,以上仅是对一些常见的命名规范的示例,具体的分支命名规范还需要根据项目和团队的实际情况进行定制。在使用 GitHub 进行项目开发时,你可以选择自己的命名规范,并利用 GitHub 提供的分支管理、Pull Request、代码审核及合并等功能,有效地帮助团队进行协作和代码管理。

“-“ 与 ‘/’

在 Git 中,分支名是使用正斜线(即 /)分割的,而在一些实现中,例如 GitHub 或 GitLab,使用短横线(即 -)作为分隔符也是常见的。这两种分隔符虽然不同,但其实质是一样的,都是用于区分分支名的不同部分。

在实际应用中,使用 /- 作为分隔符没有本质区别,但根据团队的实际情况,可以选择一个更适合自己习惯和管理风格的分隔符。例如,部分团队习惯使用 /,因为它类似于 Unix 路径分隔符,更符合 Unix 系统下目录结构的习惯;而另一些团队则更喜欢 -,因为它看起来更加简洁易懂。

需要注意的是,如果你在使用 GitLab 或 GitHub 等服务时,尽管你可以使用 - 来定义分支名称,但是在在命令行上进行相关的 Git 操作时,需要使用 /,否则会出现错误。另外,在进行一些持续集成和部署工具集成时,也需要使用 /,包括 Jenkins、Travis CI 和 GitLab CI 等工具。

综上所述,使用 /- 的区别并不大,取决于具体的团队和个人习惯,以及引用的工具和系统的要求。

commit 提交规范

Git Commit Log规范推荐 | 木小丰的博客 (lesofn.com)

1
2
3
4
5
[oceanus-tapd][scope][type] subject

body

footer

格式说明(注意tapd、type和subject为必选项):

1
2
3
4
5
6
TapdId为TAPD的需求/bug单
scope: 可选项,表示本次 commit 波及的范围,如果项目中不存在多个模块,score可以省略,如:galileo,如果项目中存在多个模块,需要加上范围,如:oceanus-common、flink
type: typecommit 的类,诸如 feat、fix、docs、style 等
subject: 简明扼要的阐述下本次 commit 的主旨,在原文中特意强调了几点 1. 使用祈使句 2. 首字母不要大写 3. 结尾无需添加标点
body: 使用祈使句,在主体内容中我们需要把本次 commit 详细的描述一下,比如此次变更的动机
footer: 描述下与之关联的 issue 或 重大改

Type的类别说明:

1
2
3
4
5
6
7
8
feat: 添加新特性
fix: 修复bug
docs: 仅仅修改了文档
style: 仅仅修改了空格、格式缩进、都好等等,不改变代码逻辑
refactor: 代码重构,没有加新功能或者修复bug
perf: 增加代码进行性能测试
test: 增加测试用例
chore: 改变构建流程、或者增加依赖库、工具等

例子

1
2
3
4
5
6
1. galileo常规特性开发
[95082695][feat] 日志上传到COS
2. galileo bug修复
[95082695][fix] 修复DescribeProperClsLogset 接口 logset为空时返回值不合法问题
3. oceanus-common代码重构
[95082695][cluster-model][refactor] 事件模块 jobAlert 等接口重构
  • 注意:
    • [oceanus-tapd][scope][type] 使用小写
    • 每个特性尽量使用单个commit就好

用户名、邮箱配置

在使用 Git 时,为了方便管理代码和协作开发,需要在 Git 中配置个人信息,包括 username 和 email。下面是在 Git 中配置个人信息的步骤:

  1. 打开 Git 命令行工具(如 Git Bash),输入以下命令并运行:

    1
    2
    git config --global user.name "Your Username"
    git config --global user.email "your_email@example.com"
  2. “Your Username” 和 “your_email@example.com“ 分别替换为你的用户名和邮箱地址即可。

  3. 如果想要检查配置是否成功,可以输入以下命令:

    1
    git config --list

    运行后,将会显示当前 Git 配置的详细信息,包括 “user.name” 和 “user.email” 配置项。

注意:在 Git 中,–global 标志的作用是将配置应用于当前用户的所有项目中,如果只想在当前项目中使用,可以去掉 –global 标志。

4、查看

1
2
git config user.name
git config user.email

文档

中文文档 : 翻译 – git-config (apachecn.org)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
git help -a
See 'git help <command>' to read about a specific subcommand

Main Porcelain Commands
add Add file contents to the index
am Apply a series of patches from a mailbox
archive Create an archive of files from a named tree
bisect Use binary search to find the commit that introduced a bug
branch List, create, or delete branches
bundle Move objects and refs by archive
checkout Switch branches or restore working tree files
cherry-pick Apply the changes introduced by some existing commits
citool Graphical alternative to git-commit
clean Remove untracked files from the working tree
clone Clone a repository into a new directory
commit Record changes to the repository
describe Give an object a human readable name based on an available ref
diff Show changes between commits, commit and working tree, etc
fetch Download objects and refs from another repository
format-patch Prepare patches for e-mail submission
gc Cleanup unnecessary files and optimize the local repository
gitk The Git repository browser
grep Print lines matching a pattern
gui A portable graphical interface to Git
init Create an empty Git repository or reinitialize an existing one
log Show commit logs
maintenance Run tasks to optimize Git repository data
merge Join two or more development histories together
mv Move or rename a file, a directory, or a symlink
notes Add or inspect object notes
pull Fetch from and integrate with another repository or a local branch
push Update remote refs along with associated objects
range-diff Compare two commit ranges (e.g. two versions of a branch)
rebase Reapply commits on top of another base tip
reset Reset current HEAD to the specified state
restore Restore working tree files
revert Revert some existing commits
rm Remove files from the working tree and from the index
shortlog Summarize 'git log' output
show Show various types of objects
sparse-checkout Reduce your working tree to a subset of tracked files
stash Stash the changes in a dirty working directory away
status Show the working tree status
submodule Initialize, update or inspect submodules
switch Switch branches
tag Create, list, delete or verify a tag object signed with GPG
worktree Manage multiple working trees

Ancillary Commands / Manipulators
config Get and set repository or global options
fast-export Git data exporter
fast-import Backend for fast Git data importers
filter-branch Rewrite branches
mergetool Run merge conflict resolution tools to resolve merge conflicts
pack-refs Pack heads and tags for efficient repository access
prune Prune all unreachable objects from the object database
reflog Manage reflog information
remote Manage set of tracked repositories
repack Pack unpacked objects in a repository
replace Create, list, delete refs to replace objects

Ancillary Commands / Interrogators
annotate Annotate file lines with commit information
blame Show what revision and author last modified each line of a file
bugreport Collect information for user to file a bug report
count-objects Count unpacked number of objects and their disk consumption
difftool Show changes using common diff tools
fsck Verifies the connectivity and validity of the objects in the database
gitweb Git web interface (web frontend to Git repositories)
help Display help information about Git
instaweb Instantly browse your working repository in gitweb
merge-tree Show three-way merge without touching index
rerere Reuse recorded resolution of conflicted merges
show-branch Show branches and their commits
verify-commit Check the GPG signature of commits
verify-tag Check the GPG signature of tags
whatchanged Show logs with difference each commit introduces

Interacting with Others
archimport Import a GNU Arch repository into Git
cvsexportcommit Export a single commit to a CVS checkout
cvsimport Salvage your data out of another SCM people love to hate
cvsserver A CVS server emulator for Git
imap-send Send a collection of patches from stdin to an IMAP folder
p4 Import from and submit to Perforce repositories
quiltimport Applies a quilt patchset onto the current branch
request-pull Generates a summary of pending changes
send-email Send a collection of patches as emails
svn Bidirectional operation between a Subversion repository and Git

Low-level Commands / Manipulators
apply Apply a patch to files and/or to the index
checkout-index Copy files from the index to the working tree
commit-graph Write and verify Git commit-graph files
commit-tree Create a new commit object
hash-object Compute object ID and optionally creates a blob from a file
index-pack Build pack index file for an existing packed archive
merge-file Run a three-way file merge
merge-index Run a merge for files needing merging
mktag Creates a tag object with extra validation
mktree Build a tree-object from ls-tree formatted text
multi-pack-index Write and verify multi-pack-indexes
pack-objects Create a packed archive of objects
prune-packed Remove extra objects that are already in pack files
read-tree Reads tree information into the index
symbolic-ref Read, modify and delete symbolic refs
unpack-objects Unpack objects from a packed archive
update-index Register file contents in the working tree to the index
update-ref Update the object name stored in a ref safely
write-tree Create a tree object from the current index

Low-level Commands / Interrogators
cat-file Provide content or type and size information for repository objects
cherry Find commits yet to be applied to upstream
diff-files Compares files in the working tree and the index
diff-index Compare a tree to the working tree or index
diff-tree Compares the content and mode of blobs found via two tree objects
for-each-ref Output information on each ref
for-each-repo Run a Git command on a list of repositories
get-tar-commit-id Extract commit ID from an archive created using git-archive
ls-files Show information about files in the index and the working tree
ls-remote List references in a remote repository
ls-tree List the contents of a tree object
merge-base Find as good common ancestors as possible for a merge
name-rev Find symbolic names for given revs
pack-redundant Find redundant pack files
rev-list Lists commit objects in reverse chronological order
rev-parse Pick out and massage parameters
show-index Show packed archive index
show-ref List references in a local repository
unpack-file Creates a temporary file with a blob's contents
var Show a Git logical variable
verify-pack Validate packed Git archive files

Low-level Commands / Syncing Repositories
daemon A really simple server for Git repositories
fetch-pack Receive missing objects from another repository
http-backend Server side implementation of Git over HTTP
send-pack Push objects over Git protocol to another repository
update-server-info Update auxiliary info file to help dumb servers

Low-level Commands / Internal Helpers
check-attr Display gitattributes information
check-ignore Debug gitignore / exclude files
check-mailmap Show canonical names and email addresses of contacts
check-ref-format Ensures that a reference name is well formed
column Display data in columns
credential Retrieve and store user credentials
credential-cache Helper to temporarily store passwords in memory
credential-store Helper to store credentials on disk
fmt-merge-msg Produce a merge commit message
hook Run git hooks
interpret-trailers Add or parse structured information in commit messages
mailinfo Extracts patch and authorship from a single e-mail message
mailsplit Simple UNIX mbox splitter program
merge-one-file The standard helper program to use with git-merge-index
patch-id Compute unique ID for a patch
sh-i18n Git's i18n setup code for shell scripts
sh-setup Common Git shell script setup code
stripspace Remove unnecessary whitespace

External commands
askpass
askyesno
credential-helper-selector
credential-manager-core
flow
lfs
update-git-for-windows
=======
>>>>>>> master


## Git 本地分支无法更新问题

先提交,在pull,保持版本一直





## git stash

[Git(六):git stash 命令 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/117553180)

存储当前尚未提交的代码,

git stash pop,取出存储的代码





## git rebase

两个分支合并

[(8条消息) git rebase详解(图解+最简单示例,一次就懂)_风中一匹狼v的博客-CSDN博客](https://blog.csdn.net/weixin_42310154/article/details/119004977)





# 业务描述



## git 删除远程分支信息

要删除远程分支,可以使用 `git push` 命令加上 `--delete` 参数。语法如下:

git push –delete

1
2
3
4
5
6
7
8

其中:

- `<remote-repository>` 是远程仓库的名称,如 `origin`。
- `<branch>` 是要删除的远程分支的名称,如 `dev-9.4`。

例如,要删除名为 `dev-9.4` 的远程分支,可以执行以下命令:

git push origin –delete dev-9.4

1
2
3
4
5

在执行命令后,Git 将会从远程仓库中删除指定的分支。需要注意的是,执行该命令后,该分支上原有的提交记录也将被删除。

如果你想在本地同时删除该远程分支的本地跟踪分支,可以在删除远程分支后执行以下命令:

git branch -d -r origin/dev-9.4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

其中,`-d` 表示删除本地跟踪分支,`-r` 表示删除远程跟踪分支。执行该命令后,本地的 `origin/dev-9.4` 跟踪分支也将被删除。

如果该远程分支存在于其他开发者的本地仓库中,他们需要执行 `git pull` 命令,从远程仓库拉取最新的分支列表。当他们尝试从远程仓库中拉取该分支时,Git 会自动将其从他们的本地仓库中删除。





## 提交 push request流程

1、在主仓库中拉去分支

2、在本地工作区修改代码

3、git fetch 拉去远程最新分支情况

4、git add . git commit git push origin master:dev -- 一套流程:添加本地仓库代码,修改远程仓库代码

5new merge request : 发起合并请求

6、合并通过,merge到master中



## git commit guide

代码提交规范使用当前业界应用的比较广泛的 Angular Git Commit Guidelines ,但是会有少许的变化
具体格式

[oceanus-tapd][scope][type] subject
body

footer
格式说明(注意:tapd、type和subject为必选项):

1
2
3
4
5



Type的类别说明:

feat: 添加新特性
fix: 修复bug
docs: 仅仅修改了文档
style: 仅仅修改了空格、格式缩进、都好等等,不改变代码逻辑
refactor: 代码重构,没有加新功能或者修复bug
perf: 增加代码进行性能测试
test: 增加测试用例
chore: 改变构建流程、或者增加依赖库、工具等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

例子

1. galileo常规特性开发
[95082695][feat] 日志上传到COS
2. galileo bug修复
[95082695][fix] 修复DescribeProperClsLogset 接口 logset为空时返回值不合法问题
3. oceanus-common代码重构
[95082695][cluster-model][refactor] 事件模块 jobAlert 等接口重构
注意:

[oceanus-tapd][scope][type] 使用小写
每个特性尽量使用单个commit就好



## 更新本地代码

git -c credential.helper= -c core.quotepath=false -c log.showSignature=false fetch origin --recurse-submodules=no --progress --prune

这个命令是用来从Git远程仓库(`origin`)中获取最新的代码,并更新本地的代码库。该命令由以下组成部分:

1. `-c credential.helper=`: 禁用Git凭证助手,以便在没有任何凭证助手的情况下执行此命令。

2. `-c core.quotepath=false`: 禁用路径名中的引号。

3. `-c log.showSignature=false`: 不显示提交者的GPG签名。

4. `fetch origin`: 从远程仓库(origin)中获取最新的代码。

5. `--recurse-submodules=no`: 不递归获取子模块的更新。

6. `--progress`: 显示进度信息,以便您可以在下载期间查看操作进展。

7. `--prune`: 删除本地不存在的远程分支信息。

总之,这个命令是一个Git命令,用于从Git远程仓库获取最新的代码,以及更新本地库。





## Angular Git Commit Guidelines -- 提交规范

[Commit message 和 Change log 编写指南 - 阮一峰的网络日志 (ruanyifeng.com)](https://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html)


git
http://example.com/2023/06/01/工具/git/
作者
where
发布于
2023年6月1日
许可协议