使用Git显示所有第一级后代分支 [英] Display all first-level descendant branches using Git

查看:106
本文介绍了使用Git显示所有第一级后代分支的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获得当前HEAD的第一级后代的分支列表?



我可以通过以下方式获取整棵树的列表:

p>

  git log --graph --abbrev-commit --pretty = decorate --branches 

给出的是

  * 2eff4a7 ... (refs / heads / issue-8351)增加了工厂工厂。 
* 2e387aa ...重构所有工厂工厂。
| * b3fad52 ...(refs / heads / issue-8354)将baz移出构造函数。
| /
| * f4cf3fe ...(参考/头/实验)quuz看起来不错
| * 1d276b9 ...危险的修复以quuz替换quux。
| * d6b0222 ...(refs / heads / issue-7559)修复了foo中的quux。
| /
| * 3f4cfff ...(refs / heads / dev)wip
| /
* 76f493f ...(refs / heads / master)SVN 30192

但我只想获得当前分支的第一级孩子的简单列表,如 master

  dev 
发行-7559
发行-8354
issue-8351

如果我在分支 issue-7559 我只会看到:

 实验性

我该怎么办?

解决方案

您可以做到这一点如下。

首先是通常的序言:

 #! / usr / bin / perl 

使用警告;
使用strict;

使用 git for-each-ref 来收集SHA- 1和名字为每个ref:

  sub refs {
打开我的$ fh, - |,git ,for-each-ref,
--format =%(objectname)\t%(refname:short)
或死$ 0:无法运行git for-each- REF;

my%ref2sha;
while(< $ fh>){
chomp;
my($ sha,$ ref)= split / \t /;
$ ref2sha {$ ref} = $ sha;
}

\%ref2sha;



$ b $ p
$ b

如果一个提交是 HEAD ,从 HEAD 可达到的提交集合中排除了所提交的所有内容都是空集合。我们可以通过 git rev-list

  sub is_child {
my ($ ref)= @_;

#git rev-list ^ dev master
my $ refs =`git rev-list ^ $ ref HEAD - 2>& 1`;
die$ 0:git rev-list-failed.\\\
$ refsif $ ?;

$ refs!〜/ \S /;

$ / code>

对于每个属于 HEAD 但它不等于 HEAD ,我们检查从 HEAD 到该引用的路径, a href =http://git-scm.com/docs/git-log =nofollow noreferrer> git log 。如果路径包含另一个分支的提示,那么裁判不能是第一级的孩子。



这个手套的所有幸存者都是一级孩子。

  chomp(my $ head =`git rev-parse HEAD 2>& 1`); 
die$ 0:git rev-parse failed.\\\
$ headif $ ?;

my $ ref2sha = refs;
my%headsha = reverse%$ ref2sha;

REF:
foreach my $ ref(keys%$ ref2sha){
my $ refsha = $ ref2sha-> {$ ref};

next,如果$ refsha eq $ head || !is_child $ ref;

my @log =`git log --pretty = format:%H .. $ ref 2>& 1`;
死$ 0:git log failed.\\\
@logif $ ?; (@log){
chomp;
;
next,如果$ _ eq $ refsha;
next如果存在$ headsha {$ _};
}

print $ ref,\\\
;
}


How can I get a list of branches that are first-level descendants of the current HEAD?

I can get a list of the whole tree with:

git log --graph --abbrev-commit --pretty=decorate --branches

which gives

* 2eff4a7... (refs/heads/issue-8351) Added a factory factory factory.
* 2e387aa... Refactored all of the factory factories.
| * b3fad52... (refs/heads/issue-8354) Moved the baz out of the constructor.
|/
| * f4cf3fe... (refs/heads/experimental) quuz looking good
| * 1d276b9... Risky fix to replace the quux with the quuz.
| * d6b0222... (refs/heads/issue-7559) Fixed the quux in the foo.
|/
| * 3f4cfff... (refs/heads/dev) wip
|/
* 76f493f... (refs/heads/master) SVN 30192

but I'd like to just get a plain list of the first-level children of the current branch, like this example for master:

dev
issue-7559
issue-8354
issue-8351

and if I was on branch issue-7559 I'd only see:

experimental

How might I go about this?

解决方案

You could do it as follows.

First the usual preamble:

#! /usr/bin/perl

use warnings;
use strict;

Use git for-each-ref to gather the SHA-1 and name for each ref:

sub refs {
  open my $fh, "-|", "git", "for-each-ref",
                            "--format=%(objectname)\t%(refname:short)"
    or die "$0: failed to run git for-each-ref";

  my %ref2sha;
  while (<$fh>) {
    chomp;
    my($sha,$ref) = split /\t/;
    $ref2sha{$ref} = $sha;
  }

  \%ref2sha;
}

If a commit is a child of HEAD, the set of commits reachable from HEAD excluding everything reachable from the commit in question is the empty set. We can check this relationship with git rev-list.

sub is_child {
  my($ref) = @_;

  # git rev-list ^dev master
  my $refs = `git rev-list ^$ref HEAD -- 2>&1`;
  die "$0: git rev-list-failed.\n$refs" if $?;

  $refs !~ /\S/;
}

For each ref that is a descendant of HEAD but it not equivalent to HEAD, we examine the path from HEAD to that reference using git log. If the path contains the tip of another branch, the ref cannot be a first-level child.

All survivors of this gauntlet are first-level children.

chomp(my $head = `git rev-parse HEAD 2>&1`);
die "$0: git rev-parse failed.\n$head" if $?;

my $ref2sha = refs;
my %headsha = reverse %$ref2sha;

REF:
foreach my $ref (keys %$ref2sha) {
  my $refsha = $ref2sha->{$ref};

  next if $refsha eq $head || !is_child $ref;

  my @log = `git log --pretty=format:%H ..$ref 2>&1`;
  die "$0: git log failed.\n@log" if $?;
  for (@log) {
    chomp;
    next if $_ eq $refsha;
    next REF if exists $headsha{$_};
  }

  print $ref, "\n";
}

这篇关于使用Git显示所有第一级后代分支的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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