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:

  • Mercurial: Granular Repositories Vs large Repositories and shared third party tools in version control
  • Branch descriptions in git
  • Why does git say I am 40 commits ahead when I seem up to date and a push-pull (no files) fixes it?
  • Remove a single merged branch from master branch
  • git branch permissions
  • What's the best practice to fork an open source project?
  • 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:


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


    How might I go about this?

  • How to fetch all remote branches?
  • Clone repository into GitHub
  • How to retrieve changesets associated with a build in TFS 2013 with Git?
  • How to view file history in Git?
  • How to pull while deployment in ansible
  • Importing an SVN Repo into an EXISTING Git repo as a branch
  • 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",
        or die "$0: failed to run git for-each-ref";
      my %ref2sha;
      while (<$fh>) {
        my($sha,$ref) = split /\t/;
        $ref2sha{$ref} = $sha;

    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;
    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) {
        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.