gpt4 book ai didi

Git:显示在两个修订版之间更改的所有文件的提交内容

转载 作者:行者123 更新时间:2023-12-05 01:23:45 27 4
gpt4 key购买 nike

给定一个提交范围 <old_sha>..<new_sha> ,我想要 committed 的内容(不是已更改文件的列表,也不是它们的差异),截至 <new_sha> , 在 <old_sha> 之间更改的所有文件中和 <new_sha> .我不能简单地从磁盘读取,因为我想忽略未提交的更改。

附加约束:

  • 我不想在这个操作中修改工作目录,所以我不能,例如,存储未暂存的更改,从磁盘读取,然后 git stash pop。
  • 必须在非常大的 repo 中具有相对的性能(它将在预推送 Hook 中执行)。

我得到的最接近的是:

  • 获取更改文件列表
  • 运行 git show head:path/to/file_a head:path/to/file_b ,它将提交的文件内容写入标准输出,但没有分隔符,因此无法以编程方式知道每个文件的结束/开始位置。

最佳答案

某些已提交文件的内容只能通过读出该文件(Git 术语中的“blob 对象”)获得。因此,给定两个提交哈希 $O$N(旧的和新的,尽管任何顺序都可以)你将需要:

  1. 运行 git diff-tree -r --name-status $O $N(或任何等效的东西——见下文)并读取它的输出以确定你关心哪些文件;
  2. 提取所有这些 Blob 。

您的 git show 方法可以工作——将 HEAD:path/to/file_a 替换为 $N:path/to/file_a 除非你保证 $NHEAD 引用相同提交——但你需要一个 git show 每个文件的命令。考虑使用 read-tree 和带有临时索引的 git checkout-index:

tf=$(mktemp)
# an empty file, as made by mktemp, is unsuitable, but a nonexistent
# one is OK, so:
rm -f $tf

假设您也想要旧版本的文件(如果不需要,将其修剪为一个 $N 案例):

GIT_INDEX_FILE=$tf git read-tree $O
# you can now `git checkout-index` files using $tf as the index

如果在名为 $filelist 的文件中有一个 \0 分隔或换行分隔的文件名列表,请考虑使用 --stdin 和一个临时的(空的)工作树,例如:

td=$(mktemp -d)
GIT_WORK_TREE=$td GIT_INDEX_FILE=$tf git checkout-index --stdin < $filelist

\0 分隔的文件添加 -z 选项,以防止文件名中出现换行符;例如,如果您编写一个 Python 脚本来使用它自己的 -z 选项运行 git diff-tree,这将很有用。请记住过滤掉 $O 中不存在但存在于 $N 中的所有文件(这些文件在 中显示为 A $N,这就是我们需要 --name-status 的原因。

临时目录现在填充了来自 $O 的有趣文件。

重复第二个临时目录,用来自 $N 的有趣文件填充其中一个;请记住包含 A 添加的文件并省略 D 删除的文件。如果您在 git diff-tree 步骤中没有明确启用重命名和/或复制检测器,您将不必处理 R 和/或 C 状态文件——这是一个很大的优势——但你将无法检测重命名和/或复制的文件,这可能是一个可怕的错误。

如果您确实需要旧的和新的提交,请注意您可以像上面那样使用 read-tree 和 checkout-index 但没有对文件名的任何限制,现在您有两个完整的提交'树。所以现在您可以使用普通的 diff 或您喜欢的任何其他递归树遍历器。对于很多情况(许多文件相同),这会更慢,但可能更方便。

您现在在两个临时目录中拥有各种文件的内容,您可以在其中对它们进行任何操作。要清理,只需删除两个临时目录和临时索引。

整个过程可能不会非常快(尽管使用 SSD 存储临时文件和目录应该会有很大帮助),但它可能是您能做的最好的。

关于Git:显示在两个修订版之间更改的所有文件的提交内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71889477/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com