在 git 历史记录中移动文件

jackocnr

在我的功能分支中,我有大约 50 个提交。在第一次提交中,我创建了一个文件,该文件在后续提交中进行了大量修改。我现在意识到将该文件存储在不同的目录中会更好,所以我想回到第一次提交并在正确的位置开始创建它,以保持历史记录干净。我可以通过编辑第一个提交并移动文件来使用交互式 rebase 来做到这一点,但是随后所有涉及该文件的提交都会产生冲突,我必须手动解决这些冲突。有没有办法告诉每次提交文件已被移动,以便他们自动将更改应用到正确的位置?

周二

TL; 博士

使用git filter-branch. 您可以使用--index-filterfor speed 但这更难使用;只需 50 次提交,使用--tree-filter它会慢得多但更容易使用:

git filter-branch --tree-filter <fill this in> --tag-name-filter cat -- --all

您通常应该在原始存储库副本(克隆)上执行此操作,因为很容易弄乱过滤器分支,而从中恢复的简单方法是删除副本并重新开始。

一旦它的工作原理,删除所有refs/original/在描述名称git filter-branch文件存储库最终会去膨胀(过滤器分支的大小会暂时增加一倍)。

在 Git 中,历史是(是?)提交。要更改历史记录,您需要将旧提交(提供旧历史记录)复制到新的不同提交(提供新历史记录)。因此,您的目标是将所有 50 次提交替换为相同的新提交,只是将文件重定位到其他路径。

正如您所提到的,您可以使用交互式 rebase做到这一点,但这很痛苦:rebase 通过将每个提交到副本转换为变更集(通过将该提交与其父项进行比较,以查看更改的内容)然后应用相同的更改来工作到一些现有的提交。

有一个更重的命令,git filter-branch,其目的是在应用某种提交修饰符的同时复制提交。它有很多选择,因为它本质上很慢;但从根本上说,它包括:

  • 列出要操作的每个提交(通过哈希 ID)。在您的情况下,这只是“每次提交”。此外,创建旧哈希 ID → 新哈希 ID 的空映射。
  • 然后,从最根(最古老/最祖先)提交开始:

    1. 将提交提取到临时工作区。
    2. 应用各种过滤器。
    3. 从结果构建一个新的提交。使用哈希映射映射父 ID,以便新提交指向较早复制的新提交。这为命令提供了新提交的哈希 ID。
    4. 从旧提交哈希→新提交哈希向映射添加条目。
  • 最后,在对每个要过滤的提交执行上述操作后,循环遍历您告诉它要更改的所有引用(主要是分支名称,但如果使用 a ,则标记名称也是如此--tag-name-filter):

    1. 将原始引用从 重命名refs/whateverrefs/original/refs/whatever
    2. refs/whatever使用在地图中找到的新哈希创建一个新的。

在此过程结束时,您拥有所有原始提交(refs/original用于引用它们)以及所有新提交(使用分支名称)。

如果您只有一个分支名称(并且没有标签),那么您需要提供的唯一名称就是这个分支名称,可能是master,但--all会告诉 Git 查看所有引用,并--tag-name-filter cat告诉 Git 它应该对标签名称,因为它更新它们毕竟是不做任何改变。

--tree-filter指导git filter-branch,对于第1步(提取提交),它应该做的充分和完全的提取,到一个临时目录git filter-branch将建立在其自身。(其他过滤器选项尝试使用更快的仅提取到临时索引的技巧。)您提供的一个或多个命令tree-filter在此临时目录中运行,因此如果您需要做的只是重命名文件,命令:

mv old-relative-path new-relative-path

就足够了(假设是 Unix/Linux-ish 系统)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

git在保持历史记录的同时移动文件

来自分类Dev

在Git中还原移动文件的历史记录

来自分类Dev

将文件以及git中的历史记录移动到其他文件夹

来自分类Dev

将文件以及git中的历史记录移动到其他文件夹

来自分类Dev

git,确保历史记录的移动/重命名文件的可靠方法

来自分类Dev

使用分支的历史记录在分支之间移动单个Git文件

来自分类Dev

git 将文件夹向下移动一级并维护历史记录

来自分类Dev

在移动目录上保留Git历史记录

来自分类Dev

Git从合并和历史记录中排除文件

来自分类Dev

在git上重命名文件并保留历史记录

来自分类Dev

使用Git强制文件历史记录关联

来自分类Dev

从所有git历史记录中删除文件

来自分类Dev

从Git历史记录中删除大文件

来自分类Dev

仅提取Git文件历史记录的“年范围”

来自分类Dev

VS Code'git mv'保留文件历史记录?

来自分类Dev

Git-从分支的历史记录中删除文件

来自分类Dev

GIT重命名文件夹历史记录

来自分类Dev

根据.mailmap文件重写git历史记录

来自分类Dev

Git从合并和历史记录中排除文件

来自分类Dev

从 git 历史记录中删除文件的某些内容

来自分类Dev

缺少删除文件历史记录中的行 (git)

来自分类Dev

Git:如何下载单个文件的整个历史记录?

来自分类Dev

从 git 历史记录中永久删除文件

来自分类Dev

清除已删除文件的git历史记录,保留重命名的文件历史记录

来自分类Dev

清除已删除文件的git历史记录,保留重命名的文件历史记录

来自分类Dev

如何清除git历史记录?

来自分类Dev

添加缺少的git历史记录

来自分类Dev

移动文件/目录后,GitHub没有显示文件的历史记录,但是Git会显示-这是由于我如何移动它们?

来自分类Dev

在目录重命名或移动的回购历史记录中查找 git commit

Related 相关文章

  1. 1

    git在保持历史记录的同时移动文件

  2. 2

    在Git中还原移动文件的历史记录

  3. 3

    将文件以及git中的历史记录移动到其他文件夹

  4. 4

    将文件以及git中的历史记录移动到其他文件夹

  5. 5

    git,确保历史记录的移动/重命名文件的可靠方法

  6. 6

    使用分支的历史记录在分支之间移动单个Git文件

  7. 7

    git 将文件夹向下移动一级并维护历史记录

  8. 8

    在移动目录上保留Git历史记录

  9. 9

    Git从合并和历史记录中排除文件

  10. 10

    在git上重命名文件并保留历史记录

  11. 11

    使用Git强制文件历史记录关联

  12. 12

    从所有git历史记录中删除文件

  13. 13

    从Git历史记录中删除大文件

  14. 14

    仅提取Git文件历史记录的“年范围”

  15. 15

    VS Code'git mv'保留文件历史记录?

  16. 16

    Git-从分支的历史记录中删除文件

  17. 17

    GIT重命名文件夹历史记录

  18. 18

    根据.mailmap文件重写git历史记录

  19. 19

    Git从合并和历史记录中排除文件

  20. 20

    从 git 历史记录中删除文件的某些内容

  21. 21

    缺少删除文件历史记录中的行 (git)

  22. 22

    Git:如何下载单个文件的整个历史记录?

  23. 23

    从 git 历史记录中永久删除文件

  24. 24

    清除已删除文件的git历史记录,保留重命名的文件历史记录

  25. 25

    清除已删除文件的git历史记录,保留重命名的文件历史记录

  26. 26

    如何清除git历史记录?

  27. 27

    添加缺少的git历史记录

  28. 28

    移动文件/目录后,GitHub没有显示文件的历史记录,但是Git会显示-这是由于我如何移动它们?

  29. 29

    在目录重命名或移动的回购历史记录中查找 git commit

热门标签

归档