ILD

git checkout branch如何处理index和work tree
作者:YUAN JIANPENG 邮箱:yuanjp@hust.edu.cn
发布时间:2018-11-5 站点:Inside Linux Development

checkout branch处理的原则是,只要不导致数据丢失,那么就不会阻止checkout成功,并且原来的修改会带到新的分支。


Work Tree

如果当前分支的工作树没有任何变化,且没有untracked files,那么新的工作树将完全等于新分支的工作树(意味着旧分支多的文件将被删除,不同的文件将被覆盖)。


1 新添加一个文件,且这个文件不属于任何分支。则不管怎么切换分支,这个文件是不会变的,因为这个文件不归git管辖,git不会touch这个文件。


2 新添加一个文件,但是新的分支有这个文件,则checkout将失败,因为checkout尝试将新文件覆盖旧文件时,可能导致数据丢失。git不会检查文件的内容,即使前后相同checkout也会失败。

1
2
3
4
5
$ git co master 
error: The following untracked working tree files would be overwritten by checkout:
    b
Please move or remove them before you can switch branches.
Aborting


3 如果一个文件属于当前分支,但不属于新分支,如果文件不变,则checkout成功,且该文件被删除。如果这个文件变了,则checkout失败,因删除会导致数据丢失。

1
2
3
4
5
6
$ echo x > b
$ git co test 
error: Your local changes to the following files would be overwritten by checkout:
    b
Please, commit your changes or stash them before you can switch branches.
Aborting


4 如果一个文件同时属于新旧分支,且该文件在两个分支的内容相同,如果该文件不变,则显然checkout成功;如果该文件变化,checkout仍然成功,并且旧文件不变,被带到新的分支。

1
2
3
4
5
6
$ echo b > a
$ git checkout master 
M   a
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)


5 如果一个文件同时属于新旧分支,但是文件的内容不同,如果该文件不变,则显然checkout成功。如果文件变化,则checkout失败。

1
2
3
4
5
6
$ echo x > a
$ git co master
error: Your local changes to the following files would be overwritten by checkout:
    a
Please, commit your changes or stash them before you can switch branches.
Aborting


6 删除work tree里面分支的文件,则不管新分支是否有该文件,都checkout成功。所以,如果删除work tree目录里面所有的文件,然后切换到新分支,checkout总是会成功,且work tree就是新分支干净的文件。


Index

如果当前的index和HEAD相同,那么checkout后,新分支的index等于新分支的HEAD。是完全干净的checkout。


1 添加一个新旧分支都不存在的文件,checkout成功,新分支的index包含这个新添加的文件。

1
2
3
4
5
6
7
8
9
10
11
$ echo c > c
$ git add c
$ git co master 
A   c
Switched to branch 'master'
$ git st
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
 
    new file:   c


2 添加一个新文件,该文件在新分支存在,如果该文件的内容和新分支相同,那么checkout成功;如果内容和新分支不同,那么checkout失败。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ echo xb > b
$ git add b
$ git st
On branch test
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
 
    new file:   b
 
$ git co master 
error: Your local changes to the following files would be overwritten by checkout:
    b
Please, commit your changes or stash them before you can switch branches.
Aborting


4 修改一个文件,如果该文件在新分支不存在,则checkout失败,因为尝试删除这个文件,会导致数据丢失。

1
2
3
4
5
6
7
8
$ echo bx > b
$ git add b
$ git co test
error: Your local changes to the following files would be overwritten by checkout:
    b
Please, commit your changes or stash them before you can switch branches.
Aborting


5 修改一个文件,如果该文件在新分支存在,且新旧分支的内容相同,那么修改的内容被带到新checkout的index:

1
2
3
4
5
6
7
8
9
10
11
12
$ echo xa > a
$ git add a
$ git co master 
M   a
Switched to branch 'master'
$ git st
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
 
    modified:   a


6 修改一个文件,如果该文件在新分支存在,且新旧分支的内容不同,如果修改后的内容和新分支相同,则checkout成功;如果修改的内容和新分支不同,则checkout失败。

1
2
3
4
5
6
7
$ echo ax > a
$ git add a
$ git co test 
error: Your local changes to the following files would be overwritten by checkout:
    a
Please, commit your changes or stash them before you can switch branches.
Aborting


7 删除index中的文件,且被删除的文件,在新分支不存在;如果工作树和index同时删除,则checkout成功;如果只删除index,则失败:

1
2
3
4
5
6
7
8
l$ git rm --cached b
rm 'b'
$
$ git co test
error: The following untracked working tree files would be removed by checkout:
    b
Please move or remove them before you can switch branches.
Aborting


8 删除index中的文件,且被删除的文件,在新分支存在;如果index和工作树同时删除,则checkout成功;且新的index和work tree中该文件,为新分支的内容。


9 删除index中的文件,且被删除的文件,在新分支存在,只删除index;如果新就分支该文件内容相同,则checkout成功,且index中,该文件保持被删除的状态。

1
2
3
4
5
6
$ git rm --cached a
rm 'a'
$
$ git co test
D   a
Switched to branch 'test'


10 删除index中的文件,且被删除的文件,在新分支存在,只删除index;如果新就分支该文件内容不相同,则checkout失败。

1
2
3
4
5
6
7
$ git rm --cached a
rm 'a'
$ git co master
error: Your local changes to the following files would be overwritten by checkout:
    a
Please, commit your changes or stash them before you can switch branches.
Aborting


checkout当前分支

当前已经是master分支,再checkout master,或者checkout不指定任何参数,不会执行任何操作,除了检查一下改变了那些文件。

1
2
3
4
5
6
7
8
$ git co test
Switched to branch 'test'
$ echo xx >a 
$ git co test
M   a
Already on 'test'
$ git co
M   a

所以不要指望checkout当前分支,来更新工作树,正确的是使用 git reset命令。


-f 选项

使用-f,强制checkout成功,本地修改可能丢失。


测试git版本2.7.4


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.