Git常用操作

警告
本文最后更新于 2020-10-10,文中内容可能已过时。

Git 的四个区域(或称工作区域)分别是:

  • 工作区(Workspace):也称为“工作目录”,是项目的根目录,其中包含项目的所有文件和子目录。这个区域是我们对项目所做更改的初始地点,即文件的初始版本。
  • 暂存区(Index):也称为“缓存区”或“staging area”,是 Git 用于暂存即将被提交到本地仓库的更改的地方。在执行 git add 命令后,文件的当前版本会被复制到暂存区。
  • 本地仓库(Repository):包含所有提交的历史版本及其元数据的数据库。在执行 git commit 命令后,暂存区中的更改会被提交到本地仓库中。
  • 远程仓库(Remote):与本地仓库类似,但它是存储在网络上的一个或多个 Git 仓库,通常由项目的团队成员使用。在与远程仓库同步之前,本地仓库中的更改不会传输到远程仓库。当您执行 git push 命令时,您将提交的更改推送到远程仓库。在执行 git pull 命令时,您将从远程仓库获取更新并将其合并到您的本地仓库中。
1
2
# 初始化一个空的仓库给
git init
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 将所有修改添加到暂存区
git add .

# 将以.go结尾的文件添加到暂存区
git add *.go

# 将以hello开头后面只有一位的文件提交到暂存区 例如:hello1.txt,helloA.cpp 如果是helloGit.txt和hello.cxx是不会被添加的。
git add hello?.*

# 将b.txt从暂存区移除,文件还在工作区
git rm --cached b.txt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 指定提交的提交信息。
git commit -a -m "first commit"

# 创建新的提交,允许用户编辑提交信息,并显示所有差异内容的详细信息(包括添加、修改、删除的文件内容)。
git commit --verbose

# 编辑最后一次提交信息,允许用户在编辑提交信息时修改之前的提交内容。会修改最后一次提交,不会生成新的提交。
git commit --verbose --amend

# 提交所有暂存区的文件,不包括未跟踪的文件,用户可以编辑提交信息。
git commit --verbose --all

# 编辑最后一次提交信息并将所有更改的文件提交,不包括未跟踪的文件。会修改最后一次提交,不会生成新的提交。
git commit --verbose --all --amend

# 提交所有暂存区文件,并使用命令行中提供的提交信息进行提交。
git commit --all --message

# 对最新一次提交进行修改,并保留原来的提交信息和日志,不修改提交信息。
git commit --verbose --no-edit --amend

# 编辑最后一次提交并将所有更改的文件提交,不需要编辑提交信息,将使用之前提交的信息。
git commit --verbose --all --no-edit --amend
  • –message:缩写为-m,用于在提交时添加提交信息。
  • –verbose:缩写为-v,用于在提交时显示变更的详细信息。
  • –amend:用于修改上一次提交的信息。
  • –all:缩写为-a,用于添加所有已修改或删除的文件,并在提交时忽略未跟踪的文件。
  • –no-edit:用于在修改提交信息时不打开编辑器,直接使用上次的提交信息。

在使用 Git 进行协作开发时,代码的提交需要有代码贡献者的签署。其中,CLA(Contributor License Agreement,贡献者许可协议)就是一种协议,它规定了贡献者对其提交代码的版权归属、代码授权许可等相关事项。CLA 的目的是保护开源软件的知识产权,防止代码提交者的版权问题引起的纠纷和法律风险。

在 Git 中,–signoff 是一个选项,用于在提交日志中添加 Signed-off-by 行。这个选项的使用场景通常是在参与开源项目的贡献时,通过在提交日志中添加 Signed-off-by 行,表示提交者确认自己已经阅读了项目的 CLA,同意将代码贡献给该项目,并承诺自己对该代码的质量和合法性负责。同时,Signed-off-by 行也提供了代码贡献者的身份信息,方便项目维护者进行代码审核和管理。

  1. 编写完要提交的代码,并通过 git add 将修改的文件添加到暂存区。
  2. 使用 git commit 命令提交代码,添加 --signoff 参数:git commit --signoff
  3. 根据提示,输入本次提交的信息。
  4. 提交成功后,可以通过 git log 命令查看到 Signed-off-by 行的信息:
