Display all first-level descendant branches using Git

后端 未结 1 1638
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-05 02:33

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 --abb         


        
1条回答
  •  臣服心动
    2021-01-05 02:58

    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";
    }
    

    0 讨论(0)
提交回复
热议问题