update 0.3.0 with decorated merged/local info

This commit is contained in:
David O'Trakoun 2015-03-31 23:53:42 -04:00
parent ec1f02f166
commit 88e88ba88a
2 changed files with 179 additions and 49 deletions

View file

@ -1,13 +1,18 @@
# git-my v0.1
# git-my v0.3.0
> Lists (stale) (branches|tags) in the remote named (origin) (where you were
> the last committer)
> Lists a user's remote branches and shows if it was merged and/or available
> locally
[Homepage](https://github.com/davidosomething/git-my)
## About
Unlike `git branch -r` this shows only YOUR branches.
Unlike `git branch -r` and `git remote show origin` this shows only branches
where YOU were the last committer and it will tell you if you have a copy of
that branch locally.
Here's a screenshot:
![Example output](https://raw.githubusercontent.com/davidosomething/git-my/docs/git-my/screenshot.png)
## Installation
@ -16,19 +21,27 @@ Unlike `git branch -r` this shows only YOUR branches.
## Usage
From command line execute:
```
git my
```
## TODO
- Add options:
## To do
- Colorize output
- Options support
```
-U|--username="gitconfig user.name"
-R|--remote=origin
-T|--tags
-B|--branches
-F|--filter=mine,stale
-v|--version
-h|--help
-d|--decorate LOCAL,MERGED
-r|--remote-ref origin/master
-U|--username
--no-color
--no-header
--no-decorate
```
Copyright (c) 2015 David O'Trakoun
Copyright (c) 2015 David O'Trakoun <me@davidosomething.com>

191
git-my
View file

@ -1,72 +1,189 @@
#!/usr/bin/env bash
# git-my v0.1
# git-my v0.3.0
#
# Lists (stale) (branches|tags) in the remote named (origin) (where you were
# the last committer)
# Lists a user's remote branches and shows if it was merged
# and/or available locally
#
# Copyright (c) 2015 David O'Trakoun <me@davidosomething.com>
#
# Usage:
# git my
#
# Options:
# @todo NOT IMPLEMENTED
# -U|--username="gitconfig user.name"
# -R|--remote=origin
# -T|--tags
# -B|--branches
# -F|--filter=mine,stale
#
set -eu
# _check_in_repository
#
# Exits with error if not a git repository
#
_check_in_repository() {
git rev-parse --git-dir > /dev/null 2>&1
}
_filter_mine() {
local git_user
git_user=$(git config --get user.name)
# _get_local_branches
#
# Proper way to get a porcelain list of local branches for shell script use
#
_get_local_branches() {
local fmt
local cmd_get_local_branches
# use eval to not parse the fmt string
local my_remotes
my_remotes=$(echo "$1" | grep -i "^$git_user")
echo "$my_remotes" | awk -F'\t' '{ print $2 }'
# shellcheck disable=SC2016
fmt='
r=%(refname)
refname_without_prefix=${r#refs/heads/}
printf "%s\t%s\n" "$refname_without_prefix"
'
cmd_get_local_branches=$(
git for-each-ref --shell --format="$fmt" refs/heads
)
eval "$cmd_get_local_branches"
}
# @TODO
_filter_stales() {
local raw_stales
raw_stales=$(git remote prune --dry-run origin)
echo "$raw_stales"
}
_main() {
if ! _check_in_repository ; then
echo "This is not a git repository."
exit 1
fi
# _get_everyones_remotes
#
# Get porcelain list of all remote branches
#
# @TODO support remote_name (currently origin)
#
_get_everyones_remotes() {
local fmt
local cmd_everyones_remotes
# user.name<TAB>branch.name
# the TAB is used as a delimiter to awk with
# shellcheck disable=SC2016
local fmt='
fmt='
a=%(authorname)
r=%(refname)
b=${r#refs/remotes/origin/}
printf "%s\t%s\n" "$a" "$b"
refname_without_prefix=${r#refs/remotes/origin/}
printf "%s\t%s\n" "$a" "$refname_without_prefix"
'
local cmd_everyones_remotes
cmd_everyones_remotes=$(
git for-each-ref --shell --format="$fmt" refs/remotes/origin
)
local everyones_remotes
everyones_remotes=$(eval "$cmd_everyones_remotes")
_filter_mine "$everyones_remotes"
eval "$cmd_everyones_remotes"
}
# _get_merged_remote_branches
#
# @TODO support param remote_branche (currently origin/master)
#
# @output names of remote branches that are merged into origin/master
_get_merged_remote_branches() {
local remote_name
local remote_refname
local merged_remote_branches
local stripped_branchnames
remote_name="origin"
remote_refname="master"
merged_remote_branches=$( \
git branch --no-color \
--remotes \
--merged $remote_name/$remote_refname \
)
# remove "origin/"
# shellcheck disable=SC2001
stripped_branchnames=$( \
echo "$merged_remote_branches" | sed "s/^\s*$remote_name\///g" \
)
echo "$stripped_branchnames"
}
# _filter_mine
#
# @param git_user
# @param branchnames
# @output branchnames owned by current git user
_filter_mine() {
local git_user
local branchnames
git_user=$1
branchnames=$2
# use eval to not parse the fmt string
local my_remotes
my_remotes=$(echo "$branchnames" | grep -i "^$git_user")
# output only the branchname
echo "$my_remotes" | awk -F'\t' '{ print $2 }'
}
# _decorate_merged
#
# @TODO support param branch to check against
#
# @param branchnames to check if merged into against
# @output branchnames with [merged]
_decorate_merged() {
local merged_remote_branches
local decorated
merged_remote_branches=$(_get_merged_remote_branches)
local_branches=$(_get_local_branches)
# heading
decorated=$( printf '%12s %12s %s' \
"local copy?" "in master? " "branch name"
)
decorated+=$'\n'
# body
for branchname in $1
do
local local_text="..........."
local merged_text='............'
echo "$local_branches" | grep -q "$branchname" && \
local_text="..[local].."
echo "$merged_remote_branches" | grep -q "$branchname" && \
merged_text="..[merged].."
decorated+=$(printf "%12s.%12s %s" \
"$local_text" "$merged_text" "$branchname"
)
decorated+=$'\n'
done
echo "$decorated"
}
_main() {
local everyones_remotes
local my_remotes
local output
local git_user
local git_remote
local heading
git_user=$(git config --get user.name)
git_remote=$(git config --get remote.origin.url)
heading="$git_user's remote branches in $git_remote"
everyones_remotes=$(_get_everyones_remotes)
my_remotes=$(_filter_mine "$git_user" "$everyones_remotes")
output=$(_decorate_merged "$my_remotes")
printf '+%78s+\n' | tr ' ' -
printf '| %-76s |\n' "$heading"
printf '+%78s+\n' | tr ' ' -
echo "$output"
}
if ! _check_in_repository ; then
echo "This is not a git repository."
exit 1
fi
_main