我已经不假思索地手动移动了一堆文件,并且无法找到让git识别文件只是被移动而不是实际上不同的文件的方法。有没有办法做到这一点,除了删除旧的并添加新的(从而丢失历史记录),或使用git-mv重做所有更改?
答案 0 :(得分:67)
要让git删除已删除或已移动的文件,只需输入
即可git add -u
答案 1 :(得分:20)
我认为它已经这样做了。现在,我可能是错的,但我读过git根据文件系统中的位置或基于delta /差异来跟踪文件的内容。在堆栈中我认为它显示它好像文件被删除然后重新添加,但我想我已经尝试了一次它仍然保持历史,由于上述git跟踪事物的方式。
如果有人确认我是否正确,仍然会有所帮助。对不起,如果我误解了你的问题。
答案 2 :(得分:11)
git
不会跟踪单个文件的历史记录,也不会特别处理移动和副本,也就是说没有特殊的元数据表明发生了移动或复制。相反,每个git commit都是工作树的完整快照。
如果您想查看git log
中的移动,除了列出哪些文件已更改的选项外,您还可以提供-M
,例如
git log --summary -M
git
将查看提交历史记录中的相邻树,并推断每个提交移动的文件是否存在。
要查找副本以及重命名,您可以使用-C
选项,您可以提供两次以使git看起来更难以找到可能的复制源而牺牲一些性能。
git log --summary -M -C -C
请注意,由于git不存储文件历史记录(仅提交历史记录),即使您执行了git rm
和git mv
文件,也不会丢失任何历史记录。对路径的所有更改仍会在git log
中记录并可见。
答案 3 :(得分:5)
为了更好地理解为什么Git会执行重命名检测而不是(更常见的)显式重命名跟踪,以及git log
路径限制如何工作,您可以阅读阅读Git维护者Junio C Hamano撰写的Linus's ultimate content tracking tool博客文章(以及其中的参考文献)。
答案 4 :(得分:0)
您可以将新文件移回/重命名为旧名称和git之外的路径,然后使用git mv
进行移动;例如在bash中:
mv $NEW $OLD && git mv $OLD $NEW
它有点麻烦 1 ,特别是如果你必须手工完成的话。但它有一个优点,即它会留下其他更改,例如更改名称空间或未分段的类名,以便您可以检查它们,并且只在您打算这样做时暂存它们。
1 我希望找到一个更好的选择,并在找到它时更新我的答案。
实施例:
我将一堆文件oldDir
移动到newDir
,并开始热情地进行其他一些更改。现在我想检查一下其他的修改。使用git xargs gawk和bash会产生以下结果(单行):
git status --short |
gawk '/^\?\?/ && match($0, /newDir\/(*.\.cs)/, a) {print "newDir/" a[1] " " "oldDir/" a[1]}' |
xargs -n 2 bash -c 'mv $0 $1; git mv $1 $0'
现在git status
显示重命名为"要提交的更改"以及#34;变更未进行提交"
答案 5 :(得分:0)
发生在我身上的是,当我移动和编辑文件时,它将不再识别为正在移动的文件,而是将其识别为新文件,因此我失去了历史记录。
我要做的是创建2个单独的提交,一个是在我移动文件时提交的,另一个是在编辑文件时进行的。这样,我便保留了历史。