ToB企服应用市场:ToB评测及商务社交产业平台

标题: Git 分支管理全攻略:一篇博客带你玩转代码分支! [打印本页]

作者: 商道如狼道    时间: 2024-12-26 23:41
标题: Git 分支管理全攻略:一篇博客带你玩转代码分支!
什么是分支?在 Git 里,分支实在就有点像一个树的枝杈,每个分支上可以有差别的文件的版本,而且不会互相干扰。

分支功能有什么用?在工作中,我们经常是需要和别人一起开发一个项目的,此时大概你开发 A 功能,别人开发 B 功能;假如只有一个分支的话,那么全部人都得在这个分支上干活;假如你开发完了功能,但是别人没有开发完,那么还得等其他人开发完(否则开发到一半的功能,怎么给别人利用,是吧)。
现在有了分支,完全可以创建多个分支,想提交就提交,开发完后再归并到原来的分支上,这样就不会影响(大概被影响)别人工作。
其他版本控制系统如 SVN 等都有分支管理,但是用过之后你会发现,这些版本控制系统创建和切换分支比蜗牛还慢,简直让人无法忍受,结果分支功能成了摆设,大家都不去用。
但 Git 的分支是与众差别的,无论创建、切换和删除分支,Git 在 1 秒钟之内就能完成!无论你的版本库是 1 个文件照旧 1 万个文件。



图示分支的概念

我们之前说过,每提交一个新版本,Git 就会把它们主动串成一条时间线,这条时间线就是一个分支。截止到现在,只有一条时间线,在 Git 里,这个分支叫主分支,即 master ​分支。
一开始的时候,master ​分支是一条线,Git 用 master ​指向最新的提交,再用 HEAD ​指向 master​,就能确定当前分支,以及当前分支的提交点:
  1.                   HEAD
  2.                     │
  3.                     │
  4.                     ▼
  5.                  master
  6.                     │
  7.                     │
  8.                     ▼
  9. ┌───┐    ┌───┐    ┌───┐
  10. │   │───→│   │───→│   │
  11. └───┘    └───┘    └───┘
复制代码


当我们创建新的分支,例如 dev ​时,Git 新建了一个指针叫 dev​,指向 master ​类似的提交,再把 HEAD ​指向 dev​,就表现当前分支在 dev ​上:
  1.                  master
  2.                     │
  3.                     │
  4.                     ▼
  5. ┌───┐    ┌───┐    ┌───┐
  6. │   │───→│   │───→│   │
  7. └───┘    └───┘    └───┘
  8.                     ▲
  9.                     │
  10.                     │
  11.                    dev
  12.                     ▲
  13.                     │
  14.                     │
  15.                   HEAD
复制代码
Git 创建一个分支很快,由于除了增长一个 dev ​指针,改改 HEAD ​的指向,工作区的文件都没有任何变化!
从现在开始,对工作区的修改和提交就是针对 dev ​分支了,比如新提交一次后,dev ​指针往前移动一步,而 master ​指针不变:
  1.                  master
  2.                     │
  3.                     │
  4.                     ▼
  5. ┌───┐    ┌───┐    ┌───┐    ┌───┐
  6. │   │───→│   │───→│   │───→│   │
  7. └───┘    └───┘    └───┘    └───┘
  8.                              ▲
  9.                              │
  10.                              │
  11.                             dev
  12.                              ▲
  13.                              │
  14.                              │
  15.                            HEAD
复制代码

假如我们在 dev ​上的工作完成了,就可以把 dev ​归并到 master ​上。Git 怎么归并呢?最简单的方法,就是直接把 master ​指向 dev ​的当前提交,就完成了归并:
  1.                            HEAD
  2.                              │
  3.                              │
  4.                              ▼
  5.                           master
  6.                              │
  7.                              │
  8.                              ▼
  9. ┌───┐    ┌───┐    ┌───┐    ┌───┐
  10. │   │───→│   │───→│   │───→│   │
  11. └───┘    └───┘    └───┘    └───┘
  12.                              ▲
  13.                              │
  14.                              │
  15.                             dev
复制代码


所以 Git 归并分支也很快!就改改指针,工作区内容也不变!
归并完分支后,以致可以删除 dev ​分支。删除 dev ​分支就是把 dev ​指针给删掉,删掉后,我们就剩下了一条 master ​分支:
  1.                            HEAD
  2.                              │
  3.                              │
  4.                              ▼
  5.                           master
  6.                              │
  7.                              │
  8.                              ▼
  9. ┌───┐    ┌───┐    ┌───┐    ┌───┐
  10. │   │───→│   │───→│   │───→│   │
  11. └───┘    └───┘    └───┘    └───┘
