前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >git初入门(三):分支

git初入门(三):分支

原创
作者头像
传说之下的花儿
修改2023-09-16 21:52:08
2470
修改2023-09-16 21:52:08
举报

1. Git分支

分支在 GIT 中相对较难。

1.1 什么是分支

分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习 Git 的时候,另一个你正在另一个平行宇宙里努力学习 SVN。

如果两个平行宇宙互不干扰,那对现在的你也没啥影响。

不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了 Git 又学会了 SVN!

分支在实际中有什么用呢? 假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了 50% 的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。 现在有了分支,就不用怕了。 你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

Git 分支的速度非常快。

截止到目前,只有一条时间线,在 Git 里,这个分支叫主分支,即 master 分支。

HEAD 严格来说不是指向提交,而是指向 master,master 才是指向提交的,所以,HEAD 指向的就是当前分支。

1.2 git 分支中常用指令

代码语言:javascript
复制
 # 列出所有本地分支
 $ git branch
 ?
 # 列出所有远程分支
 $ git branch -r
 ?
 # 列出所有本地分支和远程分支
 $ git branch -a
 ?
 # 新建一个分支,但依然停留在当前分支
 $ git branch [branch-name]
 ?
 # 新建一个分支,并切换到该分支
 $ git checkout -b [branch]
 ?
 # 新建一个分支,指向指定commit
 $ git branch [branch] [commit]
 ?
 # 新建一个分支,与指定的远程分支建立追踪关系
 $ git branch --track [branch] [remote-branch]
 ?
 # 切换到指定分支,并更新工作区
 $ git checkout [branch-name]
 ?
 # 切换到上一个分支
 $ git checkout -
 ?
 # 建立追踪关系,在现有分支与指定的远程分支之间
 $ git branch --set-upstream [branch] [remote-branch]
 ?
 # 合并指定分支到当前分支
 $ git merge [branch]
 ?
 # 选择一个commit,合并进当前分支
 $ git cherry-pick [commit]
 ?
 # 删除分支
 $ git branch -d [branch-name]
 # 强制删除
 $ git branch -D [branch-name]
 ?
 # 删除远程分支
 $ git push origin --delete [branch-name]
 $ git branch -dr [remote/branch]

1.3 新建分支与切换分支

git branch git checkout

每次提交,Git 都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在 Git 里,这个分支叫主分支,即 master 分支。

HEAD 严格来说不是指向提交,而是指向 master,master 才是指向提交的,所以,HEAD 指向的就是当前分支。 ? 一开始的时候,master 分支是一条线,Git 用 master 指向最新的提交,再用 HEAD 指向 master,就能确定当前分支,以及当前分支的提交点:

每次提交,master 分支都会向前移动一步,这样,随着你不断提交,master 分支的线也越来越长:

  1. 新建一个分支,但依然停留在当前分支,使用:$ git branch [branch-name] $ git branch dev1 $ git branch # 查看本地分支 dev1 * master 当我们创建新的分支,例如dev时,Git 新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

你看,Git 创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化! 不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:

假如我们在dev上的工作完成了,就可以把dev合并到master上。Git 怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

所以 Git 合并分支也很快!就改改指针,工作区内容也不变! 合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支: # 新建一个分支,但依然停留在当前分支 git checkout -b dev # 提交 git commit -m"D" # 切换到指定分支,并更新工作区 git checkout master # 合并分支 git merge dev # 删除dev分支 git branch -d dev

  1. 切换分支,git checkout <name>,如果name为-则为上一个分支 $ git checkout dev1 Switched to branch 'dev1' $ git checkout - Switched to branch 'master'
  2. 新建一个分支,并切换到该分支,git checkout -b [branch] $ git checkout -b dev2 Switched to a new branch 'dev2'
  3. 新建一个分支,指向指定commit使用命令:git branch [branch] [commit] # 在dev2分支 提交一个hyy05.txt $ git commit hyy05.txt -m"分支切换测试——dev2分支提交" warning: LF will be replaced by CRLF in hyy05.txt. The file will have its original line endings in your working directory [dev2 7e9d0b9] 分支切换测试——dev2分支提交 1 file changed, 1 insertion(+) create mode 100644 hyy05.txt # 查看已提交的文件(master主分支提交的文件,其他分支都可以看到) $ git ls-files hyy00.txt hyy02.txt hyy03.txt hyy04.txt hyy05.txt # 查看日志 $ git reflog 7e9d0b9 (HEAD -> dev2) HEAD@{0}: commit: 分支切换测试——dev2分支提交 # 切换到dev1分支 $ git checkout dev1 Switched to branch 'dev1' # 此时切换到dev1分支就看不到dev2分支提交的了 $ git ls-files hyy00.txt hyy02.txt hyy03.txt hyy04.txt # 创建dev3分支 并将HEAD指针指向dev3,dev3指针指向 7e9d0b9 这次提交的位置 $ git checkout dev1 7e9d0b9 # 这时候你发现在dev3中是可以访问到那次提交的文件的 $ git ls-files hyy00.txt hyy02.txt hyy03.txt hyy04.txt hyy05.txt
  4. 新建一个分支,与指定的远程分支建立追踪关系使用命令:git branch --track [branch] [remote-branch] # 请求上游dev3,创建dev4 与远程分支dev3 进行追踪关系 $ git branch --track dev4 dev3 Branch 'dev4' set up to track local branch 'dev3'. $ git branch dev1 dev2 * dev3 dev4 master $ git checkout dev4 Switched to branch 'dev4' Your branch is up to date with 'dev3' # 您的分支会 使用“dev3”更新。 ? $ git checkout dev3 Switched to branch 'dev3' $ git add . warning: LF will be replaced by CRLF in hyy06.txt. The file will have its original line endings in your working directory # 在上游分支dev3 提交 $ git commit -m "git branch --track [branch] [remote-branch]测试,上游dev3提交" [dev3 5810a51] git branch --track [branch] [remote-branch]测试,上游dev3提交 1 file changed, 1 insertion(+) create mode 100644 hyy06.txt ? # 切换到分支dev4,会提醒你dev3 进行了一次提交,而当前dev4分支并没有,可以通过git pull根据dev3快速更新 $ git checkout dev4 Switched to branch 'dev4' # 您的分支在“dev3”之后1次提交,可以快速转发。 Your branch is behind 'dev3' by 1 commit, and can be fast-forwarded. # (使用“git pull”更新您的本地分支) (use "git pull" to update your local branch) $ git pull From . * branch dev3 -> FETCH_HEAD Updating 68963ae..5810a51 Fast-forward hyy06.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 hyy06.txt ? $ git status On branch dev4 Your branch is up to date with 'dev3'. ? nothing to commit, working tree clean # 可以看到hyy06.txt也同步到了当前分支dev4 $ git ls-files hyy00.txt hyy02.txt hyy03.txt hyy04.txt hyy06.txt

