我有一个名为package/old/myfile.java
的java文件。我通过git提交了这个文件。然后我将我的包重命名为new
,因此我的文件位于package/new/myfile.java
。
我现在想将此文件重命名(和内容更改)提交给git。
当我git status
时,我得到了
# 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: package/old/myfile.java
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# package/new/myfile.java
我已经尝试add
新的rm
旧的,反之亦然,我一直在
$ git status
# On branch develop
# Changes to be committed:
# delete: package/old/myfile.java
# new file: package/new/myfile.java
我无法mv old new
因为旧文件不存在而导致bad source
错误。
还有什么我可以尝试的吗?
我已经针对类似问题在SO上尝试了一些多个答案,但它们没有用。
答案 0 :(得分:16)
relevant section中的git book解释了这一点。
与许多其他VCS系统不同,Git没有明确跟踪文件移动。如果您在Git中重命名文件,Git中不会存储任何元数据,告诉您重命名该文件。但是,Git非常聪明地知道事后 - 我们将稍后处理检测文件移动的问题。
这意味着如果您移动文件然后进行重大更改,git就不会知道这是一个移动。它会看到一个文件被删除并且创建了一个新文件,因为新文件看起来不像旧文件。为了解决这个人经常git mv
个文件,提交移动,然后进行更改。在你的情况下你可以做到
git reset # Move changes from index to working copy
git checkout package/old/myfile.java # Undo delete
git mv package/old/myfile.java package/new/myfile.java # Move file
答案 1 :(得分:6)
将文件移回,然后提交,并将实际移动放入单独的提交中。 Git不会记录移动(或重命名),但可以根据内容识别它们。如果内容发生变化,则无法正确检测到移动。因此,通常的做法是将移动和更改分成两个提交。
答案 2 :(得分:3)
通过重写历史记录在编辑文件之前移动文件来实现@Nevik Rehnel建议的两个提交的命令:
开始条件:
git log --follow newpath
将文件显示为最近提交中新创建的文件步骤:
git tag working_code
git rebase -i HEAD~2
git mv oldpath newpath
mkdir
git add .
并检查git status
现在是否显示:renamed: oldpath -> newpath
git commit -m "Rename oldpath newpath"
git rebase --continue
git checkout working_code newpath
git rebase --continue
git log --follow newpath
是否显示完整历史记录