[英]Use git rev-list to exclude a branch, but keep common ancestors with the included branches
Say I have the following git repo: 说我有以下git repo:
I want to specify a git rev-list of all branches ( --all
) but excluding a given branch (say, feature-D
), but I want to show common ancestors of feature-D
and the other branches ie commit Initial
and 1
. 我想指定所有分支(
--all
)的git rev-list但是不包括给定的分支(比如feature-D
),但是我想显示 feature-D
和其他分支的共同祖先,即提交Initial
和1
。
If I try git rev-list --all ^feature-D
commits Initial
and 1
are excluded: 如果我尝试
git rev-list --all ^feature-D
提交Initial
和1
被排除在外:
Of course I can list all branches except for feature-D
explicitly ( git rev-list feature-A feature-B feature-C
) to get what I want: 当然,我可以明确列出除
feature-D
之外的所有分支( git rev-list feature-A feature-B feature-C
)以获得我想要的东西:
But is there a way to specify a rev-list that obtains the prior result, only by reference to feature-D
? 但有没有办法指定一个获取先前结果的转录列表,只能通过引用
feature-D
?
(Note that this question was inspired by this answer: https://stackoverflow.com/a/20978568/430128 ) (请注意,这个问题的灵感来自于这个答案: https : //stackoverflow.com/a/20978568/430128 )
This is a bit indirect but seems to work. 这有点间接,但似乎有效。 We start with:
我们从:
git rev-list --no-walk --all ^feature-D
which produces a list of all SHA-1s directly pointed to by any ref (including tags, branches, stashes, etc; use --branches
rather than --all
if you want only branches) except those under feature-D
: 它产生一个由任何ref直接指向的所有SHA-1的列表(包括标签,分支,
--branches
等;使用--branches
而不是--all
如果你只想要分支) 除了 feature-D
下的那些:
$ git log --oneline --decorate --graph --all
* 74e0d3e (feature-D) 7
* 0448a13 6
| * ab3a532 (feature-C) 5
|/
| * 50477c7 (feature-B) 4
| * 28717e5 3
|/
* 2ac5cef (HEAD, master, feature-A) 2
* c6a10b4 1
* 76c511f Initial
$ git rev-list --no-walk --all ^feature-D
ab3a5320e792e945b896634d667df5ace4a8b871
50477c7b28b5479587e45fe97292e71a3c0851c5
28717e5628ad111e8b68323dc485fd190a780446
Now we feed this to git rev-list
again to get the history-walking: 现在我们再次将它提供给
git rev-list
来获取历史记录:
$ git rev-list --no-walk --all ^feature-D | git rev-list --stdin
ab3a5320e792e945b896634d667df5ace4a8b871
50477c7b28b5479587e45fe97292e71a3c0851c5
28717e5628ad111e8b68323dc485fd190a780446
2ac5cefb971c7f5c5be33a77a6db71127982eaf5
c6a10b4568136d65b31b7e262ef7745db4962460
76c511fcf38076e0ea98db73a4923de6fc806b4a
Pipe that to git log --oneline --decorate --graph --stdin
to verify that those are the right commits, if eyeballing it is not sufficiently clear: 管道
git log --oneline --decorate --graph --stdin
验证那些是正确的提交,如果眼球不够清楚:
* ab3a532 (feature-C) 5
| * 50477c7 (feature-B) 4
| * 28717e5 3
|/
* 2ac5cef (HEAD, master, feature-A) 2
* c6a10b4 1
* 76c511f Initial
(and one side note: if using git log --oneline --decorate --graph
to view your middle version, ie, git rev-list --all ^feature-D
, you need to add --boundary
to see commit 2; gitk probably adds --boundary
to make it show up, not that I tested this). (并且一方面注意:如果使用
git log --oneline --decorate --graph
来查看你的中间版本,即git rev-list --all ^feature-D
,你需要添加--boundary
来查看commit 2 ; gitk可能会添加--boundary
以使其显示,而不是我测试了这个)。
There's a defect here: if feature-C
and feature-B
branches did not exist you would not see commits 2 through Initial. 这里有一个缺陷:如果
feature-C
和feature-B
分支不存在,你将看不到提交2到Initial。 I'm not sure, but I think the only real fix for this is to use something much more complex. 我不确定,但我认为唯一真正的解决方法是使用更复杂的东西。
Edit: ok, not that much more complex. 编辑:好的,不是那么复杂。 Start with
git for-each-ref
to print branches. 从
git for-each-ref
开始打印分支。 Pipe through grep -v ^feature-D$
to eliminate feature-D
. 管道通过
grep -v ^feature-D$
来消除feature-D
。 Now you have all the branches you want as arguments: 现在您拥有所需的所有分支作为参数:
$ git log --oneline --graph --decorate $(git for-each-ref \
> --format '%(refname:short)' refs/heads/ | grep -v '^feature-D$')
* ab3a532 (feature-C) 5
| * 50477c7 (feature-B) 4
| * 28717e5 3
|/
* 2ac5cef (master, feature-A) 2
* c6a10b4 1
* 76c511f Initial
Instead of listing all branches explicitly (either manually or with a complicated program), we can use a regex to include --all
refs and --exclude
a specific one. 我们可以使用正则表达式来包含
--all
refs和--exclude
一个特定的分支,而不是明确地列出所有分支(手动或使用复杂的程序)。
According to the man page, the --all
flag will 根据手册页, -
--all
标志将
Pretend as if all the refs in
refs/
are listed on the command line as<commit>
.假装
refs/
中的所有引用都在命令行中列为<commit>
。
Ideally, we would pretend that all of the refs in refs/
except for feature-D are listed on the command line as <commit>
. 理想情况下,我们假装
refs/
除feature-D之外的所有引用都在命令行中列为<commit>
。
So to exclude feature-D
we can use --exclude=refs/heads/feature-D --all
. 因此,要排除
feature-D
我们可以使用--exclude=refs/heads/feature-D --all
。
Note: The flag order is important. 注意:标志顺序很重要。
(Probably relevant since the OP image includes a gitk screenshot.) (可能相关,因为OP图像包含gitk屏幕截图。)
I originally came across this question while trying to ignore a branch in gitk and I noticed a small gitk bug that my answer above will trigger. 我最初在尝试忽略gitk中的一个分支时遇到了这个问题,我注意到一个小的gitk错误,我上面的回答会触发。 If gitk is started with the above flags, then everything works fine.
如果使用上面的标志启动gitk,那么一切正常。 However, if after starting gitk the the view is modified from within the GUI menu, the flag ordering seems to get changed and cause the branch to reappear.
但是,如果在启动gitk之后从GUI菜单中修改了视图,则标志排序似乎会发生变化并导致分支重新出现。 (This will happen if the OK button is pressed even if no actual changes are made.) I was unable to figure out how to fix this while still using the
--all
flag, but I have a workaround. (即使没有进行实际更改,如果按下OK按钮也会发生这种情况。)我仍然无法弄清楚如何在仍然使用
--all
标志的情况下解决这个问题,但我有一个解决方法。
Instead of using --all
, we can use --branches=* --tags=* --remotes=* stash
. 而不是使用
--all
,我们可以使用--branches=* --tags=* --remotes=* stash
。
So to exclude feature-D
, we can modify this to say --exclude=refs/heads/feature-D --branches=* --tags=* --remotes=* stash
. 因此,要排除
feature-D
,我们可以将其修改为--exclude=refs/heads/feature-D --branches=* --tags=* --remotes=* stash
。
We can then start gitk using gitk --exclude=refs/heads/feature-D --branches=* --tags=* --remotes=* stash
and editing the view through the GUI no longer causes this bug. 然后我们可以使用
gitk --exclude=refs/heads/feature-D --branches=* --tags=* --remotes=* stash
启动gitk gitk --exclude=refs/heads/feature-D --branches=* --tags=* --remotes=* stash
并通过GUI编辑视图不再导致此错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.