Git-分支管理

本文深入探讨Git的分支管理策略,包括创建与合并分支、多人协作、Bug与Feature分支的处理,以及Rebase的使用技巧。通过实例演示如何解决冲突,保持项目历史整洁,适合团队开发使用。

背景

好处

1552400906464

过程

开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

git-br-initial

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

当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

git-br-create

你看,Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!

不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:

git-br-dev-fd

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

git-br-ff-merge

所以Git合并分支也很快!就改改指针,工作区内容也不变!

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

git-br-ff-merge

创建与合并

查看分支

git branch 
git branch -v  //显示详情

创建分支

git branch [name] 

切换分支

git checkout [name] 

创建+切换分支:

git checkout -b <name>

1552383408443

合并某分支到当前分支

git merge <name>

第一步,切换到接受修改的分支

第二步,执行 merge 命令

1552383800232

删除分支

git branch -d <name>

1552384111616

解决冲突

修改冲突案例

准备新的feature1分支,继续新分支开发:

$ git checkout -b feature1
Switched to a new branch 'feature1'

修改readme.txt最后一行,改为:

Creating a new branch is quick AND simple.

feature1分支上提交:

$ git add readme.txt

$ git commit -m "AND simple"
[feature1 14096d0] AND simple
 1 file changed, 1 insertion(+), 1 deletion(-)

切换到master分支:

$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Git还会自动提示我们当前master分支比远程的master分支要超前1个提交。

master分支上把readme.txt文件的最后一行改为:

Creating a new branch is quick & simple.

提交:

$ git add readme.txt 
$ git commit -m "& simple"
[master 5dc6824] & simple
 1 file changed, 1 insertion(+), 1 deletion(-)

现在,master分支和feature1分支各自都分别有新的提交,变成了这样:

git-br-feature1

Git告诉我们,readme.txt文件存在冲突,必须手动解决冲突后再提交。git status也可以告诉我们冲突的文件:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:   readme.txt

no changes added to commit (use "git add" and/or "git commit -a")

我们可以直接查看readme.txt的内容:

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1

Git用<<<<<<<=======>>>>>>>标记出不同分支的内容,我们修改如下后保存:

Creating a new branch is quick and simple.

再提交:

$ git add readme.txt 
$ git commit -m "conflict fixed"
[master cf810e4] conflict fixed

现在,master分支和feature1分支变成了下图所示:

git-br-conflict-merged

添加冲突案例

1552404286964

1552404420907

1552404388179

1552405300304

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

总结

1552405484903

  1. 编辑冲突文件,删除特殊符号并修改至合适版本,保存退出。

  2. 将冲突文件添加至暂存区,git add

  3. 将冲突文件提交到版本库,git commit

    注意:commit 后面不带具体文件名

分支管理策略

Fast forward

通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。

如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

git merge --no-ff -m [日志信息] [分支信息]

首先,仍然创建并切换dev分支,修改readme.txt文件,并提交一个新的commit。
然后切换回master,准备合并dev分支,请注意--no-ff参数,表示禁用Fast forward

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

git-no-ff-mode

分支策略

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

首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;

你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

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

git-br-policy

img

Bug分支

软件开发中,bug就像家常便饭一样。有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。

当前正在dev上进行的工作还没有提交:

$ git status
On branch dev
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   hello.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   readme.txt

创建储藏

$ git stash
Saved working directory and index state WIP on dev: f52c633 add merge

现在,用git status查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。

首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支

 git checkout master
 
 git checkout -b 【临时分支】

现在修复bug,需要把“Git is free software ...”改为“Git is a free software ...”,然后提交:

git add readme.txt

git commit -m "日志信息"

修复完成后,切换到master分支,并完成合并,最后删除临时分支

git checkout master

git merge --no-ff -m "日志信息" [临时分支]

git branch -d dev

查看储藏

git stash list

恢复储藏

  • git stash apply恢复储藏(工作现场),但是恢复后,stash内容并不删除,你需要用git stash drop来删除
git stash apply 【储藏序号:stash@{0}】 //恢复

git stash drop 【储藏序号:stash@{0}】 //删除
  • git stash pop,恢复的同时把stash内容也删了
git stash pop

取消储藏

在某些情况下,你可能想应用储藏的修改,在进行了一些其他的修改后,又要取消之前所应用储藏的修改。Git没有提供类似于 stash unapply 的命令,但是可以通过取消该储藏的补丁达到同样的效果:

$ git stash show -p stash@{0} | git apply -R

同样的,如果你沒有指定具体的某个储藏,Git 会选择最近的储藏:

$ git stash show -p | git apply -R

小结

修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;

当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。

Feature分支

添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。

如果在Feature分支还没有被合并时,需要将分支删除,需要进行强删:

git branch -D feature-vulcan

开发一个新feature,最好新建一个分支。

Rebase

merge 和 rebase关系

git rebase 和git merge 做的事其实是一样的。它们都被设计来将一个分支的更改并入另一个分支,只不过方式有些不同。

merge

命令示例

git checkout feature
git merge master

这样feature 分支中新的合并提交(merge commit)将两个分支的历史连在了一起

Merge 好在它是一个安全的操作。现有的分支不会被更改

每次合并上游更改时 feature 分支都会引入一个外来的合并提交。如果上游分支 非常活跃的话,这或多或少会污染你的分支历史

Rebase

命令示例

git checkout feature
git rebase master

它会把整个 feature 分支移动到 master 分支的后面,有效地把所有 master 分支上新的提交并入过来

但是,rebase 为原分支上每一个提交创建一个新的提交,重写了项目历史,并且不会带来合并提交。

rebase的优点和缺点

优点

  • rebase最大的好处是你的项目历史会非常整洁
  • rebase 导致最后的项目历史呈现出完美的线性——你可以从项目终点到起点浏览而不需要任何的 fork。这让你更容易使用 git log、git bisect 和 gitk 来查看项目历史

缺点

  • 安全性,如果你违反了 rebase 黄金法则,重写项目历史可能会给你的协作工作流带来灾难性的影响
  • 可跟踪性,rebase 不会有合并提交中附带的信息——你看不到 feature 分支中并入了上游的哪些更改

交互式的 rebsase

允许你更改并入新分支的提交。这比自动的 rebase 更加强大,因为它提供了对分支上提交历史完整的控制

一般来说,这被用于将 feature 分支并入 master 分支之前,清理混乱的历史。

命令示例:

git checkout feature

git rebase -i master

使用rebase合并多个commit为一个完整的commit

git rebase

参考文献

创建与合并分支

多人协作

Bug分支

尚硅谷视频 Git分支管理

3 Git 工具 - 储藏(Stashing)

聊下 git rebase -i

Git rebase详细解析

转载于:https://www.cnblogs.com/jerzy/p/10535308.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值