复制代码



在实际开发中,我们应该按照几个根本原则举行分支管理:


所以,团队互助的分支看起来就像这样:







创建分支

请读者务必也动手实践!
我们利用 git branch 分支名 ​来创建分支:
  1. $ git branch dev
复制代码

我们可以利用 git branch 来检察当前分支的创建情况:
  1. $ git branch
  2.   dev
  3. * master
复制代码
git branch ​命令会列出全部门支,当前分支前面会标一个 * ​号,可以看到现在有两个分支,一个是 dev,一个是 master。

然后我们就可以用 git switch 分支名 ​切换分支了:
  1. $ git switch dev
  2. Switched to branch 'dev'
  3. $ git branch
  4. * dev
  5.   master
复制代码

也可以一条命令创建并切换分支:
  1. $ git switch -
  2. c dev
复制代码

假如需要频繁切换分支,可以简写:
  1. $ git switch -
复制代码

管理分支



删除分支

假如我们要删除分支,利用 git branch -d 分支名 ​即可。留意,不能删除当前分支。例如我们当前在 dev 分支,假如删除就回报错:
  1. $ git branch -d dev
  2. error: Cannot delete branch 'dev' checked out at 'D:/Projects/LearnGit'
复制代码
得切换到其他分支后,才能删除
  1. $ git switch master
  2. Switched to branch 'master'
  3. Your branch is ahead of 'gitee/master' by 8 commits.
  4.   (use "git push" to publish your local commits)
  5. $ git branch -d dev
  6. Deleted branch dev (was 0066f6d).
复制代码


检察分支创建时间


git reflog show --date=iso <branch name> ​命令可以检察到指定分支的历次更改记录,最下面一条的时间即是分支创建时间。
  1. $ git reflog show --date=iso dev
  2. 0066f6d (HEAD -> dev, master) dev@{2023-01-14 15:40:45 +0800}: branch: Created from HEAD
复制代码


重命名分支

偶然候发现创建的分支名字搞错了,要改名,怎么办?利用如下命令:
  1. $ git branch -m <old_branch_name> <new_branch_name>
复制代码

当你要重命名的分支恰好是当前分支时,就不需要指定旧的分支名称。
  1. $ git branch -m <new_branch_name>
复制代码

查询分支

之前我们说了检察当地分支可以:
  1. $ git branch
  2.   bug
  3.   feature
  4. * master
复制代码



假如要列出全部门支(当地和远程),假设 -a 参数:
  1. $ git branch -a
  2.   bug
  3.   feature
  4. * master
  5.   remotes/gitee/feature
  6.   remotes/gitee/master
  7.   remotes/github/feature
  8.   remotes/github/master
复制代码


归并分支

接下来我们演示下,在其他分支上编写代码,然后归并到 master 分支。
首先照旧得创建分支
  1. $ git switch -
  2. c dev
  3. Switched to a new branch 'dev'
复制代码

我们创建一个新的文件夹,用来存放我们演示的文件。
  1. $ mkdir 3-branch
  2. $ echo "Creating a new branch is quick" > 3-branch/branch.txt
  3. $ git add .
  4. $ git commit -m "branch test"
复制代码

现在,dev ​分支的工作完成,我们就可以切换回 master ​分支:
  1. $ git checkout master
复制代码

切换回 master ​分支后,我们可以看到刚刚创建的文件夹不见了:
  1. $ ll
  2. total 5
  3. drwxr-xr-x 1 peterjxl 197121  0  1月 11 07:37 1-diffAndPath/
  4. drwxr-xr-x 1 peterjxl 197121  0  1月 14 07:19 2-versionControl/
  5. -rw-r--r-- 1 peterjxl 197121 33  1月 13 22:53 readme.md
复制代码

由于那个提交是在 dev ​分支上,而 master ​分支此刻的提交点并没有变:


现在,我们来归并分支:
  1. $ git merge dev
  2. Updating 0066f6d..5a512b7
  3. Fast-forward
  4. 3-branch/branch.txt | 1 +
  5. 1 file changed, 1 insertion(+)
  6. create mode 100644 3-branch/branch.txt
复制代码
留意 Git 的提示:Fast-forward​,指的是本次归并是“快进模式”,也就是直接把 master ​指向 dev ​的当前提交,所以归并速度非常快。固然,也不是每次归并都能 Fast-forward​,我们背面会讲其他方式的归并。


