git入门-分支

时间:2023-03-08 20:48:25

1. git分支简介

使用分支可以让你从开发主线上分离开来,然后在新的分支上解决特定问题,同时不会影响主线。像其它的一些版本控制系统,创建分支需要创建整个源代码目录的副本。而Git 的分支是很轻量级的,因为Git保存的不是文件差异,而是一系列文件快照。在Git提交时,会保存一个commit对象,该对象包含一个指向暂存内容快照的指针,Git 会先计算每一个子目录的校验和( SHA-1 哈希字串),然后在 Git 仓库中将这些目录保存为树(tree)对象。之后 Git 创建的提交对象,除了包含相关提交信息以外,还包含着指向这个树对象的指针,如此它就可以在将来需要的时候,重现此次快照的内容了。Git 中的分支,其实本质上是个指向 commit 对象的可变指针,Git 会使用 master 作为分支的默认名字,
它在每次提交的时候都会自动移动,指向最后一次提交对象。Git使用一个名为HEAD的指针,指向你正在工作的本地分支,这样你就可以知道当前在哪个分支下面工作。

2. 创建分支

1
git branch dev

上面操作会在当前的commit对象上新建一个名为dev的分支指针,但是仅仅是创建了该分支,并没有切换到dev分支,此时你还在master分支。

3. 切换分支

1
git checkout dev

此时切换到了新建的dev分支,即HEAD指向了dev分支。
ps:可以加上-b参数

1
git checkout -b dev

相当于执行

1
2
git branch dev
git checkout dev

现在我们在当前目录下进行下面的操作:

1
2
3
vim test.py
git add test.py
git commit -m "add test.py"

我们在当前目录下新建了test.py文件,并添加到本地仓库,注意:现在dev分支移动了一格,而master分支还指向原来的commit对象,test.py文件只属于dev分支,master分支并没有该文件。
现在切换到master分支

1
git checkout master

可以看到当前目录下是没有test.py文件的。因为Git 会把工作目录的内容恢复为检出某分支时它所指向的那个提交对象的快照,它会自动添加、删除和修改文件以确保目录的内容和你当时提交时完全一样。

4. 合并分支

使用dev分支完成一些需求后,需要回到开发主线把它合并到master分支。

1
git merge dev

ps:需切换到master分支
合并时出现了“Fast-forward”的提示,因为当前master分支所在的提交对象是要并入的分支dev的直接上游,换句话说,如果顺着一个分支直走下去可以到达另一分支的话,合并两者时不存在任何需要解决的分歧,只需简单的移动指针,这种合并过程称为“Fast-forward”。如果当前master分支所指向的提交对象不是dev分支的直接祖先,Git需要做一些额外处理,Git会用两个分支的末端和它们的共同祖先进行一次简单的三方合并,并做一个新的快照,自动创建一个指向它的提交对象。这个对象有两个祖先,即之前两个分支的末端。合并之后,dev分支和master分支指向同一位置,master分支指向的提交对象就是最新的修改了。

如果不同分支修改了同一文件,合并时可能会遇到冲突,此时Git做了合并,但是并没有提交。使用git status查看哪些文件发生了冲突。解决了所有的冲突后,执行git add将它们添加到暂存区域,因为一旦暂存就表示冲突已解决,然后使用git commit完成这次合并的提交。

5. 删除分支

1
git branch -d dev

6. 分支管理

6.1 列出当前所有分支的清单

1
2
3
4
git branch
dev
* master

master分支前的*字符:表示当前所在的分支。

6.2 查看各个分支最后一个提交对象的信息

1
2
3
4
git branch -v
dev [7e90b1 add helloworld.java
* master c7e90b1 [ahead 1] add helloworld.java

6.3 查看已经与当前分支合并的分支

1
2
3
4
git branch --merged
dev
* master

6.4 查看已经与当前分支未合并的分支

1
git branch --no-merged

7. 远程分支

7.1 查看远程分支

1
2
3
4
git branch -r
origin/HEAD -> origin/master
origin/master

7.2 创建远程分支
即把本地分支推送到远程

1
2
3
4
5
6
git push origin dev
git branch -r
origin/HEAD -> origin/master
origin/dev
origin/master

看到已把dev分支成功push到服务器上

7.3 同步远程服务器上的数据到本地

1
git fetch origin

7.4 跟踪远程分支
从远程拉取dev分支到本地,并切换到dev分支,ps:需要git1.6.2以上版本

1
git checkout --track origin/dev

从远程拉取dev分支到本地,命名为develop,并切换到develop分支

1
git checkout -b develop origin/dev

7.5 提交本地分支数据到远程服务器
git push origin local:remote

1
git push origin dev:dev

如果当前是在dev分支下工作,可直接git push

7.6 删除远程分支

1
git push origin :dev

8. 分支的衍合

把一个分支整合到另一个分支有两种方法:merge和rebase(衍合)
前面已经介绍过,merge是把两个分支最新的快照和二者最新的共同祖先进行三方合并,产生一个新的提交对象。rebase是回到两个分支的共同祖先,根据要进行衍合的分支dev的历次提交对象,生成一系列文件补丁,然后以主干分支master的最后一个提交对象为新的出发点,逐个应用dev分支准备好的补丁文件,生成一个新的提交对象,改写dev的提交历史,使dev成为master的直接下游。然后回到master分支,进行一次快进合并。这样能够保持更加清晰的提交记录,就像没有使用过分支一样。

1
2
git checkout dev
git rebase master

ps:可以把衍合当作一种在推送之前清理提交历史的手段,如果分支中的提交对象已经发布到服务端,就千万不要对该分支进行衍合。