# [PATCHv3 (resend) 0/4] git-am foreign patch support

7 messages from 2009-06-01 to 2009-06-02. Participants: Giuseppe Bilotta, Nanako Shiraishi, Junio C Hamano.
Thread: https://gitlist.dev/t/19631

## Giuseppe Bilotta, 2009-06-01 23:10

Subject: [PATCHv3 (resend) 0/4] git-am foreign patch support
Message-ID: <1243897841-8923-1-git-send-email-giuseppe.bilotta@gmail.com>
URL: https://gitlist.dev/e/1243897841-8923-1-git-send-email-giuseppe.bilotta%40gmail.com

```
Junio mentioned that he's ready to apply the series cleanly, so here's
a resend rebased on latest 'next' and without any 'bis' patches ;-)

Giuseppe Bilotta (4):
  git-am foreign patch support: introduce patch_format
  git-am foreign patch support: autodetect some patch formats
  git-am foreign patch support: StGIT support
  git-am: refactor 'cleaning up and aborting'

 git-am.sh |  133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 129 insertions(+), 4 deletions(-)

```

## Giuseppe Bilotta, 2009-06-01 23:10

Subject: [PATCHv3 (resend) 1/4] git-am foreign patch support: introduce patch_format
Message-ID: <1243897841-8923-2-git-send-email-giuseppe.bilotta@gmail.com>
URL: https://gitlist.dev/e/1243897841-8923-2-git-send-email-giuseppe.bilotta%40gmail.com
In-Reply-To: <1243897841-8923-1-git-send-email-giuseppe.bilotta@gmail.com>

```
Set up a framework to allow git-am to support patches which are not in
mailbox format. Introduce a patch_format variable that presently can
only be set from the command line, defaulting to 'mbox' (the only
supported format) if not specified.
---
 git-am.sh |   37 +++++++++++++++++++++++++++++++++----
 1 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/git-am.sh b/git-am.sh
index 578780b..da160de 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -18,6 +18,7 @@ whitespace=     pass it through git-apply
 directory=      pass it through git-apply
 C=              pass it through git-apply
 p=              pass it through git-apply
+patch-format=   format the patch(es) are in
 reject          pass it through git-apply
 resolvemsg=     override error message when patch failure occurs
 r,resolved      to be used after a patch failure
@@ -133,6 +134,32 @@ It does not apply to blobs recorded in its index."
     unset GITHEAD_$his_tree
 }
 
+patch_format=
+
+check_patch_format () {
+	# early return if patch_format was set from the command line
+	if test -n "$patch_format"
+	then
+		return 0
+	fi
+	patch_format=mbox
+}
+
+split_patches () {
+	case "$patch_format" in
+	mbox)
+		git mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" ||  {
+			rm -fr "$dotest"
+			exit 1
+		}
+		;;
+	*)
+		echo "Patch format $patch_format is not supported."
+		exit 1
+		;;
+	esac
+}
+
 prec=4
 dotest="$GIT_DIR/rebase-apply"
 sign= utf8=t keep= skip= interactive= resolved= rebasing= abort=
@@ -175,6 +202,8 @@ do
 		git_apply_opt="$git_apply_opt $(sq "$1=$2")"; shift ;;
 	-C|-p)
 		git_apply_opt="$git_apply_opt $(sq "$1$2")"; shift ;;
+	--patch-format)
+		shift ; patch_format="$1" ;;
 	--reject)
 		git_apply_opt="$git_apply_opt $1" ;;
 	--committer-date-is-author-date)
@@ -274,10 +303,10 @@ else
 		done
 		shift
 	fi
-	git mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" ||  {
-		rm -fr "$dotest"
-		exit 1
-	}
+
+	check_patch_format "$@"
+
+	split_patches "$@"
 
 	# -s, -u, -k, --whitespace, -3, -C and -p flags are kept
 	# for the resuming session after a patch failure.
-- 
1.6.3.1.282.g9f93

```

## Giuseppe Bilotta, 2009-06-01 23:10

Subject: [PATCHv3 (resend) 2/4] git-am foreign patch support: autodetect some patch formats
Message-ID: <1243897841-8923-3-git-send-email-giuseppe.bilotta@gmail.com>
URL: https://gitlist.dev/e/1243897841-8923-3-git-send-email-giuseppe.bilotta%40gmail.com
In-Reply-To: <1243897841-8923-2-git-send-email-giuseppe.bilotta@gmail.com>