可以看到现在 master 分支上,已经 dev 分支开发的内容了:
  1. $ ll
  2. total 5
  3. drwxr-xr-x 1 peterjxl 197121  0  1月 11 07:37 1-diffAndPath/
  4. drwxr-xr-x 1 peterjxl 197121  0  1月 14 07:19 2-versionControl/
  5. drwxr-xr-x 1 peterjxl 197121  0  1月 14 15:54 3-branch/
  6. -rw-r--r-- 1 peterjxl 197121 33  1月 13 22:53 readme.md
  7. $ cat 3-branch/branch.txt
  8. Creating a new branch is quick
复制代码


假如要丢弃一个没有被归并过的分支,可以通过 git branch -D <name> ​强行删除,否则会报错:
  1. $ git branch -d feature-vulcan
  2. error: The branch 'feature-vulcan' is not fully merged.
  3. If you are sure you want to delete it, run 'git branch -D feature-vulcan'.
复制代码
办理冲突

归并分支也不是那么一帆风顺,经常会遇到冲突:当多个人在差别分支上修改同一个文件,这样归并的时候大概率会发生冲突,我们来实践下。

首先创建一个新的分支:
  1. $ git switch -
  2. c feature1Switched to a new branch 'feature1'
复制代码

修改下 branch.txt 内容如下,并提交:
  1. $ vim 3-branch/branch.txt
  2. $ cat 3-branch/branch.txt
  3. Creating a new branch is quick And simple
  4. $ git add  3-branch/branch.txt
  5. $ git commit -m "And simple"
复制代码

切换为 master 分支,而且同样修改 branch.txt:
  1. $ git switch master
  2. $ vim 3-branch/branch.txt
  3. $ cat 3-branch/branch.txt
  4. Creating a new branch is quick & simple
  5. $ git add 3-branch/branch.txt
  6. $ git commit -m "&simple"
复制代码


现在,master ​分支和 feature1 ​分支各自都分别有新的提交,变成了这样:
  1.                             HEAD
  2.                               │
  3.                               │
  4.                               ▼
  5.                            master
  6.                               │
  7.                               │
  8.                               ▼
  9.                             ┌───┐
  10.                          ┌─→│   │
  11. ┌───┐    ┌───┐    ┌───┐  │  └───┘
  12. │   │───→│   │───→│   │──┤
  13. └───┘    └───┘    └───┘  │  ┌───┐
  14.                          └─→│   │
  15.                             └───┘
  16.                               ▲
  17.                               │
  18.                               │
  19.                           feature1
复制代码
这种情况下,Git 无法实行“快速归并”,只能试图把各自的修改归并起来,但这种归并就大概会有冲突,我们试试看:
  1. $ git merge feature1
  2. Auto-merging 3-branch/branch.txt
  3. CONFLICT (content): Merge conflict in 3-branch/branch.txt
  4. Automatic merge failed; fix conflicts and then commit the result.
复制代码
Git 告诉我们,branch.txt ​文件存在冲突,必须手动办理冲突后再提交。


git status ​也可以告诉我们冲突的文件:
  1. $ git status
  2. On branch master
  3. Your branch is ahead of 'gitee/master' by 10 commits.
  4.   (use "git push" to publish your local commits)
  5. You have unmerged paths.
  6.   (fix conflicts and run "git commit")
  7.   (use "git merge --abort" to abort the merge)
  8. Unmerged paths:
  9.   (use "git add <file>..." to mark resolution)
  10.         both modified:   3-branch/branch.txt
  11. no changes added to commit (use "git add" and/or "git commit -a")
复制代码

我们现在看看 branch.txt 的内容:
  1. $ cat 3-branch/branch.txt
  2. <<<<<<< HEAD
  3. Creating a new branch is quick & simple
  4. =======
  5. Creating a new branch is quick And simple
  6. >>>>>>> feature1
复制代码
Git 用 <<<<<<<​,=======​,>>>>>>> ​标记出差别分支的内容。我们修改如下后生存:
  1. $ cat 3-branch/branch.txt
  2. Creating a new branch is quick and simple
复制代码
再提交:
  1. $ git add 3-branch/branch.txt
  2. $ git commit -m "conflict fixed"
  3. [master dd140df] conflict fixed
复制代码
现在,master ​分支和 feature1 ​分支变成了下图所示:
  1.                                      HEAD
  2.                                        │
  3.                                        │
  4.                                        ▼
  5.                                     master
  6.                                        │
  7.                                        │
  8.                                        ▼
  9.                             ┌───┐    ┌───┐
  10.                          ┌─→│   │───→│   │
  11. ┌───┐    ┌───┐    ┌───┐  │  └───┘    └───┘
  12. │   │───→│   │───→│   │──┤             ▲
  13. └───┘    └───┘    └───┘  │  ┌───┐      │
  14.                          └─→│   │──────┘
  15.                             └───┘
  16.                               ▲
  17.                               │
  18.                               │
  19.                           feature1
