1# This shell script fragment is sourced by git-rebase to implement 2# its merge-based non-interactive mode that copes well with renamed 3# files. 4# 5# Copyright (c) 2010 Junio C Hamano. 6# 7 8prec=4 9 10read_state () { 11 onto_name=$(cat "$state_dir"/onto_name) && 12 end=$(cat "$state_dir"/end) && 13 msgnum=$(cat "$state_dir"/msgnum) 14} 15 16continue_merge () { 17 test -d "$state_dir" || die "$state_dir directory does not exist" 18 19 unmerged=$(git ls-files -u) 20 if test -n "$unmerged" 21 then 22 echo "You still have unmerged paths in your index" 23 echo "did you forget to use git add?" 24 die "$resolvemsg" 25 fi 26 27 cmt=`cat "$state_dir/current"` 28 if ! git diff-index --quiet --ignore-submodules HEAD -- 29 then 30 if ! git commit --no-verify -C "$cmt" 31 then 32 echo "Commit failed, please do not call \"git commit\"" 33 echo "directly, but instead do one of the following: " 34 die "$resolvemsg" 35 fi 36 if test -z "$GIT_QUIET" 37 then 38 printf "Committed: %0${prec}d " $msgnum 39 fi 40 echo "$cmt $(git rev-parse HEAD^0)" >> "$state_dir/rewritten" 41 else 42 if test -z "$GIT_QUIET" 43 then 44 printf "Already applied: %0${prec}d " $msgnum 45 fi 46 fi 47 test -z "$GIT_QUIET" && 48 GIT_PAGER='' git log --format=%s -1 "$cmt" 49 50 # onto the next patch: 51 msgnum=$(($msgnum + 1)) 52 echo "$msgnum" >"$state_dir/msgnum" 53} 54 55call_merge () { 56 cmt="$(cat "$state_dir/cmt.$1")" 57 echo "$cmt" > "$state_dir/current" 58 hd=$(git rev-parse --verify HEAD) 59 cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD) 60 msgnum=$(cat "$state_dir/msgnum") 61 eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"' 62 eval GITHEAD_$hd='$onto_name' 63 export GITHEAD_$cmt GITHEAD_$hd 64 if test -n "$GIT_QUIET" 65 then 66 GIT_MERGE_VERBOSITY=1 && export GIT_MERGE_VERBOSITY 67 fi 68 test -z "$strategy" && strategy=recursive 69 eval 'git-merge-$strategy' $strategy_opts '"$cmt^" -- "$hd" "$cmt"' 70 rv=$? 71 case "$rv" in 72 0) 73 unset GITHEAD_$cmt GITHEAD_$hd 74 return 75 ;; 76 1) 77 git rerere $allow_rerere_autoupdate 78 die "$resolvemsg" 79 ;; 80 2) 81 echo "Strategy: $strategy failed, try another" 1>&2 82 die "$resolvemsg" 83 ;; 84 *) 85 die "Unknown exit code ($rv) from command:" \ 86 "git-merge-$strategy $cmt^ -- HEAD $cmt" 87 ;; 88 esac 89} 90 91finish_rb_merge () { 92 move_to_original_branch 93 if test -s "$state_dir"/rewritten 94 then 95 git notes copy --for-rewrite=rebase <"$state_dir"/rewritten 96 if test -x "$GIT_DIR"/hooks/post-rewrite 97 then 98 "$GIT_DIR"/hooks/post-rewrite rebase <"$state_dir"/rewritten 99 fi 100 fi 101 say All done. 102} 103 104# The whole contents of this file is run by dot-sourcing it from 105# inside a shell function. It used to be that "return"s we see 106# below were not inside any function, and expected to return 107# to the function that dot-sourced us. 108# 109# However, FreeBSD /bin/sh misbehaves on such a construct and 110# continues to run the statements that follow such a "return". 111# As a work-around, we introduce an extra layer of a function 112# here, and immediately call it after defining it. 113git_rebase__merge () { 114 115case "$action" in 116continue) 117 read_state 118 continue_merge 119 while test "$msgnum" -le "$end" 120 do 121 call_merge "$msgnum" 122 continue_merge 123 done 124 finish_rb_merge 125 return 126 ;; 127skip) 128 read_state 129 git rerere clear 130 msgnum=$(($msgnum + 1)) 131 while test "$msgnum" -le "$end" 132 do 133 call_merge "$msgnum" 134 continue_merge 135 done 136 finish_rb_merge 137 return 138 ;; 139esac 140 141mkdir -p "$state_dir" 142echo "$onto_name" > "$state_dir/onto_name" 143write_basic_state 144 145msgnum=0 146for cmt in `git rev-list --reverse --no-merges "$revisions"` 147do 148 msgnum=$(($msgnum + 1)) 149 echo "$cmt" > "$state_dir/cmt.$msgnum" 150done 151 152echo 1 >"$state_dir/msgnum" 153echo $msgnum >"$state_dir/end" 154 155end=$msgnum 156msgnum=1 157 158while test "$msgnum" -le "$end" 159do 160 call_merge "$msgnum" 161 continue_merge 162done 163 164finish_rb_merge 165 166} 167# ... and then we call the whole thing. 168git_rebase__merge