切换分支

  • git checkout

切换分支时,Git 做了什么?

切换分支,首先意味着 HEAD 的指向变化了,比方说切换到 master 分支:

$ git checkout master

// 内部命令
$ git symbolic-ref HEAD refs/heads/master

git checkout的参数除了分支名之外,还可以是标签名或者是提交对象:

$ git checkout v2.6.17

这时候切换到了一个游离的提交位置上。当然这不是常见的情况,因为我们总是希望在某个分支上工作,而且这种游离的工作在一段时间之后是会被垃圾回收的。所以如果想要把游离的工作保留下来,你还是需要用git checkout -b <branchname>。应该说这本身就不是个好的做法。

在没有提交的情况下切换分支

通常来说,写代码之前我们会想好应该在哪个分支下面写,然后切换到那个分支去修改工作区。

但是,如果我在一个分支下面写了半天之后才发现,应该把这些代码放到别的分支去,这该怎么办?如果我不动已经"弄脏的"工作区,直接就git checkout切换过去,git 会怎么处理?

它有这么几个选择:

  1. 忽略工作区的修改,用新分支下的工作区代码
  2. 忽略新分支的工作区代码,把当前工作区的代码挪过去
  3. 尝试合并二者

很明显第一个选择是不可能的,因为这样做直接把我工作区里的工作成果全部丢弃了。第二个也不可能,因为当前分支切过去了,意味着我是希望以目的分支为工作起点的,但是工作区却还是起点分支的样子,我不得不把目的分支到起点分支之间的修改全部抹平,这不现实。

最合适的是第三个选择,Git 的做法也是如此。

没有冲突的提交

下面是一个例子,初始化项目:

$ git init
$ echo This is the README file. > README
$ git add .
$ git commit -m "init"

新建分支,修改工作区:

$ git checkout -b test
$ echo This line was added in the working directory while in the test branch. >> README
$ cat README
This is the README file.
This line was added in the working directory while in the test branch.

这时候如果要切换回 master 的话,实际上工作区就是不干净的,因为 README 都还没暂存提交。前面也提到了,这种情况 Git 会采用合并操作:

$ git checkout master
M   README
swtitched to branch 'master'
$ cat README
This is the REAMME file.
This line was added in the working directory while in the test branch.

$ git status
// 结果是处于未暂存状态,即,是处于工作区。

有冲突的提交

之前的没有冲突的情况还是比较简单,那如果冲突了呢?

开头和之前的例子一样:

$ git init
$ echo This is the readme file. > README
$ git add .
$ git commit -m "init"

现在开始有所不同:

$ git branch test
$ echo Second line added from the master branch. >> README
$ git commit -a -m "Line 2 added"

这里我先创建了一个 test 分支,然后在 master 分支上加了一行并且提交。

再回到 test 分支上:

$ git checkout test
$ cat README
This is the readme file.

这里没有把 master 分支的内容合并过来是因为 master 分支上的工作区是干净的。

然后 test 分支也开始修改:

$ echo Second line added from the test branch. >> README
$ git checkout master
error: You have local changes to 'README'; cannot switch branches.

很明白了,这时候的 test 分支上的工作区不干净,试图切换分支的时候会尝试合并到 master 分支上。但是修改了同一个地方导致了冲突,这时候无法成功地切换分支。

results matching ""

    No results matching ""