]> git.ipfire.org Git - thirdparty/git.git/blob - Reintegrate
Meta/Reintegrate: allow each step to be optionally amended
[thirdparty/git.git] / Reintegrate
1 #!/bin/sh
2
3 accept_rerere="--rerere-autoupdate" generate=no update= diff= edit=
4 while case "$#,$1" in 0,*) break;; *,-*) ;; esac
5 do
6 case "$1" in
7 -n) accept_rerere= ;;
8 -e) edit=t ;;
9 -d) update=${2?"diff with what?"}
10 diff=yes
11 generate=yes
12 shift ;;
13 -u) update=${2?"update what?"}
14 generate=yes
15 shift ;;
16 *) generate=yes
17 break ;;
18 esac
19 shift
20 done
21
22 annotate_merge () {
23 test -f Meta/whats-cooking.txt || return 0
24
25 perl -e '
26 my ($branch) = $ARGV[0];
27 my ($in_section) = 0;
28 my @msg = ();
29 while (<STDIN>) {
30 if (/^\* $branch /) {
31 $in_section = 1;
32 next;
33 }
34 if (/^[-*\[]/) {
35 last if $in_section;
36 }
37 next unless $in_section;
38 next if (/^ /);
39 push @msg, $_;
40 }
41
42 if ($in_section && @msg) {
43 open(my $fh, "-|", qw(git cat-file commit HEAD));
44 my @original = (<$fh>);
45 my @final;
46 $in_section = 0;
47 for (@original) {
48 if (!$in_section) {
49 $in_section = 1 if (/^$/);
50 next;
51 }
52 push @final, $_;
53 if (/^$/ && $in_section == 1) {
54 push @final, @msg;
55 push @final, "\n";
56 $in_section = 2;
57 }
58 }
59 close $fh;
60 open($fh, "|-", qw(git commit --amend -F -));
61 print $fh @final;
62 close $fh;
63 }
64 ' <Meta/whats-cooking.txt "$1"
65 }
66
67 case "$generate" in
68 no)
69 accept_rerere () {
70 if ! git write-tree 2>/dev/null >/dev/null
71 then
72 git rerere remaining
73 return 1
74 else
75 EDITOR=: git commit --no-verify
76 echo "Accepted previous resolution"
77 return 0
78 fi
79 }
80
81 while read branch eh
82 do
83 case "$branch" in '#'* | '') continue ;; esac
84 case "$eh" in
85 "" | "#"*)
86 echo >&2 "* $branch"
87
88 save=$(git rev-parse --verify HEAD)
89 tip=$(git rev-parse --verify "$branch^0")
90 mb=$(git merge-base "$tip" "$save")
91 test "$mb" = "$tip" && continue
92
93 git merge $accept_rerere --no-edit "$branch" ||
94 accept_rerere ||
95 exit
96
97 annotate_merge "$branch" || exit
98 test -z "$edit" ||
99 git commit --amend || exit
100
101 this=$(git rev-parse --verify HEAD)
102 if test "$this" = "$save"
103 then
104 :
105 elif git show-ref -q --verify "refs/merge-fix/$branch"
106 then
107 echo >&2 "Fixing up the merge"
108 git cherry-pick --no-commit "refs/merge-fix/$branch" &&
109 EDITOR=: git commit --amend -a || exit
110 fi
111 ;;
112 pick" "*)
113 echo >&2 "* $eh"
114 git cherry-pick "$branch" || exit ;;
115 *) echo >&2 "Eh? $branch $eh"; exit ;;
116 esac
117 done
118 exit
119 esac
120
121 if test -n "$update" && test $# = 0
122 then
123 set x $(sed -n -e '2s/^# //p' <"$update") &&
124 shift
125 fi
126
127 # Generation (or updating)
128
129 x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
130 x40="$x40$x40$x40$x40$x40$x40$x40$x40"
131 LF='
132 '
133
134 show_merge () {
135 case "$msg" in
136 "Merge branch '"*"'"*)
137 branch=$(expr "$msg" : "Merge branch '\(.*\)'")
138 merge_hier=heads/
139 ;;
140 "Merge remote branch '"*"'"*)
141 branch=$(expr "$msg" : "Merge remote branch '\(.*\)'")
142 merge_hier=
143 ;;
144 *)
145 echo 2>&1 "Huh?: $msg"
146 return
147 ;;
148 esac &&
149 tip=$(git rev-parse --verify "refs/$merge_hier$branch" 2>/dev/null) &&
150 merged=$(git name-rev --refs="refs/$merge_hier$branch" "$other" 2>/dev/null) &&
151 merged=$(expr "$merged" : "$x40 \(.*\)") &&
152 test "$merged" != undefined || {
153 other=$(git log -1 --pretty='format:%s' $other) &&
154 merged="$branch :rebased? $other"
155 }
156 }
157
158 show_pick () {
159 merged="$(git rev-parse --verify "$commit") pick $msg"
160 }
161
162 generate () {
163 PROGRAM=$1
164 shift
165 echo '#!/bin/sh'
166 echo "# $1"
167 echo 'case "$#,$1" in'
168 echo '1,-u|1,-d)'
169 echo " exec $PROGRAM" '"$1" "$0"'
170 echo 'esac'
171 echo "$PROGRAM" '"$@" <<\EOF'
172 git log --pretty=oneline --first-parent "$1" |
173 {
174 series=
175 while read commit msg
176 do
177 if other=$(git rev-parse -q --verify "$commit^2")
178 then
179 show_merge
180 else
181 show_pick
182 fi
183
184 if test -z "$series"
185 then
186 series="$merged"
187 else
188 series="$merged$LF$series"
189 fi
190 done
191 echo "$series"
192 }
193 echo EOF
194 }
195
196 if test -z "$update"
197 then
198 generate "$0" "$@"
199 elif test -z "$diff"
200 then
201 generate "$0" "$@" | diff -u "$update" -
202 if test $? = 0
203 then
204 echo >&2 "No changes."
205 else
206 echo >&2 -n "Update [y/N]? "
207 read yesno
208 case "$yesno" in
209 [Yy]*)
210 generate "$0" "$@" |
211 sed -e 's/ :rebased?.*//' >"$update" ;;
212 *)
213 echo >&2 "No update then." ;;
214 esac
215 fi
216 else
217 generate "$0" "$@" | diff -u "$update" -
218 fi