Test commit
[cogito/jonas.git] / cg-merge
blob2038f6952823faa2bb9c1c4afd18b8de27ba15f0
1 #!/usr/bin/env bash
3 # Merge a branch to the current branch
4 # Copyright (c) Petr Baudis, 2005
6 # Takes a parameter identifying the branch to be merged, defaulting
7 # to 'origin' or the current branch's default remote branch, see `cg-fetch`
8 # for details).
10 # This command merges all changes currently in the given branch to your
11 # current branch. This can produce a merging commit on your branch sticking
12 # the two branch together (so-called 'tree merge'). However in case there
13 # are no changes in your branch that wouldn't be in the remote branch, no
14 # merge commit is done and commit pointer of your branch is just updated
15 # to the last commit on the remote branch (so-called 'fast-forward merge').
17 # In case of conflicts being generated by the merge, you have to examine
18 # the tree (cg-merge will tell you which files contain commits; the commits
19 # are denoted by rcsmerge-like markers <<<<, ====, and >>>>) and then do
20 # `cg-commit` yourself. `cg-commit` will know that you are committing a merge
21 # and will record it properly.
23 # Note that when you are merging remote branches, `cg-merge` will use them
24 # in the state they are currently at in your repository. If you want to
25 # fetch the latest changes from the remote repository, use `cg-fetch`. If you
26 # want to fetch the changes and then merge them to your branch, use the command
27 # `cg-update`.
29 # Also note that if you have local changes in your tree that you did not
30 # commit, cg-merge will always preserve them when fast-forwarding. When doing
31 # a tree merge, it will preserve them if they don't conflict with the merged
32 # changes, and report an error otherwise. In short, it should do the Right
33 # Thing (tm), never lose your local changes and never let them mix up with
34 # the merge.
36 # OPTIONS
37 # -------
38 # -b BASE_COMMIT:: Specify the base commit for the merge
39 # Parameter specifies the base commit for the merge. Otherwise, the
40 # least common ancestor is automatically selected.
42 # -j:: Join current branch with BRANCH_NAME
43 # Join the current branch and BRANCH_NAME together. This makes sense
44 # when the branches have no common history, meaning they are actually
45 # not branches related at all as far as GIT is concerned. Merging such
46 # branches might be a user error and you well may be doing something
47 # you do not want; but equally likely, you may actually WANT to join
48 # the projects together, which is what this option does.
50 # -n:: Disable autocommitting
51 # Parameter specifies that you want to have tree merge never
52 # autocommitted, but want to review and commit it manually. This will
53 # basically make cg-merge always behave like there were conflicts
54 # during the merge.
56 # --squash:: Use "squash" merge to record pending commits as a single merge commit
57 # "Squash" merge - condense all the to-be-merged commits to a single
58 # merge commit. This means "throw away history of the branch I'm
59 # merging", essentially like in CVS or SVN, with the same problem -
60 # re-merging with that branch later will cause trouble. This is not
61 # recommended unless you actually really want to flatten the history
62 # of the merged branch, e.g. when merging topical branches to your
63 # mainline (you want to have the logical change you developed in
64 # a branch as a single "do it" commit instead of a sequence of
65 # "do it I", "fix it", "do it II", "fix it II", "fix it III" commits
66 # like you would get with a regular merge).
68 # -v:: Enable verbosity
69 # Display more verbose output - most notably list all the files
70 # touched by the merged changes.
72 # HOOKS
73 # -----
74 # '.git/hooks/merge-pre' BRANCH BASE CURHEAD MERGEDHEAD MERGETYPE::
75 # If the file exists and is executable it will be executed right
76 # before the merge itself happens. The merge is cancelled if the script
77 # returns non-zero exit code.
78 # - MERGETYPE is either "forward", "squash", or "tree".
80 # '.git/hooks/merge-post' BRANCH BASE CURHEAD MERGEDHEAD MERGETYPE STATUS::
81 # If the file exists and is executable it will be executed after
82 # the merge is done.
83 # - MERGETYPE is either "forward", "squash", or "tree".
84 # - For 'forward', the STATUS is "ok" or "localchanges", while for
85 # "squash" and "tree" the STATUS can be "localchanges", "conflicts",
86 # "nocommit", or "ok".
88 # Developer's documentation:
90 # ENVIRONMENT
91 # -----------
92 # _cg_orig_head::
93 # The original commit ID of the to-be-merged branch, if cg-merge
94 # is called right after fetch. This is used to do better decision
95 # about whether to fast-forward or tree-merge.
97 # Testsuite: Largely covered (t92xx testsuite family, incomplete coverage;
98 # missing: hooks, -n, -b, --squash)
100 USAGE="cg-merge [-n] [-b BASE_COMMIT] [-j] [--squash] [-v] [BRANCH_NAME]"
101 _git_requires_root=1
103 . "${COGITO_LIB}"cg-Xlib || exit 1
106 prehook()
108 if [ -x "$_git/hooks/merge-pre" ]; then
109 "$_git/hooks/merge-pre" "$branchname" "$base" "$head" "$branch" "$@" || die "merge cancelled by hook"
113 posthook()
115 if [ -x "$_git/hooks/merge-post" ]; then
116 "$_git/hooks/merge-post" "$branchname" "$base" "$head" "$branch" "$@"
121 head="$(cg-object-id -c)" || exit 1
124 careful=
125 base=
126 join=
127 squash=
128 verbose=
129 while optparse; do
130 if optparse -n; then
131 careful=1
132 elif optparse -c; then
133 warn "cg-merge -c is deprecated, cg-merge -n is the new flag name"
134 careful=1
135 elif optparse -b=; then
136 base="$(cg-object-id -c "$OPTARG")" || exit 1
137 elif optparse -j; then
138 join=1
139 # -s reserved to strategy
140 elif optparse --squash; then
141 squash=1
142 elif optparse -v; then
143 verbose=1
144 else
145 optfail
147 done
149 branchname="${ARGS[0]}"
150 [ "$branchname" ] || branchname="$(choose_origin branches "what to merge?")" || exit 1
151 branch=$(cg-object-id -c "$branchname") || exit 1
153 [ "$base" ] || base="$(git-merge-base --all "$head" "$branch")"
154 if [ ! "$join" ]; then
155 [ "$base" ] || die "unable to automatically determine merge base (consider cg-merge -j)"
156 baselist=($base)
157 if [ "${#baselist[@]}" -gt "1" ]; then
158 echo "Multiple merge base candidates, please select one manually (by running cg-merge -b BASE [BRANCH]):"
159 echo "${baselist[*]}" | tr ' ' '\n'
160 echo
161 conservative_merge_base "${baselist[@]}" # -> _cg_baselist
162 echo -n "The most conservative base (but likely a lot of conflicts): "
163 echo "${_cg_baselist[*]}"
164 exit 3
165 fi >&2
167 else
168 [ "$base" ] && die "joining branches with common history is something I refuse to do"
169 index="$(mktemp -t gitmerge.XXXXXX)" || exit $?
170 GIT_INDEX_FILE="$index" git-read-tree
171 base="$(GIT_INDEX_FILE="$index" git-write-tree)"
172 rm "$index"
176 [ -s "$_git/blocked" ] && die "merge blocked: $(cat "$_git/blocked")"
177 # Deprecated as of 2006-11-17
178 [ -s "$_git/merging" ] && die "old-style merge state detected, panicking; you upgraded cogito in the middle of a merge! redo the merge, cg-reset will bring you back to the starting line"
180 statedir="$_git/cg-merge-state"
182 if [ -s "$statedir/merging" ] && grep -q "$branch" "$statedir/merging"; then
183 echo "Branch already merged in the working tree." >&2
184 exit 0
187 if [ "$base" = "$branch" ]; then
188 echo "Branch already fully merged." >&2
189 exit 0
192 if { [ "$head" = "$base" ] || [ "$head" = "$_cg_orig_head" ]; } && [ ! "$squash" ] && [ ! -s "$statedir/merging" ]; then
193 # No need to do explicit merge with a merge commit; just bring
194 # the HEAD forward.
196 echo "Fast-forwarding $base -> $branch" >&2
197 echo -e "\ton top of $head ..." >&2
199 [ "$verbose" ] && git-diff-tree --abbrev -r "$(cg-object-id -t "$head")" "$(cg-object-id -t "$branch")"
201 prehook forward
202 if ! tree_timewarp "forward" "yes, rollback (or rather rollforth) the tree!" "$head" "$branch"; then
203 posthook forward localchanges
204 exit 1
206 posthook forward ok
208 exit 0
212 git-update-index --refresh >/dev/null
214 if [ ! "$squash" ]; then
215 [ -s "$statedir/squashing" ] && die "cannot combine squashing and non-squashing merges"
217 echo "Merging $base -> $branch" >&2
218 echo -e "\tto $head ..." >&2
220 mergetype="tree"
221 else
222 echo "Squashing $base -> $branch" >&2
223 echo -e "\ton top of $head ..." >&2
225 mergetype="squash"
228 [ "$verbose" ] && git-diff-tree --abbrev -r "$(cg-object-id -t "$base")" "$(cg-object-id -t "$branch")"
230 prehook "$mergetype"
232 mkdir -p "$statedir"
234 git-diff-index --name-only "$(cg-object-id -t $head)" >>"$statedir/commit-ignore"
235 # Don't keep around useless empty files
236 [ -s "$statedir/commit-ignore" ] || rm "$statedir/commit-ignore"
238 if ! git-read-tree -u -m "$(cg-object-id -t "$base")" "$(cg-object-id -t "$head")" "$(cg-object-id -t "$branch")"; then
239 echo "cg-merge: git-read-tree failed (merge likely blocked by local changes)" >&2
240 posthook "$mergetype" localchanges
241 rm -f "$statedir/commit-ignore"
242 rmdir "$statedir"
243 exit 1
246 echo "$base" >>"$statedir/merge-base"
247 echo "$branch" >>"$statedir/merging"
248 echo "$branchname" >>"$statedir/merging-sym"
249 [ "$squash" ] && echo "$branch" >>"$statedir/squashing"
251 if ! git-merge-index -o -q "${COGITO_LIB}"cg-Xmergefile -a || [ "$careful" ]; then
252 echo >&2
253 if [ ! "$careful" ]; then
254 echo " Conflicts during merge. Do cg-commit after resolving them." >&2
255 else
256 echo " Do cg-commit after reviewing the merge." >&2
258 if [ -s "$statedir/commit-ignore" ]; then
259 echo " cg-reset will cancel the merge (but also your pending local changes!)." >&2
260 echo >&2
261 echo " These files contained local modifications and won't be automatically chosen for committing:" >&2
262 cat "$statedir/commit-ignore" >&2
263 else
264 echo " cg-reset will cancel the merge." >&2
265 echo >&2
267 posthook "$mergetype" conflicts
268 exit 2
271 echo
272 readtree=
273 if ! cg-commit -C; then
274 readtree=1
275 echo "cg-merge: COMMIT FAILED, retry manually" >&2
276 if [ -s "$statedir/commit-ignore" ]; then
277 echo " cg-reset will cancel the merge (but also your pending local changes!)." >&2
278 else
279 echo " cg-reset will cancel the merge." >&2
281 posthook "$mergetype" nocommit
284 [ "$readtree" ] && git-read-tree -m HEAD
285 # update_index here is safe because no tree<->index desyncs could've
286 # survived the read-tree above
287 update_index
289 posthook "$mergetype" ok