1.4 查看分支

git branch

列出所有本地分支使用 $ git branch

代码语言:javascript
复制
 $ git branch
   dev1
   dev2
   dev3
 * dev4
   master

git branch -r

列表所有远程分支使用 $ git branch -r

git branch -a

列出所有本地分支和远程分支使用 $ git branch -a

代码语言:javascript
复制
 $ git branch -a
   dev1
   dev2
   dev3
 * dev4
   master

1.5 分支合并

git merge [branch]

合并指定分支到当前分支使用指令 $ git merge [branch]

这里的合并分支就是对分支的指针操作,我们先创建一个分支再合并到主分支:

代码语言:javascript
复制
 $ git branch dev1
 $ git checkout dev1
 Switched to branch 'dev1'
 # 在分支dev1 提交hyy07.txt 内容“1e”
 $ git commit -m"提交hyy07.txt--dev1"
 [dev1 d08ce1d] 提交hyy07.txt--dev1
  1 file changed, 1 insertion(+)
  create mode 100644 hyy07.txt
 # 创建并切换的到 dev2分支
 $ git  checkout -b dev2
 Switched to a new branch 'dev2'
 $ cat hyy07.txt
 1e
 $ echo "dev2 修改的内容"> hyy07.txt
 $ git status
 On branch dev2
 Changes not staged for commit:
   (use "git add <file>..." to update what will be committed)
   (use "git restore <file>..." to discard changes in working directory)
         modified:   hyy07.txt
 ?
 no changes added to commit (use "git add" and/or "git commit -a")
 $ git add .
 $ git commit -m"在分支dev2中提交对hyy07.txt的修改"
 [dev2 894bff0] 在分支dev2中提交对hyy07.txt的修改
  1 file changed, 1 insertion(+), 1 deletion(-)
  
 # 查看hyy07.txt的内容,此时的俩分支的hyy07.txt的内容不同的(相当于两个平行宇宙)
 $ cat hyy07.txt 
 dev2 修改的内容
 # 回到分支dev1 去查看hyy07.txt 你可以看到是原本的内容,并不是dev2修改后的内容
 $ git checkout dev1
 Switched to branch 'dev1'
 $ cat hyy07.txt
 1e
 # 而且你在分支dev1的时候是看不到dev2那次提交的
 $ git log
 commit d08ce1d6a6247b4ae73ce4d57563b1329e8dc046 (HEAD -> dev1)
 Author: 胡宇洋 <2582952862@qq.com>
 Date:   Mon Nov 29 18:44:33 2021 +0800
 ?
     提交hyy07.txt--dev1
     
 # 回到dev2后,是可以看到提交记录的
 $ git checkout dev2
 Switched to branch 'dev2'
 $ git log
 commit 894bff00c019ddca7390d6c790d1179489c2ff35 (HEAD -> dev2)
 Author: 胡宇洋 <2582952862@qq.com>
 Date:   Mon Nov 29 18:50:36 2021 +0800
 ?
     在分支dev2中提交对hyy07.txt的修改
 ?
 # 回到分支 dev1 
 $ git checkout dev1
 Switched to branch 'dev1'
 # 将分支dev2 合并当前分支(dev1)
 $ git merge dev2
 Updating d08ce1d..894bff0
 Fast-forward
  hyy07.txt | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 # 合并完之后你可以看到 分支dev2中的修改在分支dev1中也生效了
 $ cat hyy07.txt
 dev2 修改的内容

