列表提交不涉及特定路径

时间:2016-08-13 08:32:15

标签: git

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

D - 头

C - 触及 foo bar

B - 触及 foo

A - 基线

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

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

请告知。

2 个答案:

答案 0 :(得分:2)

Git 1.9以及介绍路径规范魔术:(exclude)及其简短形式:!以来,语法应为:

 git rev-list A..D -- foo ":(exclude)bar"

但是,这仍然会列出C,即使为该提交显示的文件不包含其路径中包含bar的文件:

 git log --oneline --name-status A..D -- foo ":(exclude)bar"

pathspec排除有效,但仍会列出C

答案 1 :(得分:1)

Git没有内置任何功能。但是,使用the comm command使用小型shell脚本构建起来很容易。只需获取影响有趣文件的所有提交的列表,以及影响使提交无趣的文件的所有提交的第二个列表,然后使用comm提取有趣的项目(出现在第一个列表中的那些项目,但是不在第一和第二列表中。)

因此:

git rev-list A..D -- foo > /tmp/list1
git rev-list A..D -- bar > /tmp/list2
comm -23 /tmp/list[12]

请注意"已排序" 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

正确添加-- 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

但是,添加:(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

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

编辑2(使用comm和bash&#39; <(...)语法,省略临时文件:

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

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