列表提交不触及特定路径 [英] List commits not touching specific paths

查看:57
本文介绍了列表提交不触及特定路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



头部

我需要列出在源代码树中碰到一个路径的提交。

C触摸 foo bar

触摸 foo / p>

A - 基线

在A和DI之间需要一个所有提交文件的列表 foo < b $ b

我尝试了 git rev-list A..​​D --exclude ='bar' - foo 但这给了我B和C两者。 / p>

请指教。

解决方案

这个。但是,使用 comm 命令。只需获取影响感兴趣文件的所有提交列表,以及影响提交不感兴趣的文件的所有提交列表,然后使用 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版本2.8.1
$ git log --oneline --name-status
731a059 both
MA / a
MB / b
6894130 B仅
MB / b
b4bb2d8 A仅
MA / a
f134515初始
AA / a
AB / b

添加 - A 正确地丢弃 B commit:

  $ git log --oneline --name-status  -  A 
731a059均为
MA / a
b4bb2d8 A仅
MA / a
f134515初始
AA / a

但是,加入 :(排除):B 对所选提交没有任何影响:

  $ git log --oneline --name-status -  A':(不包括):B'
731a059均为
MA / a
b4bb2d8 A仅
MA / a
f134515初始
AA / a

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




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

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

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


I need to list commits that touch one path in the source tree but not another.

D - head

C - touched foo and bar

B - touched foo

A - baseline

Between A and D I want a list of all commits touching folder foo unless they also touch folder bar, in other words, in the example above I would expect to see B but not C.

I tried git rev-list A..D --exclude='bar' -- foo but that gives me both B and C still.

Please advise.

解决方案

There is nothing built into Git to do this. However, it's easy to construct with a small shell script using the comm command. Simply get a list of all commits that affect interesting files, and a second list of all commits that affect files that make the commit uninteresting, then use comm to extract the interesting items (those that appear in the first list, but not in both the first and second list).

Hence:

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

Note that the "sorted" requirement for comm is deliberately violate-able (and is violated here); if your particular comm insists on it, you may need to write your own variation.


Edit: I tested VonC's suggestion, in Git 2.8.1, by making a new repository with an initial commit with files A/a and 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

Adding -- A correctly discards the B only commit:

$ git log --oneline --name-status -- A
731a059 both
M       A/a
b4bb2d8 A only
M       A/a
f134515 initial
A       A/a

However, adding :(exclude):B has no effect on the selected commits:

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

Commit 731a059, which touches files A/a and B/b, still appears in the output, as does initial commit f134515. The difference is that when the two commits that also affect B/b are selected, the file B/b is omitted. The original question calls for the entire commit to be excluded.


Edit 2 (using comm and bash's <(...) syntax, to omit the temp files):

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

This is the desired output, since only commit b4bb2 affects only the A directory.

这篇关于列表提交不触及特定路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