```
Default to mbox format if input is from stdin. Otherwise, look at the
first few lines of the first patch to try to guess its format.

Include checks for mailboxes, stgit patch series, stgit single patches
and hg patches.
---
 git-am.sh |   40 +++++++++++++++++++++++++++++++++++++++-
 1 files changed, 39 insertions(+), 1 deletions(-)

diff --git a/git-am.sh b/git-am.sh
index da160de..8519701 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -142,7 +142,45 @@ check_patch_format () {
 	then
 		return 0
 	fi
-	patch_format=mbox
+
+	# we default to mbox format if input is from stdin and for
+	# directories
+	if test $# = 0 || test "x$1" = "x-" || test -d "$1"
+	then
+		patch_format=mbox
+		return 0
+	fi
+
+	# otherwise, check the first few lines of the first patch to try
+	# to detect its format
+	{
+		read l1
+		read l2
+		read l3
+		case "$l1" in
+		"From "*|"From: "*)
+			patch_format=mbox
+			;;
+		'# This series applies on GIT commit'*)
+			patch_format=stgit-series
+			;;
+		"# HG changeset patch")
+			patch_format=hg
+			;;
+		*)
+			# if the second line is empty and the third is
+			# a From, Author or Date entry, this is very
+			# likely an StGIT patch
+			case "$l2,$l3" in
+			,"From: "*|,"Author: "*|,"Date: "*)
+				patch_format=stgit
+				;;
+			*)
+				;;
+			esac
+			;;
+		esac
+	} < "$1"
 }
 
 split_patches () {
-- 
1.6.3.1.282.g9f93

```

## Giuseppe Bilotta, 2009-06-01 23:10

Subject: [PATCHv3 (resend) 3/4] git-am foreign patch support: StGIT support
Message-ID: <1243897841-8923-4-git-send-email-giuseppe.bilotta@gmail.com>
URL: https://gitlist.dev/e/1243897841-8923-4-git-send-email-giuseppe.bilotta%40gmail.com
In-Reply-To: <1243897841-8923-3-git-send-email-giuseppe.bilotta@gmail.com>

```
Support StGIT patches by implementing a simple perl-based converter
mimicking StGIT's own parse_patch. Also support StGIT patch series by
'exploding' the index into a list of files and re-running the mail
splitting with patch_format set to stgit.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---
 git-am.sh |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/git-am.sh b/git-am.sh
index 8519701..d05c9b4 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -191,6 +191,63 @@ split_patches () {
 			exit 1
 		}
 		;;
+	stgit-series)
+		if test $# -ne 1
+		then
+			echo "Only one StGIT patch series can be applied at once"
+			exit 1
+		fi
+		series_dir=`dirname "$1"`
+		series_file="$1"
+		shift
+		{
+			set x
+			while read filename
+			do
+				set "$@" "$series_dir/$filename"
+			done
+			# remove the safety x
+			shift
+			# remove the arg coming from the first-line comment
+			shift
+		} < "$series_file"
+		# set the patch format appropriately
+		patch_format=stgit
+		# now handle the actual StGIT patches
+		split_patches "$@"
+		;;
+	stgit)
+		this=0
+		for stgit in "$@"
+		do
+			this=`expr "$this" + 1`
+			msgnum=`printf "%0${prec}d" $this`
+			# Perl version of StGIT parse_patch. The first nonemptyline
+			# not starting with Author, From or Date is the
+			# subject, and the body starts with the next nonempty
+			# line not starting with Author, From or Date
+			perl -ne 'BEGIN { $subject = 0 }
+				if ($subject > 1) { print ; }
+				elsif (/^\s+$/) { next ; }
+				elsif (/^Author:/) { print s/Author/From/ ; }
+				elsif (/^(From|Date)/) { print ; }
+				elsif ($subject) {
+					$subject = 2 ;
+					print "\n" ;
+					print ;
+				} else {
+					print "Subject: ", $_ ;
+					$subject = 1;
+				}
+			' < "$stgit" > "$dotest/$msgnum" || {
+				echo "Failed to import $patch_format patch $stgit"
+				exit 1
+			}
+		done
+		echo "$this" > "$dotest/last"
+		this=
+		msgnum=
+		;;
 	*)
 		echo "Patch format $patch_format is not supported."
 		exit 1
-- 
1.6.3.1.282.g9f93

```

## Giuseppe Bilotta, 2009-06-01 23:10

Subject: [PATCHv3 (resend) 4/4] git-am: refactor 'cleaning up and aborting'
Message-ID: <1243897841-8923-5-git-send-email-giuseppe.bilotta@gmail.com>
URL: https://gitlist.dev/e/1243897841-8923-5-git-send-email-giuseppe.bilotta%40gmail.com
In-Reply-To: <1243897841-8923-4-git-send-email-giuseppe.bilotta@gmail.com>

