在 2 git 次提交之间按文件 diff/patch 导出压缩文件?
Export a condensed file by file diff/patch between 2 git commits?
我发现这段代码可以从存储库中的特定位置导出补丁
git log --author=jdoe oldbranch..newbranch -p -- path/to/subdirectory > myChangesInSubdirectory.patch
当然,它是通过提交而不是全部揉在一起进行的,因为这就是补丁的作用。但我希望能够基本上说 "Here are the files in a particular folder that changed between commit a
and commit b
and what changed in them" 而无需对同一文件进行多次更改。
我可以从原始标签中手动创建一个新的 repo,然后复制到另一个分支并以这种方式进行一次提交,但我正在尝试找到一种单行 CLI 方式来输出它。
有很多方法可以做到这一点,具体取决于您想要的精确结果。
如果您想要区分两个特定的、已经存在的提交(可能也仅限于特定的文件/目录),git diff
会做到:
git diff rev1 rev2
或:
git diff rev1 rev2 -- path1 path2 ... pathN
如果您想要提交在特定日期范围内的更改,排除该范围之外的更改,则有点复杂。例如,考虑以下图形片段:
... - D - E - F - G - J - K ...
\ /
H - I
进一步假设提交 D
的日期是 "last Wednesday",但是提交 E
的日期是 "two months ago",因为提交 E
是向前的-从更早完成的事情移植(重新定位或类似)。同时提交 F
和 G
是最近的,H
也是如此,但是 I
也像 E
和 J
和 K
也是最近的,但您认为 K
也是 最近的。因此,您想要的提交是 D
而不是 E
; F
和 G
;和 H
但不是 I
.
在这种情况下,要将所有这些更改(而不是其他更改)作为一个补丁,您需要在 D
之前创建一个新分支,您可以在其中挑选(或等效)每一个承诺。您可以单独挑选它们,然后使用 git diff
生成从 "just before D
" 到 "final result" 的补丁。在这种情况下,仍然有一种单行(ish)方法可以做到这一点,因为您没有进行任何合并:
git checkout -b deliver D^ && git cherry-pick \
$(git rev-list --since=... --until=...) && \
git diff D^ HEAD [-- paths]
在这里,我们使用 git rev-list
选择所需的提交并将生成的 SHA-1 提供给 git cherry-pick
,后者将它们添加到从以下位置创建的新分支 (deliver
)提交 D^
。假设一切顺利——不一定是一个好的假设——最终的 git diff
将我们的起点 D^
与所有挑选之后的结果 HEAD
进行比较。
(这可以简化,如果你至少称之为简化 :-),通过创建 deliver
分支 after commit D
因为我们计划包括它。但是,我假设 --since
和 --until
值是您决定首先包含哪些提交的方式,所以我认为这样更清楚一些。)
如果您打算在此处包含合并提交 J
,这一切都会崩溃:合并提交可以是 "evil merge"(有关详细信息,请参阅 here and here),而这些不能是简单地挑选。因此,如果您 有一些奇特的要求,需要 运行 git rev-list
选择要包含的提交,请仔细检查。 (请注意,您可以使用 --merges
自动查找合并。)
我发现这段代码可以从存储库中的特定位置导出补丁
git log --author=jdoe oldbranch..newbranch -p -- path/to/subdirectory > myChangesInSubdirectory.patch
当然,它是通过提交而不是全部揉在一起进行的,因为这就是补丁的作用。但我希望能够基本上说 "Here are the files in a particular folder that changed between commit a
and commit b
and what changed in them" 而无需对同一文件进行多次更改。
我可以从原始标签中手动创建一个新的 repo,然后复制到另一个分支并以这种方式进行一次提交,但我正在尝试找到一种单行 CLI 方式来输出它。
有很多方法可以做到这一点,具体取决于您想要的精确结果。
如果您想要区分两个特定的、已经存在的提交(可能也仅限于特定的文件/目录),git diff
会做到:
git diff rev1 rev2
或:
git diff rev1 rev2 -- path1 path2 ... pathN
如果您想要提交在特定日期范围内的更改,排除该范围之外的更改,则有点复杂。例如,考虑以下图形片段:
... - D - E - F - G - J - K ...
\ /
H - I
进一步假设提交 D
的日期是 "last Wednesday",但是提交 E
的日期是 "two months ago",因为提交 E
是向前的-从更早完成的事情移植(重新定位或类似)。同时提交 F
和 G
是最近的,H
也是如此,但是 I
也像 E
和 J
和 K
也是最近的,但您认为 K
也是 最近的。因此,您想要的提交是 D
而不是 E
; F
和 G
;和 H
但不是 I
.
在这种情况下,要将所有这些更改(而不是其他更改)作为一个补丁,您需要在 D
之前创建一个新分支,您可以在其中挑选(或等效)每一个承诺。您可以单独挑选它们,然后使用 git diff
生成从 "just before D
" 到 "final result" 的补丁。在这种情况下,仍然有一种单行(ish)方法可以做到这一点,因为您没有进行任何合并:
git checkout -b deliver D^ && git cherry-pick \
$(git rev-list --since=... --until=...) && \
git diff D^ HEAD [-- paths]
在这里,我们使用 git rev-list
选择所需的提交并将生成的 SHA-1 提供给 git cherry-pick
,后者将它们添加到从以下位置创建的新分支 (deliver
)提交 D^
。假设一切顺利——不一定是一个好的假设——最终的 git diff
将我们的起点 D^
与所有挑选之后的结果 HEAD
进行比较。
(这可以简化,如果你至少称之为简化 :-),通过创建 deliver
分支 after commit D
因为我们计划包括它。但是,我假设 --since
和 --until
值是您决定首先包含哪些提交的方式,所以我认为这样更清楚一些。)
如果您打算在此处包含合并提交 J
,这一切都会崩溃:合并提交可以是 "evil merge"(有关详细信息,请参阅 here and here),而这些不能是简单地挑选。因此,如果您 有一些奇特的要求,需要 运行 git rev-list
选择要包含的提交,请仔细检查。 (请注意,您可以使用 --merges
自动查找合并。)