Skip to content

Instantly share code, notes, and snippets.

@intel352
Forked from joechrysler/who_is_my_mummy.sh
Last active June 26, 2021 17:06
Show Gist options
  • Save intel352/9761288 to your computer and use it in GitHub Desktop.
Save intel352/9761288 to your computer and use it in GitHub Desktop.
#!/usr/bin/env zsh
branch=`git rev-parse --abbrev-ref HEAD`
git show-branch | ack '\*' | ack -v "$branch" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'
# How it works:
# 1| Display a textual history of all commits.
# 2| Ancestors of the current commit are indicated
# by a star. Filter out everything else.
# 3| Ignore all the commits in the current branch.
# 4| The first result will be the nearest ancestor branch.
# Ignore the other results.
# 5| Branch names are displayed [in brackets]. Ignore
# everything outside the brackets, and the brackets.
# 6| Sometimes the branch name will include a ~2 or ^1 to
# indicate how many commits are between the referenced
# commit and the branch tip. We don't care. Ignore them.
@ezequielv
Copy link

@jpbochi: It's a nice idea to make commands like the cb and pb aliases. I've gone a bit further, and:

  • created a self-documenting pair of commands (the "long versions") and their convenient "short versions" equivalents;
  • reduced the number of runtime dependencies to just git and awk (the command(s) should work with mawk, as well as gawk):
  • made the git show-closest-parent-branch command return a non-zero exit code when the branch name could not be computed;
  • silently discarded invoked (sub)command(s) error output;
  • increased error checking;
  • FIXED: do not "trip" on output that contains an asterisk (such as one in the commit description): only the line section containing the one-character "tokens" is considered for the match;
[alias]
        # based on: https://gist.github.com/intel352/9761288
        show-closest-branch = rev-parse --abbrev-ref HEAD
        # based on: http://stackoverflow.com/questions/3161204/find-the-parent-branch-of-a-git-branch
        show-closest-parent-branch = !"git show-branch -a --no-color 2> /dev/null | awk -F '[]^~[]' -v current_branch=`git show-closest-branch 2> /dev/null || true` 'BEGIN { rc=1 ; if ( length( current_branch ) == 0 ) { exit } } ( ( index( $1, \"*\" ) > 0 ) && ( length( $2 ) > 0 ) && ( $2 != current_branch ) ) { print $2 ; rc=0 ; exit } END { exit rc }'"
        # short versions
        cb = !git show-closest-branch
        pb = !git show-closest-parent-branch

Sample runs:

# run from a directory with a valid git repository, with a topic branch branched off from an existing branch
$ ( cd my_repository_directory && git pb ) ; echo "rc: $?"
some_branch_name
rc: 0

# run from a non-git directory
$ ( cd /tmp && git pb ) ; echo "rc: $?"
rc: 1

@haoyangnz
Copy link

haoyangnz commented May 11, 2016

vbc=$(git rev-parse --abbrev-ref HEAD)
vbc_col=$(( $(git show-branch | grep '^[^\[]*\*' | head -1 | cut -d* -f1 | wc -c) - 1 )) 
swimming_lane_start_row=$(( $(git show-branch | grep -n "^[\-]*$" | cut -d: -f1) + 1 )) 
git show-branch | tail -n +$swimming_lane_start_row | grep -v "^[^\[]*\[$vbc" | grep "^.\{$vbc_col\}[^ ]" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'

Achieves the same ends, but uses a much safer approach that doesn't misbehave in a number of scenarios:

  1. Parent branch's last commit is a merge, making the column show -
    not *
  2. Commit message contains branch name
  3. Commit message contains *

Obviously you can combine this into a single line if you wish.

@kostaz
Copy link

kostaz commented Jan 12, 2017

Doesn't latest git support showing the parent branch in a native way?

@tirans
Copy link

tirans commented Jun 26, 2021

Doesn't latest git support showing the parent branch in a native way?

found the following to work for me (limited testing)
git branch --create-reflog | head -n 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment