-
-
Save intel352/9761288 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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. |
@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
andawk
(the command(s) should work withmawk
, as well asgawk
): - 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
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:
- Parent branch's last commit is a merge, making the column show
-
not*
- Commit message contains branch name
- Commit message contains
*
Obviously you can combine this into a single line if you wish.
Doesn't latest git support showing the parent branch in a native way?
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
I just redirected git's stderr to
/dev/null
. Works like a charm!