1
2
3
4
5
6
7
commit 12abc34def5678
Author: Kira Chen <[email protected]>
Date:   Wed Mar 23 12:34:56 2020 +0800

    Fix some bugs in the login page

    Signed-off-by: Kira <[email protected]>

Signed-off-by 行必须要包含提交者的姓名和 email 地址,例如上面的例子中的 “Kira [email protected]”。如果在 Git 的全局配置中没有配置 email 地址,也可以手动指定:git commit --signoff --author="Kira <[email protected]>"

--gpg-sign 是 Git 命令的一个选项,用于在提交时进行 GPG 签名。它可以确保提交的内容在传输和存储过程中不会被篡改,增强了提交的安全性。当代码库需要确保提交内容的完整性和真实性时,可以使用 --gpg-sign 选项。

使用 --gpg-sign 选项需要在本地配置好 GPG 密钥对,具体步骤如下:

  1. 生成 GPG 密钥对:使用命令 gpg --gen-key 生成 GPG 密钥对,并设置密码和用户名等信息。
  2. 将 GPG 公钥添加到代码库:使用命令 gpg --armor --export <key-id> 导出 GPG 公钥,并将公钥添加到代码库的 GPG 密钥列表中。
  3. 配置 Git 选项:使用命令 git config --global user.signingkey <key-id> 配置 Git 选项,以便在提交时使用正确的密钥进行签名。
  4. 提交代码并进行 GPG 签名:在提交时使用 --gpg-sign 选项进行签名,例如 git commit --gpg-sign

在以上步骤完成后,提交代码时会要求输入 GPG 密码进行签名,以确保提交内容的完整性和真实性。

为什么使用常规提交?

  1. 便于自动化版本号和发布流程的管理:使用规范的提交消息可以轻松自动化版本号的生成和发布流程的管理。例如,基于规范的提交消息可以自动检测是否应该发布一个新版本,以及新版本的版本号应该是多少。
  2. 提高代码可读性和可维护性:使用规范的提交消息可以提高代码的可读性和可维护性。规范的提交消息使得查找某个提交的目的、影响范围和处理方式变得更加容易。这对于团队协作和维护项目历史记录非常有帮助。
  3. 改进提交消息的一致性和可靠性:规范的提交消息可以帮助确保提交消息的一致性和可靠性。提交消息按照统一的模式编写可以避免模糊不清或不一致的消息,并且可以帮助开发人员更好地描述提交的目的和内容。
  4. 促进开发者的交流和理解:规范的提交消息可以促进开发者之间的交流和理解。通过使用规范的提交消息,开发人员可以更好地沟通并理解彼此的工作,从而帮助团队更好地合作开发。

Angular Conventional Commit 的提交规范中 message 的格式如下:

1
2
3
<type>[optional scope]: <description>
[optional body]
[optional footer]

这是 Conventional Commits 规范中标准的提交消息格式,各部分的含义如下:

  • <type>:表示本次提交的类型,例如 feat(新功能)、fix(修复 bug)、docs(文档变更)、style(代码风格变更)、refactor(重构代码)等。该字段是必填的。
  • [optional scope]:表示本次提交的范围,例如模块、文件、类等。该字段是可选的。
  • <description>:表示本次提交的简短描述,最好能够清晰地描述本次提交的目的和作用。该字段是必填的。
  • [optional body]:表示本次提交的详细说明,可以包含更详细的描述、操作流程、注意事项等内容。该字段是可选的。
  • [optional footer]:表示本次提交的元数据,包括关联的 issue、重大变化说明、不兼容变化说明等内容。该字段是可选的。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 将本地的分支推送到远程仓库中的对应分支。例如,git push origin main:main 将本地的 main 分支推送到远程仓库 origin 的 main 分支中。
git push <远程主机名> <本地分支名>:<远程分支名>

# 将本地的 main 分支推送到远程仓库 origin 的 refs/for/main 分支中,该命令通常在使用 Gerrit 这样的代码审查工具时使用。
git push origin main:refs/for/main

# 将本地的 main 分支推送到远程仓库 origin 的 main 分支中。如果本地的 main 分支和远程仓库的 main 分支名称相同,则可以简写为 git push origin main。
git push origin main

# 删除远程仓库 origin 的 main 分支,等价于 git push origin --delete main。
git push origin :main:

# 将本地的当前分支推送到远程仓库中的对应分支。如果当前分支没有与远程分支建立关联,则会自动创建一个新的分支。
git push origin

# 将本地的所有分支都推送到远程仓库中的对应分支。
git push

Git 冲突通常发生在团队合作时,多个成员在同一时间修改同一行代码,当他们尝试将修改提交到 Git 仓库时,就会发生冲突。处理冲突的流程如下:

  1. 使用 git pull 命令将远程仓库的最新更改合并到本地仓库中。如果远程仓库和本地仓库都对同一文件进行了更改,则会自动发生冲突。
  2. 找到冲突文件:如果在执行上一步命令时出现错误,则需要手动查找冲突文件。Git 会在冲突文件中标记出冲突的地方,你可以通过以下命令查找冲突文件:git status这将会列出有冲突的文件。
1
2
3
4
5
<<<<<<< HEAD
本地更改
=======
远程更改
>>>>>>> origin/main
  1. 您需要手动编辑文件并删除冲突标记,保留您需要的更改。在完成解决冲突后,保存并关闭文件。
  2. 使用 git commit 命令提交更改。在提交消息中,您可以简要描述您所做的更改和如何解决冲突。
  3. 使用 git push 命令将更改推送到远程仓库。
  4. 如果在上述步骤中出现问题,您可以使用 git merge --abort 命令取消合并,并尝试重新合并更改。
 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
# 按提交者分组显示提交记录,每个提交者只显示他们的提交次数和提交信息。
git shortlog

# 显示特定提交记录的详细修改内容。
git show commit-id

# 显示当前分支的所有提交记录,按提交时间倒序排列,每个记录包括提交的SHA-1哈希值、作者、提交时间、提交信息等。
git log

# 简化版的git log,每个提交记录只显示一行,包括提交的SHA-1哈希值和提交信息。
git log --onelie

# 显示最近的两次提交记录。
git log –2

# 显示跳过最近两次提交记录之后的接下来的三次提交记录。
git log --skip=2 -3

# 显示每个提交记录的详细修改内容。
git log -p

# 显示每个提交记录的简略修改内容统计信息,包括修改了哪些文件、每个文件修改了多少行等。
git log --stat

# 显示指定文件的所有修改记录,其中--oneline选项表示只显示每个提交的简短描述。
git log --oneline FILE_NAME

# 显示指定文件所有提交的修改内容,包括每个修改的详细差异,-p选项表示显示每个提交的补丁(patch)。
git log -p FILE_NAME

# 显示提交历史,包括分支和合并,每个提交用一行显示。
git log --graph --decorate --all

# 显示最近10次提交的历史记录,使用 --graph 选项来绘制类似于分支图的 ASCII 图形。
git log --graph --max-count=10

# 显示提交历史以及每个提交所引入的更改。使用 --stat 选项显示每个提交中每个文件的更改统计信息,使用 --patch 选项显示每个提交的详细更改内容。
git log --stat --patch
  • --stat:显示简要的统计信息,如修改的文件、插入的行数和删除的行数等。
  • --graph:使用 ASCII 字符画的方式展示提交历史,可以清晰地看到不同分支的合并情况。
  • --decorate:在提交历史中显示 tag 和分支等引用的名称。
  • --all:展示所有分支的提交历史。
  • --patch:缩写为-p,显示每个提交的具体变更内容。
  • --oneline:以单行的形式展示提交历史。
  • --pretty:可以指定不同的格式来展示提交历史,如 --pretty=format:"%h - %an, %ar : %s",这个命令会显示每个提交的简短 SHA-1 值、作者、提交时间和提交说明。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 显示指定日期之后的提交记录。
git log --after="2019-6-1"

# 显示指定日期之前的提交记录。
git log –-before="2019-6-1"

# 显示特定作者的提交记录。
git log --author="Kira"

# 在 Git 的提交历史中搜索包含 "issue" 字符串的 commit message,并将结果列出来。这个命令可以用来查找包含特定问题编号的 commit。
git log --grep="issue"

# 在 Git 的提交历史中搜索包含 ./src/test.go 文件路径的 commit,并将结果列出来。这个命令可以用来查找特定文件的提交历史。
git log -- ./src/test.go