复制代码



用带参数的 git log ​也可以看到分支的归并情况:
  1. $ git log --graph  --pretty=oneline --abbrev-commit
  2. *   dd140df (HEAD -> master) conflict fixed
  3. |\
  4. | * bbf0307 (feature1) And simple
  5. * | 668f226 &simple
  6. |/
  7. * 5a512b7 (dev) branch test
  8. * 0066f6d delete test.txt by git rm --chched
  9. * 3ce9df0 add test.txt
  10. * 8a6d94d delete test.txt
  11. * 42c477d add test.txt
  12. * b391595 delete test.txt
  13. * 8889d50 add test.txt
  14. * 643c5ef .gitignore文件不生效,重新添加
  15. * 3d04684 add gitignore file
  16. * 39d7f12 (github/master, gitee/master) add readme.md
  17. * aeb06f4 git tracks changes
  18. * 8f5bb58 understand how stage works
  19. * efc9138 append GPL word
  20. * 750360e add distributed word
  21. * 0282c44 wrote a readme file
  22. * 0b3cfef add world.txt and diff.txt
  23. * abf2051 add diff and patch hello.txt
复制代码

假如你用可视化图形界面,看到的结果也是类似的:


其他归并方式

归并分支时,Git 会默认用 Fast forward ​模式,但这种模式下,删除分支后,会丢掉分支信息。
假如禁用了 Fast forward ​模式,Git 就会在 merge 时生成一个新的 commit,这样,从分支汗青上就可以看出分支信息。
下面我们实战一下 --no-ff ​方式的 git merge​。


我们创建一个新的分支 feature02,并修改内容后提交:
  1. $ git switch -
  2. c feature02Switched to a new branch 'feature02'$ vim 3-branch/branch.txt$ cat 3-branch/branch.txt
  3. Creating a new branch is quick and simple
  4. test no fast forward$ git add 3-branch/branch.txt$ git commit -m "test"
复制代码

现在,我们切换回 master​,并归并分支:
  1. $ git switch master
  2. $ git merge --no-ff -m "merge with no-ff" feature02
  3. Merge made by the 'recursive' strategy.
  4. 3-branch/branch.txt | 1 +
  5. 1 file changed, 1 insertion(+)
复制代码

由于本次归并要创建一个新的 commit,所以加上 -m ​参数,把 commit 形貌写进去。
归并后,我们用 git log ​看看分支汗青:
  1. $ git log --graph --pretty=oneline --abbrev-commit
  2. *   f564208 (HEAD -> master) merge with no-ff
  3. |\
  4. | * 8f87605 (feature02) test
  5. |/
  6. *   dd140df conflict fixed
  7. |\
  8. | * bbf0307 And simple
  9. * | 668f226 &simple
  10. |/
  11. * 5a512b7 branch test
  12. * 0066f6d delete test.txt by git rm --chched
  13. * 3ce9df0 add test.txt
  14. * 8a6d94d delete test.txt
  15. * 42c477d add test.txt
  16. * b391595 delete test.txt
  17. * 8889d50 add test.txt
  18. * 643c5ef .gitignore文件不生效,重新添加
  19. * 3d04684 add gitignore file
  20. * 39d7f12 (github/master, gitee/master) add readme.md
  21. * aeb06f4 git tracks changes
  22. * 8f5bb58 understand how stage works
  23. * efc9138 append GPL word
  24. * 750360e add distributed word
  25. * 0282c44 wrote a readme file
  26. * 0b3cfef add world.txt and diff.txt
  27. * abf2051 add diff and patch hello.tx
复制代码


可以看到,不利用 Fast forward ​模式,merge 后就像这样:


大概用 GitExtensions 检察,结果类似:


归并分支时,加上 --no-ff ​参数就可以用普通模式归并,归并后的汗青有分支,能看出来曾经做过归并,而 fast forward ​归并就看不出来曾经做过归并。


比较分支的差异

偶然候我们需要ascii比较两个分支的差异,可以利用如下命令:
  1. $ git diff branch1 branch2 --stat   //显示出所有有差异的文件列表
  2. $ git diff branch1 branch2 文件名(带路径)   //显示指定文件的详细差异
  3. $ git diff branch1 branch2                   //显示出所有有差异的文件的详细差异
复制代码


(未完待续…)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4