Display all first-level descendant branches using Git

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:

  • Rolling back or re-creating the master branch in git?
  • How to correctly close a feature branch in Mercurial?
  • Can two branches point to the same commit?
  • Locally find all unmerged branches of origin
  • How use git? Advices for a custom use. (Save screenshot of source code)
  • How to get commit where merged branch forked from
  • 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?

  • Git post-receive hook for `Everything up-to-date`
  • .gitignore for PhoneGap/Cordova 3.0 projects - what should I commit?
  • Git, and moving between development machines
  • Importing commit history from Bitbucket to Github
  • git fatal: when trying git rm --cached
  • When I run 'bundle update' and I have git references, where are those git repositories saved?
  • One Solution collect form web for “Display all first-level descendant branches using Git”

    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 Baby is a git and github fan, let's start git clone.