# 在 Git 的提交历史中搜索引入或删除 "transport" 字符串的 commit,并将结果列出来。这个命令可以用来查找特定字符串的提交历史。
git log -S "transport"

# 列出 Git 的提交历史,其提交时间介于 <since> 和 <until> 之间的 commit。<since> 和 <until> 可以是 commit 的 SHA-1 标识符、分支名、标签名、日期、相对日期等。这个命令可以用来查找一段时间内的提交历史。
git log <since>..<until>

在 Git 中,我们可以针对同一个任务由多次提交,但是多个提交会让版本管理显得比较乱。为了解决这个问题,可以使用 git rebase 命令来合并多个 commit 为一个。

  1. 使用 git rebase -i <commit> 命令来打开交互式 rebase 窗口,然后将需要合并的 commit 的前面的命令改为 squash 或 s。(其中的顺序和 git log 相反)
  2. squash 表示该 commit 将会被合并到前一个 commit 中,pick 表示该 commit 会被保留。
  3. 保存并退出后,需要重新编辑合并后的 commit 信息,即输入合并后的 commit message,保存后即完成 commit 的合并。

需要注意的是,使用 git rebase 命令合并 commit 时,需要注意保持提交顺序不变,否则可能会造成代码冲突或者其他问题。另外,如果合并后的 commit 包含了多个功能或者修改,建议将其拆分成多个独立的 commit,以便更好地进行版本管理。

修改 commit 的 message

如果我们想修改之前的某个 commit message,可以使用 git rebase 命令。

  1. 首先,输入git rebase -i <commit-hash>命令,来进入交互式编辑模式。
  2. 在编辑窗口中,找到需要修改的 commit,将对应的 pick 命令修改为 reword,并保存退出。
  3. 之后会弹出一个编辑器窗口,让我们编辑 commit message,修改完成后保存并退出。
  4. 如果需要修改多个 commit message,则需要重复这个过程。
  5. 最后,如果所有的 commit 都已经 push 到远程仓库,我们需要使用 git push --force 强制推送到远程仓库。

修改 commit 的内容

当我们在历史提交中发现某个文件的修改不完整时,可以使用 git rebase 的 edit 命令进行修改。

  1. 首先,我们需要使用 git rebase 命令进入交互式界面,然后将需要修改的 commit 前的 pick 命令改为 edit
  2. 接下来,git rebase 会停止工作,以便我们可以编辑文件和 commit message。
  3. 在编辑完毕后,我们可以使用 git commit --amend 命令来修改提交内容,然后使用 git rebase --continue 命令继续进行之后的 edit 命令。
  4. 如果修改前的所有 commit 都已经推送到远程仓库,我们需要使用 git push --force 命令来强制推送到远程仓库。

本地仓库检出内容,然后覆盖掉工作区的内容,即丢弃了本地所有的修改

1
2
3
4
5
6
7
8
# 切换到名为stable-v1.20的分支
git checkout branches/stable-v1.20

# 切换到commit id为6bfbacxd的版本,即回退到该版本
git checkout 6bfbacxd

# 将当前分支的main.go文件恢复到最近一次commit或者上一次执行git add时的状态
git checkout main.go

内容已经存在工作区了,但是尚未提交到暂存区,即是 untracked 的内容,我们可以使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 展示在当前目录下执行git clean会删除哪些文件,但不会真正删除它们。
git clean -n

# 删除当前目录下所有没有被跟踪的文件,但不删除.gitignore文件中指定的文件和文件夹。
git clean -f

# 删除指定路径下没有被跟踪的文件。
git clean -f <path>

# 删除当前目录下所有没有被跟踪的文件和文件夹,但不删除.gitignore文件中指定的文件和文件夹。
git clean -df

# 删除当前目录下所有没有被跟踪的文件,包括.gitignore文件中指定的文件和文件夹。
git clean -xf

放弃本地的所有修改

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 会将当前工作区的所有修改恢复成和最近一次commit时的状态相同,包括所有被修改的文件。
git checkout .

# 会将当前工作区所有被修改的文件恢复成和最近一次commit时的状态相同,但是不会影响新增加的文件,也不会删除已经被删除的文件。
git checkout -- .

# 删除当前目录下所有未被Git跟踪的文件和文件夹,包括Git忽略的文件和文件夹。
git clean -xdf

