-
Notifications
You must be signed in to change notification settings - Fork 2
/
git-tfs-sync
180 lines (140 loc) · 5.04 KB
/
git-tfs-sync
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
#!/bin/sh
ME=$(basename "$0")
usage () {
cat <<EOF
Usage: $ME [-h|--help] [-v]
Options
=======
-h, --help
Show this usage text
-v
Verbose. Show extra output to aid in debugging.
This command will ensure that a Git branch which has a corresponding TFS
remote is synchronized with TFS and the branch's Git remote in the correct
order to prevent Git commit hash sequencing problems.
Whenever you need to update a local Git branch which has a corresponding TFS
remote, use this command instead of the standard fetch or pull commands or
even Git-TFS fetch or pull commands.
If the sequence of fetches or pulls is not performed in the correct order,
the effect would be the same as rebasing a public, shared Git branch,
possibly causing others to lose work or not be able to synchronize with the
Git remote.
EOF
exit 1
}
die () {
echo "$*" >&2
exit 1
}
write_info () {
echo "
$(tput setaf 14)$*$(tput sgr0)"
}
not_rebasing() {
local retVal;
test ! -d "${GIT_DIR:-.git}"/rebase-apply
retVal=$?
exit $retVal
}
get_upstream() {
test $# = 2 || exit 1
case $1 in
--remote|-r)
echo "$2" | sed -e 's|\([^/]*\)/\(.*\)|\1|' ;;
--branch|-b)
echo "$2" | sed -e 's|\([^/]*\)/\(.*\)|\2|' ;;
esac
}
FOUND_GIT_TFS="f"
VERBOSE="f"
BRANCH=
BRANCH_UPSTREAM=
BRANCH_TFS=
REBASING_MSG="
$(tput setaf 1)ERROR: Rebase in progress. Please finish the rebase operation in progress or
abort the rebase and try again.$(tput sgr0)
"
for arg
do
case $1 in
-h|-help)
usage
;;
-v)
VERBOSE="t"
shift
;;
esac
done
test $# = 0 || usage
FOUND_GIT_TFS="$(which git-tfs)" && test ! "$FOUND_GIT_TFS" = "f" || die "
$(tput setaf 1)ERROR: git-tfs could not be found. Please ensure you installed git-tfs and that
git-tfs.exe is in your PATH.$(tput sgr0)
"
# This is here just to add some separation between the script invocation
# and any script output.
echo
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
BRANCH_TFS=$(git config --local --get tfs-remote."$(git config --local --get git-tfs-branch."$BRANCH".remote)".repository) || die "
$(tput setaf 1)ERROR: A Git-TFS remote could not be found for this branch.$(tput sgr0)
Did you forget to issue a $(tput setaf 15)'git-tfs-remote add'$(tput sgr0) command on '$BRANCH'?
"
BRANCH_UPSTREAM="$(git rev-parse --abbrev-ref "$BRANCH"@{u})"
test -n "$(get_upstream -b "$BRANCH_UPSTREAM")" || die "$(tput setaf 1)ERROR: No Git remote tracking branch found.$(tput sgr0)
If the Git-TFS branch you're trying to synchronize is not shared on a
centralized Git server, simply use 'git-tfs-fetch -r -x' or
'git-tfs-pull -r -x' instead.
Otherwise, please issue the following command to setup a remote tracking branch:
git branch --set-upstream-to=<remote_name>/<remote_branch_name>
For example:
git branch --set-upstream-to=origin/feature/my-topic-branch
"
test "$VERBOSE" = "f" && test "$BRANCH" = "$(get_upstream -b "$BRANCH_UPSTREAM")" || \
cat <<EOF
Branch Information
===============================================================================
Branch name: $BRANCH
Upstream branch remote: $(get_upstream -r "$BRANCH_UPSTREAM")
Upstream branch name: $(get_upstream -b "$BRANCH_UPSTREAM")
TFS Remote: $BRANCH_TFS
EOF
test "$BRANCH" = "$(get_upstream -b "$BRANCH_UPSTREAM")" || (
CONTINUE=n
read -n 1 -p "
$(tput setaf 11)WARNING:$(tput sgr0) Your local branch name:
$(tput setaf 10)'$BRANCH'$(tput sgr0)
is different than the remote tracking branch name:
$(tput setaf 9)'$BRANCH_UPSTREAM'$(tput sgr0)
Please ensure the branch information above is correct before continuing.
$(tput setaf 15)Do you want to continue synchronization?$(tput sgr0) [y|$(tput setaf 11)N$(tput sgr0)] ? " CONTINUE
case "$CONTINUE" in
y|Y) echo
exit 0
;;
*)
exit 1
;;
esac
) || die "
$(tput setaf 1)Synchronization canceled.$(tput sgr0)
"
# Update the local copy of the destination branch from the git server
(write_info "Updating '$BRANCH' with any upstream commits" &&
(
git fetch $(get_upstream -r "$BRANCH_UPSTREAM") && \
git rebase "$BRANCH_UPSTREAM" && \
not_rebasing
) || die "$REBASING_MSG"
) || die
# Update the local copy of the destination branch with any changesets in TFS but not in git
(write_info "Updating '$BRANCH' with any new changesets from '$BRANCH_TFS'" && \
(
git tfs pull -x -r -i default && \
not_rebasing
) || die "$REBASING_MSG"
) || die
# At this point we can minimally push the new TFS changes to origin
(write_info "Updating '$BRANCH_UPSTREAM' with any new commits on '$BRANCH'" && \
git push $(get_upstream -r "$BRANCH_UPSTREAM") refs/notes/*:refs/notes/* "$BRANCH":"$(get_upstream -b "$BRANCH_UPSTREAM")"
) || die
exit