What's cooking (2013/04 #05)
[git.git] / Reintegrate
blobda69ce5a0292b9027ea0c95a0a5cd149de257d1c
1 #!/bin/sh
3 accept_rerere="--rerere-autoupdate" generate=no update= diff= edit= stop_at_cut=
4 while case "$#,$1" in 0,*) break;; *,-*) ;; esac
5 do
6 case "$1" in
7 -n) accept_rerere= ;;
8 -e) edit=t ;;
9 -c) stop_at_cut=1 ;;
10 -c?*) stop_at_cut=${1#-c} ;;
11 -d) update=${2?"diff with what?"}
12 diff=yes
13 generate=yes
14 shift ;;
15 -u) update=${2?"update what?"}
16 generate=yes
17 shift ;;
18 *) generate=yes
19 break ;;
20 esac
21 shift
22 done
24 annotate_merge () {
25 test -f Meta/whats-cooking.txt || return 0
27 perl -e '
28 my ($branch) = $ARGV[0];
29 my ($in_section, $in_desc);
30 my @msg = ();
31 while (<STDIN>) {
32 chomp;
33 if (/^\* $branch /) {
34 $in_section = 1;
35 next;
37 last if (/^[-*\[]/ && $in_section);
38 next unless $in_section;
39 s/^\s+//;
40 if (/^$/) {
41 $in_desc = 1;
43 next unless ($in_section && $in_desc);
44 push @msg, "$_\n";
47 if ($in_section && @msg) {
48 open(my $fh, "-|", qw(git cat-file commit HEAD));
49 my @original = (<$fh>);
50 my @final;
51 $in_section = 0;
52 for (@original) {
53 if (!$in_section) {
54 $in_section = 1 if (/^$/);
55 next;
57 push @final, $_;
58 if (/^$/ && $in_section == 1) {
59 push @final, @msg;
60 push @final, "\n";
61 $in_section = 2;
64 close $fh;
65 open($fh, "|-", qw(git commit --amend -F -));
66 print $fh @final;
67 close $fh;
69 ' <Meta/whats-cooking.txt "$1"
72 case "$generate" in
73 no)
74 accept_rerere () {
75 if ! git write-tree 2>/dev/null >/dev/null
76 then
77 git rerere remaining
78 return 1
79 else
80 EDITOR=: git commit --no-verify
81 echo "Accepted previous resolution"
82 return 0
86 mark_cut () {
87 test -n "$stop_at_cut" && return
89 count_since_last_cut=$(( $count_since_last_cut + 1 ))
90 test -z "$prev_cut" && return
91 git commit --allow-empty -m "$prev_cut"
92 prev_cut=
95 cut_seen=0 prev_cut= count_since_last_cut=0
96 while read branch eh
98 case "$branch" in '###') cut_seen=$(( $cut_seen + 1 )) ;; esac
99 if test -n "$stop_at_cut" && test $stop_at_cut -le $cut_seen
100 then
101 continue ;# slurp the remainder and skip
104 case "$branch" in
105 '###')
106 if test "$count_since_last_cut" = 0
107 then
108 prev_cut=
109 else
110 echo >&2 "$branch $eh"
111 prev_cut="$branch $eh"
112 count_since_last_cut=0
114 continue ;;
115 '#'* | '')
116 continue ;;
117 esac
119 case "$eh" in
120 "" | "#"*)
121 echo >&2 "* $branch"
123 save=$(git rev-parse --verify HEAD)
124 tip=$(git rev-parse --verify "$branch^0")
125 mb=$(git merge-base "$tip" "$save")
126 test "$mb" = "$tip" && continue
128 mark_cut
130 EDITOR=: git merge $accept_rerere --edit "$branch" ||
131 accept_rerere ||
132 exit
134 annotate_merge "$branch" || exit
135 test -z "$edit" ||
136 git commit --amend || exit
138 this=$(git rev-parse --verify HEAD)
139 if test "$this" = "$save"
140 then
142 elif git show-ref -q --verify "refs/merge-fix/$branch"
143 then
144 echo >&2 "Fixing up the merge"
145 git cherry-pick --no-commit "refs/merge-fix/$branch" &&
146 EDITOR=: git commit --amend -a || exit
149 pick" "*)
150 echo >&2 "* $eh"
152 mark_cut
154 git cherry-pick "$branch" || exit ;;
155 *) echo >&2 "Eh? $branch $eh"; exit ;;
156 esac
157 done
158 exit
159 esac
161 if test -n "$update" && test $# = 0
162 then
163 set x $(sed -n -e '2s/^# //p' <"$update") &&
164 shift
167 # Generation (or updating)
169 x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
170 x40="$x40$x40$x40$x40$x40$x40$x40$x40"
171 LF='
174 show_merge () {
175 case "$msg" in
176 "Merge branch '"*"'"*)
177 branch=$(expr "$msg" : "Merge branch '\(.*\)'")
178 merge_hier=heads/
180 "Merge remote branch '"*"'"*)
181 branch=$(expr "$msg" : "Merge remote branch '\(.*\)'")
182 merge_hier=
185 echo 2>&1 "Huh?: $msg"
186 return
188 esac &&
189 tip=$(git rev-parse --verify "refs/$merge_hier$branch" 2>/dev/null) &&
190 merged=$(git name-rev --refs="refs/$merge_hier$branch" "$other" 2>/dev/null) &&
191 merged=$(expr "$merged" : "$x40 \(.*\)") &&
192 test "$merged" != undefined || {
193 other=$(git log -1 --pretty='format:%s' $other) &&
194 merged="$branch :rebased? $other"
198 show_pick () {
199 case "$msg" in
200 "### "* | "###")
201 merged="$msg"
204 merged="$(git rev-parse --verify "$commit") pick $msg"
206 esac
210 generate () {
211 PROGRAM=$1
212 shift
213 echo '#!/bin/sh'
214 echo "# $1"
215 echo 'case "$#,$1" in'
216 echo '1,-u|1,-d)'
217 echo " exec $PROGRAM" '"$1" "$0"'
218 echo 'esac'
219 echo "$PROGRAM" '"$@" <<\EOF'
220 git log --no-decorate --pretty=oneline --first-parent "$1" |
222 series=
223 while read commit msg
225 if other=$(git rev-parse -q --verify "$commit^2")
226 then
227 show_merge
228 else
229 show_pick
232 if test -z "$series"
233 then
234 series="$merged"
235 else
236 series="$merged$LF$series"
238 done
239 echo "$series"
241 echo EOF
244 if test -z "$update"
245 then
246 generate "$0" "$@"
247 elif test -z "$diff"
248 then
249 generate "$0" "$@" | diff -u "$update" -
250 if test $? = 0
251 then
252 echo >&2 "No changes."
253 else
254 echo >&2 -n "Update [y/N]? "
255 read yesno
256 case "$yesno" in
257 [Yy]*)
258 generate "$0" "$@" |
259 sed -e 's/ :rebased?.*//' >"$update" ;;
261 echo >&2 "No update then." ;;
262 esac
264 else
265 generate "$0" "$@" | diff -u "$update" -