# 恢复指定文件的最近一次提交状态,即将该文件恢复为最近一次提交时的状态。
git checkout file-name

假设你在本地对代码做了一些修改,但尚未将这些修改推送到远程仓库。当你想要撤销这些修改时,可以使用 git reset 命令。

首先要知道的是,git reset 命令有三个参数:

  • –soft:只回滚提交历史,不改变暂存区和工作目录的内容
  • –mixed:回滚提交历史和暂存区的内容,但不改变工作目录的内容(默认参数)
  • –hard:回滚提交历史、暂存区和工作目录的所有内容

假设远程仓库的最新提交是 6ff5433b,而你在本地已经有三个新的提交。你想要回滚这些提交并覆盖本地工作区的内容,然后将这些修改推送到远程仓库。

你可以使用git reset --hard HEAD~3命令,将 HEAD 指针回滚三个版本,使用这些版本的代码覆盖本地工作区的内容。这样,你的本地仓库就恢复到了远程仓库的状态。最后,使用git push origin main命令将你的修改推送到远程仓库。

需要注意的是,git reset --hard命令是不可逆的,因此在执行该命令之前,一定要确保你理解了它的工作原理,并且做好必要的备份。如果你想要保留这些修改但不想将其推送到远程仓库,可以考虑使用git stash命令。

如果没有其它同事基于我们的 commit 做修改的话,使用git revert命令是比较好的选择,而不是git reset命令。因为git reset会删除 commit 记录,对于其它同事的修改也会产生影响。

举个例子,假设我们有三个 commit,现在想回退 3f5313b 这个分支:

1
2
3
4
$ git log --oneline
3243893 (HEAD -> main) 3.txt
3f5313b 2.txt
fd33f64 1.txt

需要执行以下步骤:

  1. git revert 3f5313b
  2. 如果有冲突需要解决冲突 或 git revert --abort 取消本次回退
  3. git commit:提交修改
  4. git push:push 到远程仓库
  1. git checkout -b reset_to_5ff5433b 5ff5433bd1fe4:从 5ff5433bd1fe4 处创建分支。
  2. git show 9d531db98276:9d531db98276 为最新的提交,查看 main 分支上的其它同事的提交,把他的修改在新分支上再修改一遍。
  3. git commit –a –m “reverted 5ff5433b”:提交
  4. git checkout main:切换到 main 分支。
  5. git merge reset_to_5ff5433b:合并修改。
  6. git push:推送到远程仓库

正常删除文件

  1. git rm -rf test.go:删除当前目录下的 test.go 文件,并将此修改标记为待提交的更改。
  2. git commit -m "remove test.go":将此次删除提交到本地仓库,并使用 “remove test.go” 作为提交信息。
  3. git push:将本地仓库的修改推送到远程仓库,以便其他人或其他机器可以访问这些更改。

敏感文件删除,比如 RSA 的私钥或生产环境数据库密码等

  1. git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch src/main/resources/config/application-test.yml' --prune-empty --tag-name-filter cat -- --all
    1. git filter-branch: 这个命令可以重写 Git 仓库的历史记录。它提供了多个选项,可以对提交的内容进行修改、删除、重命名等操作。
    2. --force: 强制执行操作。
    3. --index-filter 'git rm --cached --ignore-unmatch src/main/resources/config/application-test.yml': 用于指定一个索引过滤器。这个索引过滤器会在每个提交中删除 src/main/resources/config/application-test.yml 这个文件(或者文件夹,如果使用了 -r 参数)。
    4. --prune-empty: 这个选项会在过滤器执行后删除空的提交。
    5. --tag-name-filter cat: 这个选项会用 cat 命令来处理标签名。这个选项的作用是确保所有标签都被重写,以便与过滤后的提交相匹配。
    6. -- --all: 这个选项表示应用以上所有选项到所有分支。
  2. git push origin --force --all: 强制推送所有本地分支的修改到远程仓库。
  3. git push origin --force --tags: 强制推送所有本地标签的修改到远程仓库。

