-
Notifications
You must be signed in to change notification settings - Fork 2
/
git-jolt
executable file
·58 lines (48 loc) · 1.76 KB
/
git-jolt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#! /bin/bash
#
# Create worktree for the branch of current repo (if absent) and output path to cd to it.
# Will automatically setup local tracking branch if passed remote branch.
# Worktree will be created one level above git dir, so for cleaner layout
# it is recommended to have checkout structure like <project>/<branch>/.git
#
# See helper function below to change directory to worktree in one go.
#
# Usage: git jolt { <branch> | <remote>/<branch> }
set -e
# TODO
# - use dir <repo>_<branch> when there is no separate level for branches
: <<'COMMENT'
# suggested for .bashrc
# function to cd to the worktree dir
function gj() { cd $(git jolt "$@" || echo .) ; }
# bash autocompletion (sourcing required to get __git_complete)
source /usr/share/bash-completion/completions/git
_git_jolt() { __gitcomp_nl "$(__git_refs)"; }
__git_complete gj _git_jolt
COMMENT
cmd() {
echo "[#] $*" >&2
"$@"
}
branch=$1
where=$(git name-rev --name-only "$branch")
if [[ "$where" == remotes/* ]] ; then
remote=$branch
branch=${where#*/*/}
# checkout tracking branch, it doesn't exist cause otherwise name-rev would have returned it
>&2 cmd git branch "$branch" "$remote"
where=$(git name-rev --name-only "$branch")
fi
if [ -z "$where" ] ; then >&2 echo "cannot find $branch" ; exit 1; fi
>&2 echo "looking for $where"
dir=$(git worktree list --porcelain | grep "^branch refs/heads/$where$" -B 3 | grep ^worktree | cut -d ' ' -f 2)
if [ -z "$dir" ] ; then
dir=$(git worktree list --porcelain | grep ^worktree | head -1 | cut -d ' ' -f 2)
if [ -z "$dir" ] ; then >&2 echo cannot find master; exit 2; fi
dir=$(realpath -m "$dir/../$where")
>&2 cmd git worktree add "$dir" "$where"
fi
cur=$(pwd)
git=$(git rev-parse --show-toplevel)
rel=${cur#$git}
echo "$(realpath -m "$dir/$rel")"