~ubuntu-branches/ubuntu/intrepid/git-core/intrepid-updates

« back to all changes in this revision

Viewing changes to git-merge.sh

  • Committer: Package Import Robot
  • Author(s): Gerrit Pape
  • Date: 2007-10-04 08:27:01 UTC
  • mfrom: (1.1.23)
  • Revision ID: package-import@ubuntu.com-20071004082701-rsd058ontoqz4i30
Tags: 1:1.5.3.4-1
new upstream point release (closes: #445188).

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
# Copyright (c) 2005 Junio C Hamano
4
4
#
5
5
 
6
 
USAGE='[-n] [--no-commit] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+'
 
6
USAGE='[-n] [--summary] [--no-commit] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+'
7
7
 
8
8
SUBDIRECTORY_OK=Yes
9
9
. git-sh-setup
19
19
all_strategies='recur recursive octopus resolve stupid ours subtree'
20
20
default_twohead_strategies='recursive'
21
21
default_octopus_strategies='octopus'
22
 
no_trivial_merge_strategies='ours subtree'
 
22
no_fast_forward_strategies='subtree ours'
 
23
no_trivial_strategies='recursive recur subtree ours'
23
24
use_strategies=
24
25
 
25
 
index_merge=t
 
26
allow_fast_forward=t
 
27
allow_trivial_merge=t
26
28
 
27
29
dropsave() {
28
30
        rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
31
33
 
32
34
savestate() {
33
35
        # Stash away any local modifications.
34
 
        git-diff-index -z --name-only $head |
 
36
        git diff-index -z --name-only $head |
35
37
        cpio -0 -o >"$GIT_DIR/MERGE_SAVE"
36
38
}
37
39
 
40
42
        then
41
43
                git reset --hard $head >/dev/null
42
44
                cpio -iuv <"$GIT_DIR/MERGE_SAVE"
43
 
                git-update-index --refresh >/dev/null
 
45
                git update-index --refresh >/dev/null
44
46
        fi
45
47
}
46
48
 
57
59
squash_message () {
58
60
        echo Squashed commit of the following:
59
61
        echo
60
 
        git-log --no-merges ^"$head" $remote
 
62
        git log --no-merges ^"$head" $remote
61
63
}
62
64
 
63
65
finish () {
79
81
                        echo "No merge message -- not updating HEAD"
80
82
                        ;;
81
83
                *)
82
 
                        git-update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1
 
84
                        git update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1
83
85
                        ;;
84
86
                esac
85
87
                ;;
88
90
        '')
89
91
                ;;
90
92
        ?*)
91
 
                case "$no_summary" in
92
 
                '')
93
 
                        git-diff-tree --stat --summary -M "$head" "$1"
94
 
                        ;;
95
 
                esac
 
93
                if test "$show_diffstat" = t
 
94
                then
 
95
                        # We want color (if set), but no pager
 
96
                        GIT_PAGER='' git diff --stat --summary -M "$head" "$1"
 
97
                fi
96
98
                ;;
97
99
        esac
98
100
}
99
101
 
100
102
merge_name () {
101
103
        remote="$1"
102
 
        rh=$(git-rev-parse --verify "$remote^0" 2>/dev/null) || return
103
 
        bh=$(git-show-ref -s --verify "refs/heads/$remote" 2>/dev/null)
 
104
        rh=$(git rev-parse --verify "$remote^0" 2>/dev/null) || return
 
105
        bh=$(git show-ref -s --verify "refs/heads/$remote" 2>/dev/null)
104
106
        if test "$rh" = "$bh"
105
107
        then
106
108
                echo "$rh               branch '$remote' of ."
107
109
        elif truname=$(expr "$remote" : '\(.*\)~[1-9][0-9]*$') &&
108
 
                git-show-ref -q --verify "refs/heads/$truname" 2>/dev/null
 
110
                git show-ref -q --verify "refs/heads/$truname" 2>/dev/null
109
111
        then
110
112
                echo "$rh               branch '$truname' (early part) of ."
111
113
        elif test "$remote" = "FETCH_HEAD" -a -r "$GIT_DIR/FETCH_HEAD"
120
122
case "$#" in 0) usage ;; esac
121
123
 
122
124
have_message=
123
 
while case "$#" in 0) break ;; esac
 
125
while test $# != 0
124
126
do
125
127
        case "$1" in
126
128
        -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
127
129
                --no-summa|--no-summar|--no-summary)
128
 
                no_summary=t ;;
 
130
                show_diffstat=false ;;
 
131
        --summary)
 
132
                show_diffstat=t ;;
129
133
        --sq|--squ|--squa|--squas|--squash)
130
134
                squash=t no_commit=t ;;
131
135
        --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
167
171
        shift
