我遇到此代码从存储库中的特定位置导出补丁
git log --author=jdoe oldbranch..newbranch -p -- path/to/subdirectory > myChangesInSubdirectory.patch
当然,它是通过提交而不是全部共同进行,因为它是补丁所做的。但我希望能够基本上说'#34;以下是特定文件夹中的文件,这些文件在commit a
和commit b
之间发生了变化,其中的内容发生了变化"没有对同一文件进行多次更改。
我可以从原始标记手动创建一个新的repo,然后复制到另一个分支,并以这种方式进行一次提交,但我试图找到一种单行CLI方式来输出它。
答案 0 :(得分:2)
根据您想要的精确结果,有很多方法可以做到这一点。
如果您想要两个特定的,已经存在的提交之间的差异(可能也限制在特定的文件/目录中),git diff
将会这样做:
git diff rev1 rev2
或:
git diff rev1 rev2 -- path1 path2 ... pathN
如果您希望更改的提交在特定日期范围内,排除该范围之外的更改,则会更复杂一些。例如,请考虑以下图形片段:
... - D - E - F - G - J - K ...
\ /
H - I
进一步假设提交D
上的日期是“上周三”,但提交E
上的日期是“两个月前”,因为提交E
是前向移植的(从更早出现的事情中重新定义或类似的。同时提交F
和G
是最近的,H
也是如此,但I
也是从E
提前转发的J
和K
K
也是最近的,但您最近确定D
。因此,您想要的提交为E
,但不是F
; G
和H
;和I
但不是D
。
在这种情况下,要将所有这些更改(而不是其他更改)作为单个修补程序,您需要在git diff
之前开始一个新的分支,您可以在其中挑选(或等效)那些承诺。您可以单独挑选它们,然后使用D
生成从“git checkout -b deliver D^ && git cherry-pick \
$(git rev-list --since=... --until=...) && \
git diff D^ HEAD [-- paths]
之前”到“最终结果”的补丁。在这种情况下,由于您没有获取任何合并,因此仍然有一种单行(ish)方式:
git rev-list
在这里,我们使用git cherry-pick
选择所需的提交,并将生成的SHA-1提供给deliver
,将它们添加到从commit {D^
开始创建的新分支上。 {1}}。假设一切顺利 - 不一定是一个好的假设 - 最终的git diff
比较D^
,我们的起点,HEAD
,是所有采摘后的结果。
(这可以简化,如果你简称为简化:-),在提交deliver
之后创建D
分支,因为我们计划包含它。但是,我假设--since
和--until
值是您决定首先包含哪些提交的值,所以我认为这样更清晰。)
如果你打算在这里包含merge-commit J
,这一切都会崩溃:merge commits可能是一个“邪恶的合并”(详见here和here),这些不能简单地挑选出来。因此,如果你做有一些花哨的要求需要运行git rev-list
来选择要包含的提交,请仔细检查。 (请注意,您可以使用--merges
自动查找合并。)