Git stash 可以用来暂存未提交的工作进度,并将当前工作目录还原到上一次提交的状态。这里是使用 Git stash 的一个典型流程:

  1. 使用 git stash push 将当前未提交的工作进度暂存起来。

  2. 可以使用 git stash list 命令查看当前所有的 stash 记录。

  3. 使用 git stash apply 命令来恢复最新的 stash 记录。如果有多个 stash 记录,可以使用 git stash apply stash@{n} 命令来恢复指定的 stash 记录。

  4. 如果要暂存所有的变更,可以使用 git stash --all 命令。

  5. 使用 git stash drop 命令来删除最新的 stash 记录。

    1. git stash drop stash@{X} :删除 Git stash(缓存)中序号为 X 的存储修改内容。
    2. 如果要删除所有的 stash 记录,可以使用 git stash clear 命令(慎用)。
  6. 使用 git stash pop 命令可以恢复最新的 stash 记录,并删除该记录。

  7. 使用 git stash show --text 命令可以查看 stash 记录的内容。如果需要查看更多信息,可以使用 git stash show stash@{n} --text 命令来查看指定的 stash 记录。

git stash save 和 git stash push 区别?

  • 在早期版本的 Git 中,使用 git stash save 命令来保存工作区的修改,但在 Git 2.13 版本中,git stash save 已经被废弃,建议使用 git stash push 命令来代替。
  • 实际上,git stash push 命令和 git stash save 命令的作用是一样的,都是将当前工作区的修改保存到一个栈中。区别在于,git stash push 命令可以通过选项更加灵活地控制保存的内容。
    • 例如,可以使用 --include-untracked 选项来将未跟踪的文件也一同保存,使用 --patch 选项来交互式选择要保存的修改等。同时,git stash push 命令也可以使用 -m 选项来添加一条消息,以便后续更好地识别保存的内容。
  • 综上,虽然 git stash save 命令在一些老版本的 Git 中仍然可以使用,但建议使用 git stash push 命令来代替,并结合选项更加灵活地控制保存的内容。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 显示某个提交中指定文件的修改内容,其中commit-id指定提交的ID号,FILE_NAME是指定的文件名。
git show commit-id FILE_NAME

# 显示指定提交与当前工作目录的文件的差异,其中commit-id可以替换为其他提交ID或分支名,FILE_NAME是指定的文件名。
git diff commit-id FILE_NAME

# 显示指定两个提交之间的差异,其中commit-id1和commit-id2是两个不同的提交ID或分支名。
git diff commit-id1 commit-id2

# 显示当前工作目录中指定文件和暂存区之间的差异。
git diff FILE_NAME

# 显示暂存区和本地仓库中指定文件之间的差异。
git diff --cached FILE_NAME

# 显示本地分支和远程仓库中指定分支之间的差异。
git diff BRANCH origin/main

添加和更新子模块

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 向主仓库添加一个子模块。子模块是一个独立的 Git 仓库,它可以被主仓库所引用。
git submodule add <remote_url> <destination_folder>

# 使用这个命令克隆主仓库时,会同时克隆所有的子模块。
git clone <url> --recurse-submodules

# 如果主仓库中已经有子模块了,这个命令会将子模块下载并更新到主仓库的最新版本。
git submodule update --init --recursive

# 查看当前主仓库的子模块状态。
git submodule status

# 更新子模块的版本到最新版本,并将这些子模块的新版本合并到主仓库中。
git submodule update --remote --merge

# 从主仓库中移除一个子模块。
git rm submodule
 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
# 查看所有本地分支
git branch

# 查看所有本地和远程分支
git branch -a

# 删除远程分支 BRANCH_NAME
git push origin --delete BRANCH_NAME

# 删除本地分支 BRANCH_NAME
git branch -d BRANCH_NAME

# 切换到 dev 分支
git checkout dev

# 创建一个名为 dev 的新分支,并切换到该分支
git checkout -b dev

# 创建一个名为 develop 的新分支
git branch develop

# 基于当前分支创建一个新的名为 feature/123456 的分支,并切换到该分支
git checkout -b feature/123456

# 切换到 develop 分支
git checkout develop

# 将 feature/123456 分支合并到当前所在的分支(即 develop 分支)
git merge feature/123456

# 删除 feature/FT-123456 分支
git branch -d feature/123456

# 推送本地 hotfix/issue-345678 分支到远程分支并与其关联
git push -u origin hotfix/issue-345678

