如何提交文件重命名及其内容分别进行编辑(以便git检测到重命名)?

时间:2019-07-03 19:44:59

标签: git file-rename

澄清代码时,我重命名和编辑文件太多,以至git无法将其识别为重命名。

一个解决方案:提交旧文件的重命名;然后,提交新文件。

在所有编辑之后 之后,我该如何很好地使用git?


git stash无法识别新文件名。

目前我正在这样做:

  • 将新文件移动到其他位置 -git reset oldfile获取旧文件
  • 重命名
  • 提交

  • 现在,取回新文件,覆盖上面的

  • 确认

我已经将其描述为一个文件,但通常是在不同目录中的许多文件。我不了解您,但对我来说,很容易意外覆盖并丢失新版本……这些新版本尚未提交,因此无需reflog进行救援。

这似乎只是 git可以帮助我的事情...

EDIT 为了安全reflog,我可以将其提交到临时分支。

2 个答案:

答案 0 :(得分:2)

Git并没有提供一种非常好的方法来做到这一点,但这是可行的。假设:

  • foo是文件的旧名称,修改后的文件仍在磁盘上具有该名称
  • bar是您想要的新名称
  • 索引中未进行任何更改

然后做:

git update-index --add --cacheinfo "$(git ls-files --full-name -s foo \
    | awk '{print $1 "," $2 ",bar"}')"
git rm --cached foo
git commit -m "rename foo to bar"
mv foo bar
git add bar
git commit -m "make changes to bar"

git update-index告诉git在索引中暂存一个新文件,该文件具有与索引版本foo相同的哈希和模式,但有一个新名称bar。它不查询磁盘,只是假设存在一个带有该哈希值的对象(确实如此)。 git rm --cached告诉git在不触摸磁盘的情况下进行foo的移除。它们共同构成了一个可以提交的重命名。然后,我们将文件实际移动,使用git add通知git有关其新内容的信息,然后再次提交。当然,您也可以向此提交添加其他更改。

git update-indexmv之间的

git status将显示deleted: bar的无阶段更改,因为文件存在于索引中但不在磁盘上(位于至少还没有这个名字),但这不是问题。

请注意,即使从子目录进行操作,名称bar也必须是相对于存储库根目录的路径。为简单起见,请从存储库根目录进行操作,并对foobar使用完整路径。

这些操作实际上都不比您执行的操作简单 ,但是它确实避免了需要从工作树中还原更改。

答案 1 :(得分:1)

我想这听起来可能很简单,但是最简单的解决方案是:编辑文件时,进行一堆待处理的编辑,然后确定需要重命名文件,

(1)记录您需要重命名 (2)将文件置于可以提交所做更改的状态 (3)提交 (4)重命名 (5)提交重命名 (6)如有必要,继续编辑

也就是说-如果您不想在提交对受影响文件的更改的同时提交重命名...则不要。

在极少数情况下,可能有理由通过更改提交重命名。例如,Java中的公共类名称应与其文件名匹配。但这很好-重命名检测更改阈值始终不是100%匹配(默认情况下)。小小的变化很少会伤害任何事物。但这并不是真正的问题,因为您已经决定要进行单独的提交。

因此,问题只是未来的一点计划。现在,您要重命名一个经过重大编辑的文件(或对一个重命名的文件进行重大编辑),这是决定“哦,我要将此下一步分为与我已经完成的操作不同的提交“。

如果您真的不能做到这一点,那么藏匿实际上很好。存储您的编辑,重命名文件,提交,然后弹出存储。是的,弹出的文件将位于错误的路径,因此请重新命名(覆盖原始文件)。

顺便说一句,根据您的工作流程,这可能都是徒劳的。合并不会查看单个提交,并且会看到与您一次提交完成所有操作完全相同的情况。如果您使用基于rebase的工作流,您可能会发现它确实有帮助(尽管这会带来其他成本)。但是总的来说,我想说还有其他的方法可以减少这个问题,例如确保分支分支的寿命短,这样即使重命名检测不成功,冲突解决方案也可以保持在最低水平。