git分支

前面介绍了一些关于git的知识,然后下面重点介绍一下git分支

分支

分支的主要应用场景是“假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。”
git处理分支的方式非常轻量,不像其它版本控制系统一样需要完全创建一个源代码目录副本,它只是为你创建了一个可以移动的新的指针,然后又有一个HEAD指针指向当前分支。
“截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。”

创建分支

git checkout -b dev创建dev分支,并切换到了dev分支
该命令可分解为git branch devgit checkout dev或者使用git switch -c dev,切换使用git switch dev
git branch可以用来查看当前所在分支和所有的分支
在dev分支上进行操作,看看master分支啥情况:

  1. 修改test1.txt;
  2. git add .git commit -m "dev"
  3. 切换回主分支git checkout master
  4. 发现test1.txt没有任何变化

我觉得git官方上画的图和解释的比较清楚:
创建testing分支并切换到testing分支时:
1
testing分支有commit操作时:
2
切换回主分支后:
3
指针所指的正是我们的commit快照,都有一个commitID(sha1算法产生的)

合并分支

现在我们把dev分支上的工作合并到主分支上:
git merge dev

1
2
3
4
Updating 4b194ea..535f59d
Fast-forward
test1.txt | 1 +
1 file changed, 1 insertion(+)

采用的是Fast-Forward方式,即此时将master指向dev的当前提交,所以合并速度非常快。

合并如何出现冲突?

我们经常会遇见合并不成功,出现冲突
一般是指经过了下列操作:

  1. 切换到dev分支git switch dev,修改test1.txt的第一行内容为12345;
  2. 执行add和commit;
  3. 切回到主分支,修改test1.txt的第一行内容为678910;
  4. 执行add和commit

此时分支结构变为了下图:
4
这种情况下我们进行合并git merge dev

1
2
3
Auto-merging test1.txt
CONFLICT (content): Merge conflict in test1.txt
Automatic merge failed; fix conflicts and then commit the result.

出现合并冲突了,无法自动合并了,git status也可以查看更多信息:

1
2
3
4
5
6
7
8
9
10
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: test1.txt
no changes added to commit (use "git add" and/or "git commit -a")

此时test1.txt变成了下列内容:
5
标出了不同分支的内容,此时我们将主分支的内容改为12345,再add和commit
然后合并分支发现可以了
现在分支结构变为了:
6
使用git log也可以查看到分支的合并情况:
git log --graph --pretty=oneline --abbrev-commit

不使用FAST-FORWARD方式合并

我们之前讲过了自动合并使用的是FAST-FORWARD方式,此时将master指向dev的当前提交,所以合并速度非常快。
如下图所示:
7
但是这样会存在一个问题,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
git merge --no-ff -m "merge with no-ff" dev,但是我刚才试了试,发现只有第一个文件的合并采用的Fast forward模式,后来都是没采用,如下图所示分支结构为:
8

git push推送的是哪一个分支?

现在我们本地有两个分支主分支和dev分支,现在要推送至远程仓库里,就要使用git push命令,其实我们之前所使用的git push命令默认都是在主分支,然后默认也是推送给仓库里的主分支上的
现在进行细化:
如果想推送某一分支到远程仓库的某一分支:

  1. 切换到对应分支,如git checkout dev
  2. 推送:git push origin dev

当然该dev分支可以不推送至远程仓库,自己玩也行

多人协作

注意此时当别人clone这个远程库时,只能看到主分支,并不能看到dev分支,如果想要在dev分支上工作的话,需要git checkout -b dev origin/dev
现在我的主分支上还没有push,如果别人在主分支上新建了一个test5.txt,然后他add、commit和push(成功push)了,那我这端的主分支如果push会有什么样的效果呢?
报错了:

1
2
3
4
5
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

那更不用提有冲突的push了,解决办法就是要使用git pull
但是如果别人push的是test1.txt,并且我也在改text1,并且修改内容不同,我也想push,会咋样呢?
此时别人将test1.txt改为了12345,push上去了,然后我将test1.txt改为了12356,也想push咋办呢?
我先git pull

1
2
3
Auto-merging test1.txt
CONFLICT (content): Merge conflict in test1.txt
Automatic merge failed; fix conflicts and then commit the result.

冲突了,如何解决呢?那就现在本地解决好了冲突后再add、commit和push就可以了,然后git pull就没问题了

我们发现在别人那里查看日志也发现里面含有全部的版本日志,包括分支合并等。