git mv file1 file2
git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: file1 -> file2
git stash
git stash pop
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: file2
#
# Changes not staged for commit:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: file1
正如您所看到的,git在存储/弹出后丢失了重命名的关系。有没有办法重新获得这种关系,或者藏匿知道文件被移动了?我经常藏匿以查看我的系统状态是什么样的预更改,但让它失去重命名关系对我来说是一个问题。除了删除新文件,再次执行git mv以及替换新文件的内容之外,我不知道如何修复它。
答案 0 :(得分:37)
如果尚未弹出您的存储,请执行以下操作:
git stash pop --index
这样可以在存储中正确保留已移动(但未提交)的文件关系。根据{{1}}:
如果使用--index选项,则尝试不仅恢复工作树的更改,还尝试恢复索引的更改。但是,如果存在冲突(存储在索引中,因此您无法再按原样应用更改),则可能会失败。
如果您已经弹出您的存储并希望重新创建已移动的关系,请执行以下操作:
git help stash
这将从索引中删除“旧的”未移动文件:
使用此选项仅从索引
取消暂存和删除路径
答案 1 :(得分:20)
简短回答:git rm --cached file1
所有git mv
确实重命名文件(在文件系统上),然后将文件删除和创建添加到索引(暂存区域)。它没有特别标记。其他机器随后通过查看之前称为file1的内容现在称为file2来实现重命名。
由于git stash
命令会修改索引,因此它们会扰乱事物。请注意,现在您已经创建了暂存,但没有删除! (通常git-stash会在弹出后保留所有未分级的内容,但在这种情况下,我认为它没有太多选择,只能将新文件放在索引中,以避免您不知道要保留哪一个。您可以避免这种情况与git stash pop --index
一起发生,但如果无法干净地应用隐藏的更改,那就会爆炸,因此它不是默认的。)git status
不能再将其显示为重命名,因为重命名是在索引和工作树之间有效地分开,两个部分都不能完全声明它。
只需运行git rm --cached file1
即可暂停删除(即从索引中删除file1),它将再次显示为重命名。您也可以运行git add -u
自动添加更改,只要您没有其他您不想进行的更改。
请注意,这意味着在实践中您无需担心:当您准备好提交所有内容(例如使用git add -u
)时,“问题”会自行处理。