列表提交不涉及特定路径

FFD*_*FFD 5 git

我需要列出触及源树中的一个路径而不是另一个路径的提交。

D-头

C - 触摸foobar

B - 触碰foo

A - 基线

在 A 和 DI 之间想要一个所有涉及文件夹foo 的 提交列表,除非他们也接触文件夹bar,换句话说,在上面的例子中,我希望看到 B 而不是 C。

我试过了,git rev-list A..D --exclude='bar' -- foo但这仍然给了我 B 和 C。

请指教。

tor*_*rek 2

Git 中没有内置任何东西来执行此操作。然而,使用命令可以comm很容易地通过一个小的 shell 脚本来构建。只需获取影响感兴趣文件的所有提交的列表,以及影响使提交变得无趣的文件的所有提交的第二个列表,然后用于comm提取感兴趣的项目(那些出现在第一个列表中,但不在第一个列表中的项目)和第二个列表)。

因此:

git rev-list A..D -- foo > /tmp/list1
git rev-list A..D -- bar > /tmp/list2
comm -23 /tmp/list[12]
Run Code Online (Sandbox Code Playgroud)

请注意,“排序”要求comm是故意违反的(并且在这里被违反);如果您comm坚持这样做,您可能需要编写自己的变体。


编辑:我在 Git 2.8.1 中测试了 VonC 的建议,方法是创建一个新的存储库,并使用文件 A/a 和 B/b 进行初始提交:

$ git --version
git version 2.8.1
$ git log --oneline --name-status
731a059 both
M       A/a
M       B/b
6894130 B only
M       B/b
b4bb2d8 A only
M       A/a
f134515 initial
A       A/a
A       B/b
Run Code Online (Sandbox Code Playgroud)

-- A正确添加会丢弃B only提交:

$ git log --oneline --name-status -- A
731a059 both
M       A/a
b4bb2d8 A only
M       A/a
f134515 initial
A       A/a
Run Code Online (Sandbox Code Playgroud)

但是,添加:(exclude):B对所选提交没有影响:

$ git log --oneline --name-status -- A ':(exclude):B'
731a059 both
M       A/a
b4bb2d8 A only
M       A/a
f134515 initial
A       A/a
Run Code Online (Sandbox Code Playgroud)

731a059涉及文件 A/a 和 B/b 的Commit仍然出现在输出中,初始提交也是如此f134515。不同之处在于,当选择也影响 B/b 的两个提交时,文件B /b 被省略。最初的问题要求排除整个提交。


编辑2(使用commbash的<(...)语法,省略临时文件):

[~/tmp/git-exclude]$ comm -23 <(git rev-list HEAD -- A) <(git rev-list HEAD -- B)
b4bb2d84d633e2254081b7ce99681d92b7974a9d
Run Code Online (Sandbox Code Playgroud)

这是所需的输出,因为只有提交b4bb2影响目录。A