```
Introduce a clean_abort function that echoes an optional error message
to standard error, removes the dotest directory and exits with status 1.

Use it when patch format detection or patch splitting fails early.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---
 git-am.sh |   29 +++++++++++++++--------------
 1 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/git-am.sh b/git-am.sh
index d05c9b4..e8b2bc2 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -134,6 +134,15 @@ It does not apply to blobs recorded in its index."
     unset GITHEAD_$his_tree
 }
 
+clean_abort () {
+	if test $# -gt 0
+	then
+		echo "$@" > /dev/stderr
+	fi
+	rm -fr "$dotest"
+	exit 1
+}
+
 patch_format=
 
 check_patch_format () {
@@ -180,22 +189,18 @@ check_patch_format () {
 			esac
 			;;
 		esac
-	} < "$1"
+	} < "$1" || clean_abort
 }
 
 split_patches () {
 	case "$patch_format" in
 	mbox)
-		git mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" ||  {
-			rm -fr "$dotest"
-			exit 1
-		}
+		git mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" || clean_abort
 		;;
 	stgit-series)
 		if test $# -ne 1
 		then
-			echo "Only one StGIT patch series can be applied at once"
-			exit 1
+			clean_abort "Only one StGIT patch series can be applied at once"
 		fi
 		series_dir=`dirname "$1"`
 		series_file="$1"
@@ -210,7 +215,7 @@ split_patches () {
 			shift
 			# remove the arg coming from the first-line comment
 			shift
-		} < "$series_file"
+		} < "$series_file" || clean_abort
 		# set the patch format appropriately
 		patch_format=stgit
 		# now handle the actual StGIT patches
@@ -239,18 +244,14 @@ split_patches () {
 					print "Subject: ", $_ ;
 					$subject = 1;
 				}
-			' < "$stgit" > "$dotest/$msgnum" || {
-				echo "Failed to import $patch_format patch $stgit"
-				exit 1
-			}
+			' < "$stgit" > "$dotest/$msgnum" || clean_abort
 		done
 		echo "$this" > "$dotest/last"
 		this=
 		msgnum=
 		;;
 	*)
-		echo "Patch format $patch_format is not supported."
-		exit 1
+		clean_abort "Patch format $patch_format is not supported."
 		;;
 	esac
 }
-- 
1.6.3.1.282.g9f93

```

## Nanako Shiraishi, 2009-06-02 10:56

Subject: Re: [PATCHv3 (resend) 0/4] git-am foreign patch support
Message-ID: <20090602195608.6117@nanako3.lavabit.com>
URL: https://gitlist.dev/e/20090602195608.6117%40nanako3.lavabit.com
In-Reply-To: <1243897841-8923-1-git-send-email-giuseppe.bilotta@gmail.com>

```
Quoting Giuseppe Bilotta <giuseppe.bilotta@gmail.com>:

> Junio mentioned that he's ready to apply the series cleanly, so here's
> a resend rebased on latest 'next' and without any 'bis' patches ;-)
>
> Giuseppe Bilotta (4):
>   git-am foreign patch support: introduce patch_format
>   git-am foreign patch support: autodetect some patch formats
>   git-am foreign patch support: StGIT support
>   git-am: refactor 'cleaning up and aborting'
>
>  git-am.sh |  133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 129 insertions(+), 4 deletions(-)

May we have a summary of what's updated, compared to the version that has been in the "pu" branch?

-- 
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/

```

## Junio C Hamano, 2009-06-02 15:21

Subject: Re: [PATCHv3 (resend) 0/4] git-am foreign patch support
Message-ID: <7v4ouyhda4.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v4ouyhda4.fsf%40alter.siamese.dyndns.org
In-Reply-To: <20090602195608.6117@nanako3.lavabit.com>

```
Nanako Shiraishi <nanako3@lavabit.com> writes:

> Quoting Giuseppe Bilotta <giuseppe.bilotta@gmail.com>:
>
>> Junio mentioned that he's ready to apply the series cleanly, so here's
>> a resend rebased on latest 'next' and without any 'bis' patches ;-)
>>
>> Giuseppe Bilotta (4):
>>   git-am foreign patch support: introduce patch_format
>>   git-am foreign patch support: autodetect some patch formats
>>   git-am foreign patch support: StGIT support
>>   git-am: refactor 'cleaning up and aborting'
>>
>>  git-am.sh |  133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>>  1 files changed, 129 insertions(+), 4 deletions(-)
>
> May we have a summary of what's updated, compared to the version that has been in the "pu" branch?

A good thing to ask, for two reasons, as (1) Giuseppe might not have known
about what were in 'pu', and (2) I _did_ fix up his earlier series when I
queued, and his "resend" loses them.

I just compared what is in 'pu' with this resend, and the only changes I
saw was my fix-up, so I'll keep the previous ones.

Thanks.

```
