git Git无法识别重命名和修改的包文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14527257/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git doesn't recognize renamed and modified package file
提问by Sotirios Delimanolis
I had a java file called package/old/myfile.java
. I had committed this file through git. I then renamed my package to new
so my file was in package/new/myfile.java
.
我有一个名为package/old/myfile.java
. 我已经通过 git 提交了这个文件。然后我将我的包重命名为new
这样我的文件在package/new/myfile.java
.
I now want to commit this file rename (and content changes) to git.
我现在想将此文件重命名(和内容更改)提交给 git。
When I do git status
I get
当我这样做时,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
I've tried add
ing the new and rm
ing the old and vice versa, I keep getting
我试过add
新的和rm
旧的,反之亦然,我不断得到
$ git status
# On branch develop
# Changes to be committed:
# delete: package/old/myfile.java
# new file: package/new/myfile.java
I can't do mv old new
because the old file doesn't exist and so I get bad source
error.
我不能这样做,mv old new
因为旧文件不存在,所以bad source
出现错误。
Is there anything else I can try?
还有什么我可以尝试的吗?
I've tried some of the multiple answers on SO for similar problem, but they haven't worked.
对于类似的问题,我已经尝试了一些关于 SO 的多个答案,但它们没有奏效。
回答by asm
The relevant sectionfrom the git bookexplains this.
Unlike many other VCS systems, Git doesn't explicitly track file movement. If you rename a file in Git, no metadata is stored in Git that tells it you renamed the file. However, Git is pretty smart about figuring that out after the fact — we'll deal with detecting file movement a bit later.
与许多其他 VCS 系统不同,Git 没有明确跟踪文件移动。如果您在 Git 中重命名文件,则 Git 中不会存储任何元数据来告诉它您重命名了文件。然而,Git 在事后解决这个问题方面非常聪明——我们稍后会处理检测文件移动的问题。
What this means is that if you move a file and then make significant changes git will not know that it was a move. It will see a file deleted and a new file created because the new file doesn't look like the old one. To get around this people often git mv
files, commit the move, and then make changes. In your situation you can do
这意味着如果您移动文件然后进行重大更改,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
回答by Nevik Rehnel
Move the file back, then commit it, and put the actual move into a separate commit. Git does not record moves (or renames) as such, but can recognize them afterward based on content. If the content changes, it can't detect the move properly. Therefore it's common practice to split moves and changes into two commits.
将文件移回,然后提交,并将实际移动放入单独的提交中。Git 不会像这样记录移动(或重命名),但可以在之后根据内容识别它们。如果内容发生变化,则无法正确检测移动。因此,通常的做法是将移动和更改分成两个提交。
回答by Stan Kurdziel
Commands to implement @Nevik Rehnel's suggestion of two commits by rewriting history to move the file before it's edited:
通过重写历史记录来实现@Nevik Rehnel 的两次提交建议的命令,以便在编辑之前移动文件:
Starting condition:
启动条件:
- your most recent commit includes both a move and modification to a file and
git log --follow newpath
shows the file as newly created in the most recent commit
- 您最近的提交包括对文件的移动和修改,并将文件
git log --follow newpath
显示为在最近的提交中新创建的
Steps:
脚步:
- Tag your current status
git tag working_code
- Start an interactive rebase to edit the history:
git rebase -i HEAD~2
- in the editor that pops up, change "pick" on the first line to "edit", save and exit.
- Your are now editing history just before your commit
- Create the move as its own commit
git mv oldpath newpath
- The directory to contain the new file location has to exist; you may have to
mkdir
it first - (optionally) Edit the file with any small changes needed to accompany the file rename (ex: in Java: class name and/or package and import lines) - Avoid making other changesGit detects these as the same file based on similarity
git add .
and check thatgit status
now shows:renamed: oldpath -> newpath
git commit -m "Rename oldpath newpath"
git rebase --continue
- You should get a conflict on newpath. Restore the file with
git checkout working_code newpath
- Complete the rebase:
git rebase --continue
- You should get a conflict on newpath. Restore the file with
- Verify that
git log --follow newpath
shows the full history
- 标记您的当前状态
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
- 你应该在 newpath 上遇到冲突。恢复文件
- 验证是否
git log --follow newpath
显示完整历史记录