168
172
done
169
173
 
 
174
if test -z "$show_diffstat"; then
 
175
    test "$(git config --bool merge.diffstat)" = false && show_diffstat=false
 
176
    test -z "$show_diffstat" && show_diffstat=t
 
177
fi
 
178
 
170
179
# This could be traditional "merge <msg> HEAD <commit>..."  and the
171
180
# way we can tell it is to see if the second token is HEAD, but some
172
181
# people might have misused the interface and used a committish that
174
183
# have "-m" so it is an additional safety measure to check for it.
175
184
 
176
185
if test -z "$have_message" &&
177
 
        second_token=$(git-rev-parse --verify "$2^0" 2>/dev/null) &&
178
 
        head_commit=$(git-rev-parse --verify "HEAD" 2>/dev/null) &&
 
186
        second_token=$(git rev-parse --verify "$2^0" 2>/dev/null) &&
 
187
        head_commit=$(git rev-parse --verify "HEAD" 2>/dev/null) &&
179
188
        test "$second_token" = "$head_commit"
180
189
then
181
190
        merge_msg="$1"
182
191
        shift
183
192
        head_arg="$1"
184
193
        shift
185
 
elif ! git-rev-parse --verify HEAD >/dev/null 2>&1
 
194
elif ! git rev-parse --verify HEAD >/dev/null 2>&1
186
195
then
187
196
        # If the merged head is a valid one there is no reason to
188
197
        # forbid "git merge" into a branch yet to be born.  We do
196
205
        rh=$(git rev-parse --verify "$1^0") ||
197
206
                die "$1 - not something we can merge"
198
207
 
199
 
        git-update-ref -m "initial pull" HEAD "$rh" "" &&
200
 
        git-read-tree --reset -u HEAD
 
208
        git update-ref -m "initial pull" HEAD "$rh" "" &&
 
209
        git read-tree --reset -u HEAD
201
210
        exit
202
211
 
203
212
else
212
221
        merge_name=$(for remote
213
222
                do
214
223
                        merge_name "$remote"
215
 
                done | git-fmt-merge-msg
 
224
                done | git fmt-merge-msg
216
225
        )
217
226
        merge_msg="${merge_msg:+$merge_msg$LF$LF}$merge_name"
218
227
fi
219
 
head=$(git-rev-parse --verify "$head_arg"^0) || usage
 
228
head=$(git rev-parse --verify "$head_arg"^0) || usage
220
229
 
221
230
# All the rest are remote heads
222
231
test "$#" = 0 && usage ;# we need at least one remote head.
225
234
remoteheads=
226
235
for remote
227
236
do
228
 
        remotehead=$(git-rev-parse --verify "$remote"^0 2>/dev/null) ||
 
237
        remotehead=$(git rev-parse --verify "$remote"^0 2>/dev/null) ||
229
238
            die "$remote - not something we can merge"
230
239
        remoteheads="${remoteheads}$remotehead "
231
240
        eval GITHEAD_$remotehead='"$remote"'
237
246
'')
238
247
        case "$#" in
239
248
        1)
240
 
                var="`git-config --get pull.twohead`"
 
249
                var="`git config --get pull.twohead`"
241
250
                if test -n "$var"
242
251
                then
243
252
                        use_strategies="$var"
245
254
                        use_strategies="$default_twohead_strategies"
246
255
                fi ;;
247
256
        *)
248
 
                var="`git-config --get pull.octopus`"
 
257
                var="`git config --get pull.octopus`"
249
258
                if test -n "$var"
250
259
                then
251
260
                        use_strategies="$var"
258
267
 
259
268
for s in $use_strategies
260
269
do
261
 
        for nt in $no_trivial_merge_strategies
262
 
        do
263
 
                case " $s " in
264
 
                *" $nt "*)
265
 
                        index_merge=f
 
270
        for ss in $no_fast_forward_strategies
 
271
        do
 
272
                case " $s " in
 
273
                *" $ss "*)
 
274
                        allow_fast_forward=f
 
275
                        break
 
276
                        ;;
 
277
                esac
 
278
        done
 
279
        for ss in $no_trivial_strategies
 
280
        do
 
281
                case " $s " in
 
282
                *" $ss "*)
 
283
                        allow_trivial_merge=f
266
284
                        break
267
285
                        ;;
268
286
                esac
271
289
 
272
290
case "$#" in
273
291
1)
274
 
        common=$(git-merge-base --all $head "$@")
 
292
        common=$(git merge-base --all $head "$@")
275
293
        ;;
276
294
*)
277
 
        common=$(git-show-branch --merge-base $head "$@")
 
295
        common=$(git show-branch --merge-base $head "$@")
278
296
        ;;
279
297
esac
280
298
echo "$head" >"$GIT_DIR/ORIG_HEAD"
281
299
 
