我手动移动了一个文件,然后修改了它。根据Git,它是一个新文件和一个已删除的文件。有什么方法可以强制Git将其视为文件移动吗?


当前回答

git diff -M或git log -M会自动检测这些更改,如重命名和微小的更改,只要它们确实是。 如果你的小变化不是小的,你可以降低相似度阈值,例如。

$ git log -M20 -p --stat

将其从默认的50%降低到20%。

其他回答

在不同的提交中执行移动和修改操作。

如果你的修改不是很严重,Git会自动检测移动/重命名。只需git添加新文件,git rm旧文件。Git状态将显示它是否检测到重命名。

此外,对于目录的移动,你可能需要:

CD到目录结构的顶部。 执行git add -A命令。 运行git status来验证“新文件”现在是一个“重命名”文件

如果git状态仍然显示“新文件”而不是“重命名”,你需要遵循Hank Gay的建议,在两次单独的提交中进行移动和修改。

对我来说,在提交之前保存所有更改并再次弹出它们是有效的。这使得git重新分析添加/删除的文件,并正确地将它们标记为已移动。

可能有一个更好的“命令行”方法来实现这一点,我知道这是一种hack,但我从来没有找到一个好的解决方案。

使用TortoiseGIT:如果你有一个GIT提交,其中一些文件移动操作显示为加载添加/删除,而不是重命名,即使文件只有很小的变化,那么这样做:

检查你在当地做了什么 在第二次提交中检入一个小的单行更改 去GIT登录乌龟GIT 选择两个提交,右键单击,选择“merge into one commit”

新的提交现在将正确地显示文件重命名……这将有助于维护正确的文件历史。

其他的答案已经涵盖了,你可以简单地git添加新&& git rm OLD,以使git识别移动。

然而,如果你已经在工作目录中修改了文件,add+rm方法将把修改添加到索引中,这在某些情况下可能是不希望的(例如,在大量修改的情况下,Git可能不再识别它是一个文件重命名)。

让我们假设您想要将重命名添加到索引,而不是任何修改。显而易见的方法来实现这一点,是做一个来回重命名mv NEW OLD && git mv OLD NEW。

但是也有一种(稍微复杂一点的)方法可以直接在索引中做这件事,而不需要在工作树中重命名文件:

info=$(git ls-files -s -- "OLD" | cut -d' ' -f-2 | tr ' ' ,)
git update-index --add --cacheinfo "$info,NEW" &&
  git rm --cached "$old"

这也可以放在~/.gitconfig中作为别名:

[alias]
    mv-index = "!f() { \
      old=\"$1\"; \
      new=\"$2\"; \
      info=$(git ls-files -s -- \"$old\" | cut -d' ' -f-2 | tr ' ' ,); \
      git update-index --add --cacheinfo \"$info,$new\" && \
      git rm --cached \"$old\"; \
    }; f"