1.6 解决冲突

如果同一个文件在合并分支时都被修改了则会引起冲突,如下所示:

提交前两个分支的状态

代码语言:javascript
复制
 $ echo "dev1 修改了内容">hyy07.txt
 $ git add .
 warning: LF will be replaced by CRLF in hyy07.txt.
 The file will have its original line endings in your working director
 $ git commit -m "在分支dev1上提交hyy07.txt"
 [dev1 9dcbd95] 在分支dev1上提交hyy07.txt
  1 file changed, 1 insertion(+), 1 deletion(-)
 $ git checkout dev2
 Switched to branch 'dev2'
 $ echo "在dev1之后,dev2修改了内容">hyy07.txt
 $ git add .
 warning: LF will be replaced by CRLF in hyy07.txt.
 The file will have its original line endings in your working directory
 $ git commit -m"在分支dev2上提交hyy07.txt"
 [dev2 f9113e3] 在分支dev2上提交hyy07.txt
  1 file changed, 1 insertion(+), 1 deletion(-)
 ?
 $ git checkout dev1
 Switched to branch 'dev1'
 ?
 # 将dev2合并到当前分支dev1,会提示合并失败
 $ git merge dev2 
 # 自动合并hyy07.txt
 Auto-merging hyy07.txt
 # hyy07.txt中的合并冲突
 CONFLICT (content): Merge conflict in hyy07.txt 
 # 自动合并失败;修复冲突,然后提交结果。
 Automatic merge failed; fix conflicts and then commit the result.
 # 查看当前状态,可以看到
 $ git status
 On branch dev1
 # 您有未合并的路径
 You have unmerged paths.
   # (修复冲突并运行“git提交”)
   (fix conflicts and run "git commit")
   # (使用“git merge--abort”中止合并)
   (use "git merge --abort" to abort the merge)
 # 未合并路径:
 Unmerged paths:
   (use "git add <file>..." to mark resolution)
         both modified:   hyy07.txt
 ?
 no changes added to commit (use "git add" and/or "git commit -a")
 ?
 # 此时查看hyy.txt可以在 dev1 分支中的状态
 $ cat hyy07.txt
 <<<<<<< HEAD
 dev1 修改了内容
 =======
 在dev1之后,dev2修改了内容
 >>>>>>> dev2

Git 用<<<<<<<=======>>>>>>> 标记出不同分支的内容,其中 <<<HEAD 是指主分支修改的内容,>>>>>dev2是指 dev2 上修改的内容

代码语言:javascript
复制
 # 解决的办法是我们可以修改冲突文件后重新提交,请注意当前的状态产生的,比如上面的:
 <<<<<<< HEAD# 当前分支dev1
 dev1 修改了内容               ------------->dev1分支修改的
 =======
 在dev1之后,dev2修改了内容     ------------->dev1分支修改的
 >>>>>>> dev2 
 # 二者选一个你想要留下的,去手动修改,比如我这里是hyy07.txt 我想要dev1分钟的修改,我去手动把内容修改成了:
 dev1 修改了内容
 # 其他内容全部删除,只保留了dev1分支修改的部分,抛弃了dev2 分支的修改、

重新提交后冲突解决:

代码语言:javascript
复制
 $ git add .
 $ git commit -m"解决分支冲突问题"
 [dev1 8c8d593] 解决分支冲突问题

手动解决完冲突后就可以把此文件添 加git add到暂存区中去,用 git commit命令来提交,就像平时修改了一个文件 一样。

git log --graph 命令可以看到分支合并图。

□ 分支策略

master 主分支应该非常稳定,用来发布新版本,一般情况下不允许在上面工作,工作一般情况下在新建的 dev 分支上工作,工作完后,比如上要发布,或者说 dev 分支代码稳定后可以合并到主分支 master 上来。

1.7 删除分支

删除本地分支可以使用命令:

代码语言:javascript
复制
 # 删除分支。
 # 分支必须完全合并到其上游分支中,或者 如果没有上游被设置为--track或--set upstream,则必须完全合并到其上游分支中。
 git branch -d [branch-name]
 # --delete--force的快捷方式。
 # 强制删除
 git branch -D [branch-name] 

删除远程分支可以使用如下指令:

代码语言:javascript
复制
 $ git push origin --delete [branch-name]
 ?
 $ git branch -dr [remote/branch]

-d 表示删除分支。分支必须完全合并在其上游分支,或者在 HEAD 上没有设置上游 -r 表示远程的意思 remotes,如果 - dr 则表示删除远程分支

我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. Git分支
    • 1.1 什么是分支
      • 1.2 git 分支中常用指令
        • 1.3 新建分支与切换分支
          • □ git branch git checkout
        • 1.4 查看分支
          • □ git branch
          • □ git branch -r
          • □ git branch -a
        • 1.5 分支合并
          • □ git merge [branch]
        • 1.6 解决冲突
          • □ 分支策略
        • 1.7 删除分支
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
        http://www.vxiaotou.com