-
Notifications
You must be signed in to change notification settings - Fork 13
/
git-up
executable file
·117 lines (100 loc) · 2.66 KB
/
git-up
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env bash
# git-up -- fast-forward the latest changes from upstream
# TODO:
# fetch.output compact
# merge.stat off
. lib.bash || exit
log:() {
"$@" || err "command '$1' failed (status $?)"
}
svnsync() {
local lib=$(which libfunsync.so 2>/dev/null)
if [[ -f $lib ]]; then
env LD_PRELOAD="$lib" svnsync "$@"
else
env svnsync "$@"
fi
}
update() {
# If we're running in a subdir
dir=$(git rev-parse --show-cdup) && cd "$dir" || return
if [[ -d .git/svn ]]; then
if remote=$(git config --get svn-remote.svn.url); then
rroot=$(log: svn info "$remote" | sed -n 's/^Repository Root: //p')
if [[ $rroot == file://* ]]; then
log: svnsync sync "$rroot"
fi
fi
ref=$(git config --get svn-remote.svn.fetch)
ref=${ref#*:}
ref=${ref:-refs/remotes/git-svn}
old=$(git rev-parse --verify HEAD)
log: git svn fetch &&
log: git merge --ff-only "$ref" || return
new=$(git rev-parse --verify HEAD)
elif [[ -e .git ]]; then
sparse=$(git config --type bool core.sparseCheckout || echo false)
case $sparse in
true) recurseopt='--recurse-submodules=no';;
*) recurseopt='';
esac
old=$(git rev-parse --verify HEAD)
log: git pull --ff-only --no-stat $recurseopt || return
new=$(git rev-parse --verify HEAD)
if [[ -e .gitmodules ]] && [[ $sparse != true ]]; then
log: git submodule update
fi
elif [[ "$(git config core.bare)" == "true" ]]; then
old=$(git rev-parse --verify HEAD)
git fetch || return
new=$(git rev-parse --verify HEAD)
fi
if [[ "$old" != "$new" ]] && (( opt_stat || opt_tig )); then
local diff_paths=(:!{fuzz,test\*,vendor}/)
mapfile -t -O ${#diff_paths[@]} diff_paths \
< <(git config --get-all nullroute.git-new.paths)
local diff_args=("$old..$new" -- "${diff_paths[@]}")
if (( opt_stat )); then
git --no-pager diff --stat "${diff_args[@]}"
fi
if (( opt_tig )); then
revs=$(git rev-list --count "${diff_args[@]}")
# Only run tig if there are commits to show, as
# otherwise it still triggers the 'focus' \e[I and
# there's no Bash prompt to consume that.
if (( revs )); then
local tig_opts=()
mapfile -t tig_opts \
< <(git config --get-all nullroute.git-new.options)
tig "${tig_opts[@]}" "${diff_args[@]}" || true
else
vmsg "no interesting commits to show"
fi
fi
fi
}
usage() {
echo "Usage: $progname [<dir>...]"
}
set -u
opt_stat=0
opt_tig=1
if (( ${PULL_DIFFSTAT-} )); then
opt_stat=1
fi
if (( ${PULL_NONINTERACTIVE-} )); then
opt_tig=0
fi
while getopts : OPT; do
case $OPT in
*) lib:die_getopts;;
esac
done; shift $[OPTIND-1]
(( $# )) || set -- .
for arg; do
if [[ $* != . ]]; then
vmsg "updating $arg"
settitle "pull $arg"
fi
(cd "$arg" && update)
done