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: 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和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 |
当前已经是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,强制checkout成功,本地修改可能丢失。
测试git版本2.7.4