-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit-sync
More file actions
executable file
·192 lines (163 loc) · 5.25 KB
/
Copy pathgit-sync
File metadata and controls
executable file
·192 lines (163 loc) · 5.25 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#!/bin/bash
#
# Script that syncs a branch of a repo tracking a remote repo.
# Checks first to make sure there's no uncommited changes on the local branch,
# and fails.
# Basically, this means:
# git checkout master
# git pull
# git checkout <original branch>
# git pull master
#
SUBREMOTE=""
# Set usage output
DESCRIPTION="Sync a git repo with it's tracking branch and remote repo"
USAGE="[-h |--help] [-V | --verbose] [-f | --force] [-s | --stash] [-o | --origin] [-r | --remote]"
LONGUSAGE="\t-h, --help\n\t\tPrint this help message
\t-V, --verbose\n\t\tPrint verbose debugging info
\t-f, --force\n\t\tSync even if the local branch is not up-to-date
\t-s, --stash\n\t\tStash before syncing, and pop after
\t-o, --origin\n\t\tIf in a workspace, update origin insted of local
\t-r, --remote\n\t\tUpdate submodules to the most recent version"
# Standard functions
GTWS_LOC=$(readlink -f $(dirname "$0"))
source ${GTWS_LOC}/gtws.sh
# Script name
ME=$(basename $0)
# Parse arguments
ARGS=`getopt -o hVfsort --long help,verbose,force,stash,origin,remote,tags -n "${ME}" -- "$@"`
if [ $? != 0 ] ; then
usage
fi
eval set -- "$ARGS"
while true ; do
case "$1" in
-h|--help) usage; shift ;;
-V|--verbose) GTWS_VERBOSE="yes"; shift ;;
-f|--force) FORCE="yes"; shift ;;
-s|--stash) STASH="yes"; shift ;;
-o|--origin) ORIGIN="yes"; shift ;;
-r|--remote) SUBREMOTE="--remote"; shift ;;
-t|--tags) TAGS="yes"; shift ;;
--) shift ; break ;;
* ) usage "Invalid argument $1";;
esac
done
# Remaining arguments are in $1, $2, etc. as normal
# Source the git environment. Checks to see if we're in a git repo
SUBDIRECTORY_OK=Yes
source "$(git --exec-path)/git-sh-setup"
# Re-source my script to replace git's version of functions
source ${GTWS_LOC}/gtws.sh
# update_repo ${repo_path} ${stash}
function update_repo {
local repodir=$1
local stash=$2
local savedir=${PWD}
local branch=$(git branch | grep "\*" | sed 's/\* //')
local remote=$(git config --get branch.${branch}.remote)
local bare=
local upstream=
GIT_DIR="$(git rev-parse --git-dir 2>/dev/null)"
is_git_rebase && die "Rebase in progress"
if git-issvn > /dev/null 2>&1; then
local svn="yes"
fi
cd "${repodir}"
if test "z$(is_bare_repository)" == ztrue; then
bare="true"
fi
if [ -n "${bare}" ]; then
upstream=
elif [ -z "${remote}" ]; then
upstream="master"
elif [ "${remote}" == "." ]; then
# Local tracking branch. Use it instead of master
m=$(git config --get branch.${branch}.merge)
upstream=${m##*/}
elif [ "${remote}" == "origin" ]; then
# This branch directly tracks upstream; don't do any form of
# local upstream
upstream=
fi
if [ -n "${stash}" ]; then
git stash || die "Couldn't stash" || return 1
fi
if [ -z "${bare}" -a -z "${FORCE}" ]; then
git status | grep clean > /dev/null || \
die "Current branch is not clean" || return 1
fi
if [ -n "${upstream}" ]; then
echo "Updating ${upstream} first..."
git checkout ${upstream} || \
die "Could not checkout ${upstream}" || return 1
if [ -n "${svn}" ]; then
git svn rebase || die "rebase of ${upstream} failed" || return 1
else
git pull --rebase || \
die "rebase of ${upstream} failed" || return 1
git submodule update --init --recursive ${SUBREMOTE} || \
die "submodule update of ${upstream} failed" || return 1
fi
git checkout ${branch}
fi
if [ -n "${bare}" ]; then
debug_print "Updating bare"
git fetch --all --prune || die "update of bare repo failed" || return 1
elif [ -n "${svn}" ]; then
debug_print "Updating svn ${branch}"
git svn rebase || die "rebase of ${branch} failed" || return 1
else
debug_print "Updating git ${branch}"
git pull --rebase || die "rebase of ${branch} failed" || return 1
git submodule update --init --recursive ${SUBREMOTE} || \
die "submodule update of ${branch} failed" || return 1
fi
if [ -n "${stash}" ]; then
git stash pop
fi
cd "${savedir}"
}
branch=$(git branch | grep "\*" | sed 's/\* //' | grep detached)
if [ -n "${branch}" ]; then
die "Checkout is on detached HEAD. Please pick a branch"
fi
function sm_update {
local smopv="${1}"
local subpaths=$(gtws_submodule_paths)
debug_print "${FUNCNAME} updating ${smopv}"
for sub in ${subpaths}; do
MIRROR=$(gtws_submodule_mirror ${smopv} ${sub})
debug_print "${sub}: ${MIRROR}"
if [ -d "${MIRROR}" ]; then
echo ""
echo "Updating submodule mirror $MIRROR"
update_repo "${MIRROR}" || die
local sub_base==${sub%.git}
if [ -d "${smopv}/${sub_base}_submodule" ]; then
sm_update "${smopv}/${sub_base}_submodule"
fi
fi
done
}
if [ -n "${ORIGIN}" ]; then
is_gtws || usage "--origin may only be given inside a workspace"
OPV=$(gtws_opvn "${GTWS_ORIGIN}" "${GTWS_PROJECT}" "${GTWS_PROJECT_VERSION}" "${GTWS_WSNAME}")
# First update upstream
git_top_dir GITDIR || die "Failed to get top dir"
TARGET=$(basename $GITDIR)
gtws_get_origin "${OPV}" "${TARGET}" OREPO || die "failed to get origin"
echo ""
echo "Updating origin $OREPO"
update_repo "${OREPO}"
SMOPV=$(gtws_smopvn "${GTWS_ORIGIN}" "${GTWS_PROJECT}" "${GTWS_PROJECT_VERSION}" "${GTWS_WSNAME}")
sm_update ${SMOPV}
fi
# Update local repo
echo ""
echo "Updating checkout";
update_repo "." ${STASH} || die
# Neovim doesn't use cscope anymore, so don't make tags
#if [ -n "${TAGS}" -a -f ".maketagssave" ]; then
#maketags -r
#fi