git笔记--(3) --分支管理

来源:互联网 发布:路径优化tsp的发展 编辑:程序博客网 时间:2024/06/08 13:11

4.1分支管理

git checkout -b dev #创建分支,并切换到新建分支。

相当于:
git branch <branch name> #创建分支
git checkout dev #切换分支

git branch #查看分支,当前分支前面会标一个*号。

git merge <branch> #合并分支,合并指定分支到当前分支。

$ git merge dev
Updating d17efd8..fec145a
Fast-forward
 readme.txt |    1 +
 1 file changed, 1 insertion(+)

注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。

git branch -d <branch name> #删除分支

因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。

4.2分支冲突

如果在2个分支上都对一个文件的相同位置进行修改,那么当2个分支合并时,会产生冲突。
例如:
master分支,feature1分支都对readme.txt的同一位置进行修改。
在master分支上合并feature1分支。

$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

我们可以直接查看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用<<<<<<<,=======,>>>>>>>标记出不同分支的内容。
作出合适的修改后,提交。

用带参数的git log也可以看到分支的合并情况:
$ git log --graph --pretty=oneline --abbrev-commit

--graph #可以看到分支合并图。
--pretty=online #用一行来表示
--abbrev-commit #缩写commit_id

然后,就可以删除feature1分支。
$ git branch -d feature1
Deleted branch feature1 (was 75a857c).

重要注释:
一.
分支合并部分楼主只提到master先合并dev时对冲突进行手动修改然后提交。其中有几个问题不清楚实际测试了一下才知道。

1)出现冲突时,在master修改冲突并commit之前无法切换到dev分支。

2)master修改冲突并提交之后切换到dev,发现dev内容保持原来不变(合并之前dev分支)。

3)此时在dev下再次合并master无冲突,直接替换成master修改冲突并提交之后的内容。

dev先合并master的情况相同。

二.
3)很重要,在实际开发中会经常用到,这样可以保持冲突后的一致性。

三.
我理解的冲突的情况。一般来说,只要没merge过,两个分支对同一个文件的任何位置的修改都会出现分支的冲突。
例如,我们从master建立一个新分支dev,
(1)dev修改而master不修改,则是最一般和最理想的情况,没有冲突。
(2)dev修改,master也修改(在master分支上的修改,或者另外分支合并造成修改),这里的修改指对同一个文件的修改,这样才会产生逻辑的冲突,都会产生分支冲突。

实验跟楼主在楼下总结的“实际项目中master是主线,每个开发小组都有自己的分支,比如dev-1, dev-2,每个组都要干两件事:
1)把自己的dev-N往master merge:自己的修改提交到master,
2)把master往自己的dev-N merge:获得别人的修改。”相吻合。

4.3分支管理策略

通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
(!!因为在fast forward模式中,直接将master指针指向合并的分支指针,逻辑图上看,2个分支就是一条线,意味着分支信息丢掉。)
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
(!!逻辑图上,会显示出分别的分支,这在实际开发中经常用到。)

--no-ff方式的git merge:

$ git merge --no-ff -m "merge with no-ff" dev

我亲自做了2中方式的对比。可以从分支历史图上看出。

git log --graph

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

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

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

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

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

4.4Bug分支

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

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

那么在下面的情况下呢?
我们在dev分支上,任务正在进行中没有完成,这时要在master分支上修改一个bug。

Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作。

$ git stash #存储现场
$ git checkout master #切换到master分支,建立新分支,修改,合并,删除。
..
..
..
$ git checkout dev #切换到dev分支

$ git stash list #查看保存的工作现场,栈结构

恢复有2种,
(1)
$ git stash apply #恢复,但是恢复后stash内容不删除
$ git stash drop #删除stash相应内容

(2)

$ git stash pop #恢复的同时,也将stash相应内容删除

你可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:
$ git stash apply stash@{0}

当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。
重要注释:
一.
在处理完bug,回到工作的分支后,因为master分支修改了bug,在工作分支还有存在这那个bug,即和原来一样。
二.由于这样,再合并的时候可能会出现分支冲突,按照之前的方法处理就可以。


4.5Feature分支

软件开发中,总有无穷无尽的新的功能要不断添加进来。

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

如果在feature分支进行中,发现不需要feature的功能,就需要删除。

$ git branch -D feature-vulcan #删除未合并过的分支

使用-d参数会有提示,无法删除。
开发一个新feature,最好新建一个分支;

如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除。

4.6多人协作

$ git remote #查看远程库的信息
$ git remote -v #详细信息

推送分支
$ git push origin master #推送master分支
$ git push origin dev #推送dev分支

* master分支是主分支,因此要时刻与远程同步;

* dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;

* bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;

* feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

抓取分支
可以在另一台电脑(注意要把SSH Key添加到GitHub)或者同一台电脑的另一个目录下克隆。
$ git clone git@github.com:michaelliao/learngit.git
不过,只能看到master分支。
$ git branch #查看分支
如果需要dev分支,
$ git checkout -b dev origin/dev

修改之后可以推送,
$ git push origin dev

如果你在推送之前,有人已经推送了自己的修改。这时会有冲突。
需要将最新的提交抓取下来,然后与本地合并,解决冲突,再推送。
$ git pull
第一次会失败,原因是没有指定本地dev分支与远程origin/dev分支的链接。根据提示,建立连接。
$ git branch --set-upstream dev origin/dev #具体格式可能不同,按照git push里的提示做

解决冲突之后,push。

因此,多人协作的工作模式通常是这样:

首先,可以试图用git push origin branch-name推送自己的修改;

如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;

如果合并有冲突,则解决冲突,并在本地提交;

没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!

如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name。

这就是多人协作的工作模式,一旦熟悉了,就非常简单。

在Git里,这个分支叫主分支,即master分支。一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上。Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变。假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并。合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支。


0 0
原创粉丝点击