Git

Git 分支操作

Posted by AspenStars on June 24, 2021

本地分支

创建分支

1
2
3
4
5
git checkout -b iss53

# 等价于
git branch iss53
git checkout iss53

删除分支

1
git branch -d hotfix

分支的合并

检出到你想合并入的分支(要保留的那个分支),然后运行 git merge 命令:

1
2
3
4
5
6
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

远程分支

GitHub上远程分支默认为origin

远程仓库名字 “origin” 与分支名字 “master” 一样,在 Git 中并没有任何特别的含义一样。 同时 “master” 是运行 git init 时默认的起始分支名字,原因仅仅是它的广泛使用, “origin” 是运行 git clone 时默认的远程仓库名字。 如果运行 git clone -o booyah,那么默认的远程分支名字将会是 booyah/master

获得远程分支的信息

1
2
3
4
5
6
7
8
9
# 获得远程引用的完整列表
git ls-remote <remote>

# 获得远程分支的详细信息
git remote show <remote> 

# e.g.,  也可以不带`origin`
git ls-remote origin
git remote show origin

添加一个远程分支

在已有的远程分支的基础上添加第二个也可以用这个命令

一般默认将GitHub的分支命名为origin,此处示例添加第二个远程分支

1
2
3
4
git remote add <remote> <remote-url>

# 添加远程分支git@github.com:aspenstarss/project.git,并命名一个简称为new-remote
git remote add new-remote git@github.com:aspenstarss/project.git

推送

本地的分支并不会自动与远程仓库同步,必须显式地推送想要分享的分支

1
2
3
4
5
6
7
8
9
git push <remote> <branch>

# 推送本地的 serverfix 分支来更新远程仓库上的 serverfix 分支
git push origin serverfix
# 等价于
git push origin serverfix:serverfix

# 将本地的 serverfix 分支推送到远程仓库上的 awesomebranch 分支
git push origin serverfix:awesomebranch 

Note

可以运行 git fetch <remote> 来抓取远程仓库 <remote> 有而本地没有的数据

当抓取到新的远程跟踪分支时(e.g., serverfix分支),本地不会自动生成一份可编辑的副本(拷贝)
换一句话说,这种情况下,不会有一个新的 serverfix 分支,只有一个不可以修改的 origin/serverfix指针
可以运行 git merge origin/serverfix 将这些工作合并到当前所在的分支。

如果想要在自己的 serverfix 分支上工作,可以将其建立在远程跟踪分支之上:

1
2
3
$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

这会建立一个用于工作的本地分支,并且起点位于 origin/serverfix。

跟踪分支

跟踪分支是与远程分支有直接关系的本地分支。 如果在一个跟踪分支上输入 git pull,Git 能自动地识别去哪个服务器上抓取、合并到哪个分支。

从一个远程分支检出一个本地分支会自动创建“跟踪分支”(它的远程分支叫做“上游分支”)。当克隆一个仓库时,它通常会自动地创建一个跟踪 origin/master 的 master 分支。

可以设置跟踪分支为在其他远程仓库上的跟踪分支,或者不跟踪分支
e.g.,运行 git checkout -b <branch> <remote>/<branch>
这是一个十分常用的操作所以 Git 提供了 –track 快捷方式:

1
2
3
$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

由于这个操作太常用了,该捷径本身还有一个捷径。 如果尝试检出的分支不存在且刚好只有一个名字与之匹配的远程分支,那么 Git 就会为创建一个跟踪分支
假设serverfix本地不存在,远程有一个

1
2
3
$ git checkout serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

如果想要将本地分支与远程分支设置为不同的名字,你可以轻松地使用上一个命令增加一个不同名字的本地分支,本地分支 sf 会自动从 origin/serverfix 拉取。

1
2
3
$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'

设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的上游分支
可以在任意时间使用 -u--set-upstream-to 选项运行 git branch 来显式地设置

1
2
$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.

查看设置的所有跟踪分支

1
git branch -vv  

将所有的本地分支列出来并且包含更多的信息,如每一个分支正在跟踪哪个远程分支与本地分支是否是领先、落后或是都有。

1
2
3
4
5
$ git branch -vv
  iss53     7e424c3 [origin/iss53: ahead 2] forgot the brackets
  master    1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
  testing   5ea463a trying something new

这里可以看到 iss53 分支正在跟踪 origin/iss53 并且 “ahead” 是 2,意味着本地有两个提交还没有推送到服务器上。 也能看到 master 分支正在跟踪 origin/master 分支并且是最新的。 接下来可以看到 serverfix 分支正在跟踪 teamone 服务器上的 server-fix-good 分支并且领先 3 落后 1, 意味着服务器上有一次提交还没有合并入同时本地有三次提交还没有推送。 最后看到 testing 分支并没有跟踪任何远程分支。

Note: 这些数字的值来自于你从每个服务器上最后一次抓取的数据。 这个命令并没有连接服务器,它只会告诉你关于本地缓存的服务器数据。 如果想要统计最新的领先与落后数字,需要在运行此命令前抓取所有的远程仓库。 可以像这样做:

1
$ git fetch --all; git branch -vv

拉取

git fetch 命令从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容。 它只会获取数据然后让你自己合并

git pull 在大多数情况下它的含义是一个 git fetch 紧接着一个 git merge 命令。

如果有一个像之前章节中演示的设置好的跟踪分支,不管它是显式地设置还是通过 clonecheckout 命令为创建的,git pull 都会查找当前分支所跟踪的服务器与分支, 从服务器上抓取数据然后尝试合并入那个远程分支。

Note: 由于 git pull 的魔法经常令人困惑所以通常单独显式地使用 fetchmerge 命令会更好一些

不过我主要还是用git pull

删除远程分支

假设你已经通过远程分支做完所有的工作了——也就是说你和你的协作者已经完成了一个特性, 并且将其合并到了远程仓库的 master 分支(或任何其他稳定代码分支)。 可以运行带有 --delete 选项的 git push 命令来删除一个远程分支。 如果想要从服务器上删除 serverfix 分支,运行下面的命令:

1
2
3
$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
 - [deleted]         serverfix

基本上这个命令做的只是从服务器上移除这个指针。 Git 服务器通常会保留数据一段时间直到垃圾回收运行,所以如果不小心删除掉了,通常是很容易恢复的。