Git无法识别重命名和修改的包文件

时间:2013-01-25 17:33:43

标签: java git

我有一个名为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上尝试了一些多个答案,但它们没有用。

3 个答案:

答案 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
  • 启动交互式rebase以编辑历史记录:git rebase -i HEAD~2
    • 在弹出的编辑器中,将第一行的“pick”更改为“edit”,保存并退出。
  • 您现在正在提交之前编辑历史记录
  • 将移动创建为自己的提交
    • git mv oldpath newpath
    • 包含新文件位置的目录必须存在;你可能必须先mkdir
    • (可选)使用文件重命名所需的任何小改动来编辑文件(例如:在Java中:类名和/或包和导入行) - 避免进行其他更改 Git检测到这些作为基于相似性的同一文件
    • git add .并检查git status现在是否显示:renamed: oldpath -> newpath
    • git commit -m "Rename oldpath newpath"
  • git rebase --continue
    • 你应该在newpath上遇到冲突。使用git checkout working_code newpath
    • 还原文件
    • 完成变基:git rebase --continue
  • 验证git log --follow newpath是否显示完整历史记录