Skip to content

Commit 7557b34

Browse files
committed
Merge branch 'gb/am-foreign'
* gb/am-foreign: git-am: refactor 'cleaning up and aborting' git-am foreign patch support: StGIT support git-am foreign patch support: autodetect some patch formats git-am foreign patch support: introduce patch_format
2 parents e526692 + 0cd29a0 commit 7557b34

File tree

1 file changed

+127
-4
lines changed

1 file changed

+127
-4
lines changed

git-am.sh

Lines changed: 127 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ whitespace= pass it through git-apply
1919
directory= pass it through git-apply
2020
C= pass it through git-apply
2121
p= pass it through git-apply
22+
patch-format= format the patch(es) are in
2223
reject pass it through git-apply
2324
resolvemsg= override error message when patch failure occurs
2425
r,resolved to be used after a patch failure
@@ -138,6 +139,126 @@ It does not apply to blobs recorded in its index."
138139
unset GITHEAD_$his_tree
139140
}
140141

142+
clean_abort () {
143+
test $# = 0 || echo >&2 "$@"
144+
rm -fr "$dotest"
145+
exit 1
146+
}
147+
148+
patch_format=
149+
150+
check_patch_format () {
151+
# early return if patch_format was set from the command line
152+
if test -n "$patch_format"
153+
then
154+
return 0
155+
fi
156+
157+
# we default to mbox format if input is from stdin and for
158+
# directories
159+
if test $# = 0 || test "x$1" = "x-" || test -d "$1"
160+
then
161+
patch_format=mbox
162+
return 0
163+
fi
164+
165+
# otherwise, check the first few lines of the first patch to try
166+
# to detect its format
167+
{
168+
read l1
169+
read l2
170+
read l3
171+
case "$l1" in
172+
"From "* | "From: "*)
173+
patch_format=mbox
174+
;;
175+
'# This series applies on GIT commit'*)
176+
patch_format=stgit-series
177+
;;
178+
"# HG changeset patch")
179+
patch_format=hg
180+
;;
181+
*)
182+
# if the second line is empty and the third is
183+
# a From, Author or Date entry, this is very
184+
# likely an StGIT patch
185+
case "$l2,$l3" in
186+
,"From: "* | ,"Author: "* | ,"Date: "*)
187+
patch_format=stgit
188+
;;
189+
*)
190+
;;
191+
esac
192+
;;
193+
esac
194+
} < "$1" || clean_abort
195+
}
196+
197+
split_patches () {
198+
case "$patch_format" in
199+
mbox)
200+
git mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" ||
201+
clean_abort
202+
;;
203+
stgit-series)
204+
if test $# -ne 1
205+
then
206+
clean_abort "Only one StGIT patch series can be applied at once"
207+
fi
208+
series_dir=`dirname "$1"`
209+
series_file="$1"
210+
shift
211+
{
212+
set x
213+
while read filename
214+
do
215+
set "$@" "$series_dir/$filename"
216+
done
217+
# remove the safety x
218+
shift
219+
# remove the arg coming from the first-line comment
220+
shift
221+
} < "$series_file" || clean_abort
222+
# set the patch format appropriately
223+
patch_format=stgit
224+
# now handle the actual StGIT patches
225+
split_patches "$@"
226+
;;
227+
stgit)
228+
this=0
229+
for stgit in "$@"
230+
do
231+
this=`expr "$this" + 1`
232+
msgnum=`printf "%0${prec}d" $this`
233+
# Perl version of StGIT parse_patch. The first nonemptyline
234+
# not starting with Author, From or Date is the
235+
# subject, and the body starts with the next nonempty
236+
# line not starting with Author, From or Date
237+
perl -ne 'BEGIN { $subject = 0 }
238+
if ($subject > 1) { print ; }
239+
elsif (/^\s+$/) { next ; }
240+
elsif (/^Author:/) { print s/Author/From/ ; }
241+
elsif (/^(From|Date)/) { print ; }
242+
elsif ($subject) {
243+
$subject = 2 ;
244+
print "\n" ;
245+
print ;
246+
} else {
247+
print "Subject: ", $_ ;
248+
$subject = 1;
249+
}
250+
' < "$stgit" > "$dotest/$msgnum" || clean_abort
251+
done
252+
echo "$this" > "$dotest/last"
253+
this=
254+
msgnum=
255+
;;
256+
*)
257+
clean_abort "Patch format $patch_format is not supported."
258+
;;
259+
esac
260+
}
261+
141262
prec=4
142263
dotest="$GIT_DIR/rebase-apply"
143264
sign= utf8=t keep= skip= interactive= resolved= rebasing= abort=
@@ -180,6 +301,8 @@ do
180301
git_apply_opt="$git_apply_opt $(sq "$1=$2")"; shift ;;
181302
-C|-p)
182303
git_apply_opt="$git_apply_opt $(sq "$1$2")"; shift ;;
304+
--patch-format)
305+
shift ; patch_format="$1" ;;
183306
--reject)
184307
git_apply_opt="$git_apply_opt $1" ;;
185308
--committer-date-is-author-date)
@@ -281,10 +404,10 @@ else
281404
done
282405
shift
283406
fi
284-
git mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" || {
285-
rm -fr "$dotest"
286-
exit 1
287-
}
407+
408+
check_patch_format "$@"
409+
410+
split_patches "$@"
288411

289412
# -s, -u, -k, --whitespace, -3, -C, -q and -p flags are kept
290413
# for the resuming session after a patch failure.

0 commit comments

Comments
 (0)