282
 
case "$index_merge,$#,$common,$no_commit" in
283
 
f,*)
284
 
        # We've been told not to try anything clever.  Skip to real merge.
285
 
        ;;
 
300
case "$allow_fast_forward,$#,$common,$no_commit" in
286
301
?,*,'',*)
287
302
        # No common ancestors found. We need a real merge.
288
303
        ;;
292
307
        finish_up_to_date "Already up-to-date."
293
308
        exit 0
294
309
        ;;
295
 
?,1,"$head",*)
 
310
t,1,"$head",*)
296
311
        # Again the most common case of merging one remote.
297
 
        echo "Updating $(git-rev-parse --short $head)..$(git-rev-parse --short $1)"
298
 
        git-update-index --refresh 2>/dev/null
 
312
        echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $1)"
 
313
        git update-index --refresh 2>/dev/null
299
314
        msg="Fast forward"
300
315
        if test -n "$have_message"
301
316
        then
302
317
                msg="$msg (no commit created; -m option ignored)"
303
318
        fi
304
 
        new_head=$(git-rev-parse --verify "$1^0") &&
305
 
        git-read-tree -v -m -u --exclude-per-directory=.gitignore $head "$new_head" &&
 
319
        new_head=$(git rev-parse --verify "$1^0") &&
 
320
        git read-tree -v -m -u --exclude-per-directory=.gitignore $head "$new_head" &&
306
321
        finish "$new_head" "$msg" || exit
307
322
        dropsave
308
323
        exit 0
314
329
?,1,*,)
315
330
        # We are not doing octopus, not fast forward, and have only
316
331
        # one common.
317
 
        git-update-index --refresh 2>/dev/null
318
 
        case " $use_strategies " in
319
 
        *' recursive '*|*' recur '*)
320
 
                : run merge later
321
 
                ;;
322
 
        *)
 
332
        git update-index --refresh 2>/dev/null
 
333
        case "$allow_trivial_merge" in
 
334
        t)
323
335
                # See if it is really trivial.
324
336
                git var GIT_COMMITTER_IDENT >/dev/null || exit
325
337
                echo "Trying really trivial in-index merge..."
326
 
                if git-read-tree --trivial -m -u -v $common $head "$1" &&
327
 
                   result_tree=$(git-write-tree)
 
338
                if git read-tree --trivial -m -u -v $common $head "$1" &&
 
339
                   result_tree=$(git write-tree)
328
340
                then
329
341
                        echo "Wonderful."
330
342
                        result_commit=$(
331
343
                                printf '%s\n' "$merge_msg" |
332
 
                                git-commit-tree $result_tree -p HEAD -p "$1"
 
344
                                git commit-tree $result_tree -p HEAD -p "$1"
333
345
                        ) || exit
334
346
                        finish "$result_commit" "In-index merge"
335
347
                        dropsave
343
355
        up_to_date=t
344
356
        for remote
345
357
        do
346
 
                common_one=$(git-merge-base --all $head $remote)
 
358
                common_one=$(git merge-base --all $head $remote)
347
359
                if test "$common_one" != "$remote"
348
360
                then
349
361
                        up_to_date=f
412
424
        if test "$exit" -eq 1
413
425
        then
414
426
            cnt=`{
415
 
                git-diff-files --name-only
416
 
                git-ls-files --unmerged
 
427
                git diff-files --name-only
 
428
                git ls-files --unmerged
417
429
            } | wc -l`
418
430
            if test $best_cnt -le 0 -o $cnt -le $best_cnt
419
431
            then
425
437
    }
426
438
 
427
439
    # Automerge succeeded.
428
 
    result_tree=$(git-write-tree) && break
 
440
    result_tree=$(git write-tree) && break
429
441
done
430
442
 
431
443
# If we have a resulting tree, that means the strategy module
432
444
# auto resolved the merge cleanly.
433
445
if test '' != "$result_tree"
434
446
then
435
 
    parents=$(git-show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
436
 
    result_commit=$(printf '%s\n' "$merge_msg" | git-commit-tree $result_tree $parents) || exit
 
447
    parents=$(git show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
 
448
    result_commit=$(printf '%s\n' "$merge_msg" | git commit-tree $result_tree $parents) || exit
437
449
    finish "$result_commit" "Merge made by $wt_strategy."
438
450
    dropsave
439
451
    exit 0
489
501
                sed -e 's/^[^   ]*      /       /' |
490
502
                uniq
491
503
        } >>"$GIT_DIR/MERGE_MSG"
492
 
        if test -d "$GIT_DIR/rr-cache"
493
 
        then
494
 
                git-rerere
495
 
        fi
 
504
        git rerere
496
505
        die "Automatic merge failed; fix conflicts and then commit the result."
497
506
fi