Compare commits

...

6 commits

Author SHA1 Message Date
David O'Trakoun c3f6e20965
MIT license 2020-04-03 02:48:10 -04:00
David O'Trakoun 56675a7f7e
update with notes 2017-08-16 14:17:56 -04:00
David O'Trakoun 402c0180fb
zplug guide 2017-03-14 00:03:17 -04:00
David O'Trakoun c46dd14ac2
shellcheck fixes 2016-08-19 12:07:05 -04:00
David O'Trakoun 23b27d75e5 up to 1.1/0 2015-12-03 20:25:45 -05:00
David O'Trakoun 9b6943e5e4 ensure everything quoted 2015-12-03 20:25:14 -05:00
3 changed files with 115 additions and 52 deletions

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License Copyright (c) 2020 davidosomething
Permission is hereby granted,
free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice
(including the next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -1,4 +1,4 @@
# git-my v1.0.0
# git-my
Lists all of a user's branches, including local and remote, and shows:
@ -6,8 +6,8 @@ Lists all of a user's branches, including local and remote, and shows:
- if a local branch is tracked remotely
- if a local branch is up-to-date with a specified branch
| Name | Link |
| ---- | ---- |
| Name | Link |
| ------------- | -------- |
| Project Home: | [https://github.com/davidosomething/git-my](https://github.com/davidosomething/git-my)
## About
@ -21,8 +21,17 @@ Here's a screenshot:
## Installation
- Requires BASH 4+
- Add the `git-my` file somewhere in your path, e.g. `/usr/local/bin/`
### zplug installation
Super simple if you use zplug:
```sh
zplug "davidosomething/git-my", as:command
```
## Usage
From command line execute:
@ -50,5 +59,5 @@ merged into `origin/qa`.
----
Copyright (c) 2015 David O'Trakoun <me@davidosomething.com>
Copyright (c) 2017 David O'Trakoun <me@davidosomething.com>

129
git-my
View file

@ -1,40 +1,40 @@
#!/usr/bin/env bash
# git-my v1.0.0
# git-my v1.1.2
#
# Lists a user's remote branches and shows if it was merged
# and/or available locally
# and/or available locally.
#
# Copyright (c) 2015 David O'Trakoun <me@davidosomething.com>
# Copyright (c) 2017 David O'Trakoun <me@davidosomething.com>
#
# Requires:
# bash 4+ for readarray
#
# Usage:
# git my
#
set -eu
# _check_in_repository
# is_repository
#
# Exits with error if not a git repository
#
_check_in_repository() {
is_repository() {
git rev-parse --git-dir >/dev/null 2>&1
}
# _get_local_branches
# get_local_branches
#
# Proper way to get a porcelain list of local branches for shell script use
#
_get_local_branches() {
get_local_branches() {
local fmt
local cmd_get_local_branches
# shellcheck disable=SC2016
fmt='
fmt="
r=%(refname)
refname_without_prefix=${r#refs/heads/}
printf "%s\t%s\n" "$refname_without_prefix"
'
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
@ -43,13 +43,13 @@ _get_local_branches() {
eval "$cmd_get_local_branches"
}
# _get_everyones_remotes
# get_everyones_remotes
#
# Get porcelain list of all remote branches
#
# @TODO support remote_name (currently origin)
#
_get_everyones_remotes() {
get_everyones_remotes() {
local fmt
local cmd_everyones_remotes
@ -58,13 +58,12 @@ _get_everyones_remotes() {
# user.name<TAB>branch.name
# the TAB is used as a delimiter to awk with
# shellcheck disable=SC2016
fmt='
fmt="
a=%(authorname)
r=%(refname)
refname_without_prefix=${r#refs/remotes/$remote_name/}
printf "%s\t%s\n" "$a" "$refname_without_prefix"
'
refname_without_prefix=\${r#refs/remotes/\${remote_name}/}
printf \"%s\\t%s\\n\" \"\$a\" \"\$refname_without_prefix\"
"
cmd_everyones_remotes=$(
git for-each-ref --shell --format="$fmt" "refs/remotes/$remote_name"
@ -73,12 +72,12 @@ _get_everyones_remotes() {
eval "$cmd_everyones_remotes"
}
# _get_merged_remote_branches
# get_merged_remote_branches
#
# @param string optional remote to list merged branches of. Defaults to
# "origin/master"
# @output names of remote branches that are merged into given branch
_get_merged_remote_branches() {
get_merged_remote_branches() {
local remote
local remote_name
#local remote_refname
@ -98,7 +97,6 @@ _get_merged_remote_branches() {
)
# remove "origin/"
# shellcheck disable=SC2001
stripped_branchnames=$( \
echo "$merged_remote_branches" | sed "s/^\s*$remote_name\///g" \
)
@ -106,12 +104,12 @@ _get_merged_remote_branches() {
echo "$stripped_branchnames"
}
# _filter_mine
# filter_mine
#
# @param git_user
# @param branchnames
# @output branchnames owned by current git user
_filter_mine() {
filter_mine() {
local git_user
local branchnames
git_user=$1
@ -125,20 +123,40 @@ _filter_mine() {
echo "$my_remotes" | grep -v "HEAD" | awk -F'\t' '{ print $2 }'
}
_merge_lists() {
# shellcheck disable=SC2086
echo $1 $2 | tr ' ' '\n' | sort -u
# merge_lists
#
# Convert two lists to bash arrays, merge them, sort them
#
# @param list1
# @param list2
merge_lists() {
local l1
local l2
l1=$(echo "$1" | awk '{$1=$1};1')
l2=$(echo "$2" | awk '{$1=$1};1')
readarray -t a1 <<< "$l1"
readarray -t a2 <<< "$l2"
local merged
merged=( "${a1[@]}" "${a2[@]}" )
local intersect
readarray -t intersect < <(printf '%s\n' "${merged[@]}" | sort -u)
echo "${intersect[@]}"
}
# _decorate_merged
# decorate_merged
#
# @param string my_branches list of remote branch names owned by me
# @param string local_branches list of local branch names
# @param string merged_remote_branches list of all remote branch names merged
# into another branch
# @output table of branch names and status
_decorate_merged() {
local my_branches=$1
decorate_merged() {
local my_branches
readarray -t my_branches <<< "$(echo "$1" | tr ' ' '\n' )"
local local_branches=$2
local merged_remote_branches=$3
@ -156,8 +174,9 @@ _decorate_merged() {
# body
local zebra=0
for branchname in $my_branches
do
local last=$((${#my_branches[@]} - 1))
for i in "${!my_branches[@]}"; do
local branchname="${my_branches[$i]}"
local decorated=''
local is_local=' '
local is_tracked=' '
@ -166,7 +185,7 @@ _decorate_merged() {
echo "$local_branches" | grep -q "$branchname" && \
is_local='✓'
if git rev-parse --symbolic-full-name "$branchname"@{u} >/dev/null 2>&1; then
if git rev-parse --symbolic-full-name "$branchname@{u}" >/dev/null 2>&1; then
is_tracked='✓'
fi
@ -174,33 +193,37 @@ _decorate_merged() {
is_merged='✓'
if [ "$branchname" == "$(git symbolic-ref --short HEAD)" ]; then
branchname="${magenta}${branchname}${normal}"
branchname="${magenta}${branchname}"
else
branchname="${branchname}"
fi
decorated=$(printf " %s | %s | %s %s" \
"$is_local" "$is_tracked" "$is_merged" "$branchname")
"$is_local" "$is_tracked" "$is_merged" "$branchname")
if [ $zebra = 0 ]; then
echo -en "${normal}"
printf "\e[48;5;0m%s %s\n" "$decorated" "$clreol"
zebra=1
else
printf "\e[48;5;236m%s %s\n" "$decorated" "$clreol"
echo -en "${normal}"
printf "\e[48;5;236m%s %s" "$decorated" "$clreol"
if [[ "$i" != "$last" ]]; then printf "\n"; fi
zebra=0
fi
done
printf "\e[48;5;0m"
printf "\e[48;5;0m\n"
}
_main() {
main() {
local decorated
local everyones_remotes
local git_remote
local git_user
local local_branches
local merged_remote_branches
local my_branches
local my_remotes
local remote=${1:-"origin/master"}
@ -211,12 +234,22 @@ _main() {
local remote_ref=${remote#*/}
git_user=$(git config --get user.name)
if [ -z "$git_user" ]; then
echo "ERROR: user.name is not set in git config"
exit 1
fi
git_remote=$(git config --get "remote.${remote_name}.url")
everyones_remotes=$(_get_everyones_remotes "$remote_name")
my_remotes=$(_filter_mine "$git_user" "$everyones_remotes")
merged_remote_branches=$(_get_merged_remote_branches "$remote_name/$remote_ref")
local_branches=$(_get_local_branches)
my_branches=$(_merge_lists "$my_remotes" "$local_branches")
if [ -z "$git_remote" ]; then
echo "ERROR: remote.${remote_name}.url is not set"
exit 1
fi
everyones_remotes=$(get_everyones_remotes "$remote_name")
my_remotes=$(filter_mine "$git_user" "$everyones_remotes")
merged_remote_branches=$(get_merged_remote_branches "$remote_name/$remote_ref")
local_branches=$(get_local_branches)
my_branches=$(merge_lists "$my_remotes" "$local_branches")
echo
echo "branches owned by user: $git_user"
@ -224,15 +257,15 @@ _main() {
echo "in remote repository: $git_remote"
echo
_decorate_merged "$my_branches" "$local_branches" "$merged_remote_branches"
decorate_merged "$my_branches" "$local_branches" "$merged_remote_branches"
echo
}
if ! _check_in_repository ; then
if ! is_repository; then
echo "This is not a git repository."
exit 1
fi
_main "$@"
main "$@"