checkout branch处理的原则是,只要不导致数据丢失,那么就不会阻止checkout成功,并且原来的修改会带到新的分支。
如果当前分支的工作树没有任何变化,且没有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: bPlease 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: bPlease, 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 aSwitched 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 mastererror: Your local changes to the following files would be overwritten by checkout: aPlease, commit your changes or stash them before you can switch branches.Aborting |
6 删除work tree里面分支的文件,则不管新分支是否有该文件,都checkout成功。所以,如果删除work tree目录里面所有的文件,然后切换到新分支,checkout总是会成功,且work tree就是新分支干净的文件。
如果当前的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 cSwitched to branch 'master'$ git stOn branch masterChanges 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 stOn branch testChanges 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: bPlease, 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 testerror: Your local changes to the following files would be overwritten by checkout: bPlease, 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 aSwitched to branch 'master'$ $ git stOn branch masterChanges 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: aPlease, 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 brm 'b'$$ git co testerror: The following untracked working tree files would be removed by checkout: bPlease 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 arm 'a'$$ git co testD aSwitched to branch 'test' |
10 删除index中的文件,且被删除的文件,在新分支存在,只删除index;如果新就分支该文件内容不相同,则checkout失败。
1 2 3 4 5 6 7 | $ git rm --cached arm 'a'$ git co mastererror: Your local changes to the following files would be overwritten by checkout: aPlease, commit your changes or stash them before you can switch branches.Aborting |
当前已经是master分支,再checkout master,或者checkout不指定任何参数,不会执行任何操作,除了检查一下改变了那些文件。
1 2 3 4 5 6 7 8 | $ git co testSwitched to branch 'test'$ echo xx >a $ git co testM aAlready on 'test'$ git coM a |
所以不要指望checkout当前分支,来更新工作树,正确的是使用 git reset命令。
使用-f,强制checkout成功,本地修改可能丢失。
测试git版本2.7.4