Git 的分支管理涉及到以下分支:

  • main:作为稳定分支,仅接受已经 review 过且通过测试的代码,可用于生产环境部署。
  • develop:主要开发分支,用于进行持续集成和 code review,也是 bug 修复和新功能开发的基础分支。
  • feature:每个功能或变更请求都可以基于 Develop 分支拉取一个 Feature 分支,用于开发、review 和测试,测试通过后将该分支合并到 Develop 分支。
  • hotfix:紧急修复分支,主要用于从 Main 分支拉取代码修复紧急问题并合并到 Develop 和 Main 分支。
  • release:预发布分支,用于特定版本的系统测试,测试通过后可合并到 Main 分支并打上对应的版本号。
  • bug:用于修复 bug 的分支,定位并解决后将该分支合并到 Develop 和 Release 分支,并进行回归测试,回归测试通过后关闭该 bug。

Git 的 tag 是用来标记特定的 commit,以便于后续的查找和发布等操作。在一个项目中,可能存在多个 tag,每个 tag 可以对应不同的版本或者里程碑。

 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
# 创建一个tag名称为v0.10.15,并将它附加在当前HEAD上的commit上。
git tag v0.10.15

# 创建一个tag名称为v0.10.13,并将它附加在指定的commit ID上。
git tag v0.10.13 612931c0f

# 创建一个带注释的tag名称为v0.10.9,并将它附加在指定的commit ID上。
git tag –a v0.10.9 –m "bumped version to 0.10.9" 89de7802

# 列出所有的tag。
git tag

# 查看tag名称为v0.10.13对应的commit的详细信息。
git show v0.10.13

# 将tag_name推送到远程服务器。
git push origin tag_name

# 将所有的tag推送到远程服务器。
git push origin --tags

# 检出tag名称为tag_name对应的commit。
git checkout tag_name

# 删除本地的tag名称为tag_name的标签。
git tag –d tag_name

# 删除远程tag名称为tag_name的标签。
git push origin :refs/tags/tag_name

git bisect 命令可以帮助我们找到引入问题的提交。使用该命令需要先指定一个知道没有问题的提交和一个已知有问题的提交,然后 Git 会逐步缩小问题引入的范围,直到找到引入问题的提交为止。

  1. 确定一个已知没有问题的提交和一个已知有问题的提交,例如:
1
2
3
git bisect start            # 开始二分查找
git bisect bad              # 标记当前的提交有问题
git bisect good v1.2.3      # 指定一个没有问题的提交

注意,goodbad 都可以指定提交的 SHA-1 值,也可以使用分支名、tag 名等来表示。

  1. Git 会自动切换到一个中间的提交,并等待你测试该提交是否有问题。你需要执行一些测试代码来判断该提交是否有问题,然后告诉 Git 结果:
1
2
git bisect good             # 该提交没有问题
git bisect bad              # 该提交有问题
  1. Git 根据你的测试结果自动切换到另一个中间的提交,然后你需要再次测试该提交并告诉 Git 结果。这个过程会一直进行下去,直到找到引入问题的提交为止。
  2. 如果你测试了很多次后无法确定问题引入的提交,可以使用 git bisect reset 命令结束二分查找,并返回到起始状态。

git worktree 是 Git 的一个功能,可以让你在同一个本地仓库中创建多个工作区,每个工作区都可以指向仓库的不同分支或提交。这个功能可以方便地进行多个任务的并行开发,而不必切换分支或创建多个本地仓库。

比如:通过 git worktree 可以方便地创建多个工作区,每个工作区可以指向不同的分支或提交,从而让你能够在同一个本地仓库中并行开发不同的功能或修复不同的问题。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 列出本地仓库中所有工作树的信息,包括当前所在工作树。
git worktree list

# 在本地仓库中添加一个新的工作树,路径为 <path>,可选参数 <commit> 为新工作树所在的提交,如果不指定,则默认为当前所在工作树所在的提交。该命令会在新工作树目录下创建一个隐藏的 .git 目录,保存该工作树的 Git 元数据信息。使用该命令可以创建多个独立的工作环境,进行并行开发或测试。
git worktree add <path> [<commit>]

# 将一个工作树从原路径 <path> 移动到新路径 <new_path>。
git worktree move <path> <new_path>

# 删除一个工作树,会删除该工作树的目录和隐藏的 .git 目录。删除工作树不会影响本地仓库的提交历史等信息。
git worktree remove <path>

相关内容