git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Boaz Harrosh <bharrosh@panasas.com>
To: Paolo Ciarrocchi <paolo.ciarrocchi@gmail.com>
Cc: Junio C Hamano <gitster@pobox.com>,
	git mailing list <git@vger.kernel.org>
Subject: Re: How to split a patch
Date: Mon, 28 Jan 2008 12:37:59 +0200	[thread overview]
Message-ID: <479DB087.30405@panasas.com> (raw)
In-Reply-To: <4d8e3fd30801280132k59676921h272addab6cac6899@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2039 bytes --]

On Mon, Jan 28 2008 at 11:32 +0200, "Paolo Ciarrocchi" <paolo.ciarrocchi@gmail.com> wrote:
> On Jan 28, 2008 10:25 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> "Paolo Ciarrocchi" <paolo.ciarrocchi@gmail.com> writes:
>>
>>> I know ho to do the opposite process, rebase -i and squash is something
>>> I'm really used to do but this time that trick is not going to help me.
>>>
>>> What is the preferred way to split a big patch in a series of
>>> smaller patches?
>>
>> I personally found the procedure described there a bit on the
>> sketchy side, but does "SPLITTING COMMITS" section of git-rebase
>> manual help?
> 
> Yes it helps but I still wonder whether thereis a "simpler" way to achive that.
> Is it possible to split a patch selecting the hunk in git gui or any
> other graphical
> tool?
> 
> That would be a good starting point for a newbie (like me).
> 
> Thanks!
> 
> Ciao,
What I do is edit the patch, let me explain.
- I create a new branch based at the base of the big patch. Now
  I have the original branch for reference. Lets say the original
  branch is called ALL, and this new branch SPLIT. and BASE is the base.
- # git-checkout -b SPLIT BASE
- # git-diff -R ALL >edit-the-patch-001.patch
- now I open the patch file with an editor. I use kwrite because of
  the good color highlighting.
- I remove all the hunks that I don't need, and am left with only the
  parts that I want to be in the first patch.
- I save the patch.
- If at the edit stage I have changed a big hunk and only used part
  of it I need to run fixpatch script attached below. If I only removed
  complete hunks then I'm good to go.
- I now use:
  # patch -p 1 < edit-the-patch-001.patch
- # git-commit -a
- and git-commit --amend until the first patch is good
- now do the 
  # git-diff -R ALL >edit-the-patch-002.patch
  and so on until there is nothing left. It is nice how
  every time it gets smaller and smaller.

[fixpatch command line]
usage: fixpatch inputfile outputfile
what I do is just
# fixpatch edit-the-patch-001.patch{,}

Boaz


[-- Attachment #2: fixpatch --]
[-- Type: text/plain, Size: 2455 bytes --]

#!/bin/sh

src="$1"
dest="$2"
tmp=/tmp/`basename $0`.tmp.$$

if [ -z "$dest" ]; then
	dest="/dev/fd/1"
elif [ "$src" == "$dest" ]; then
	cp "$src" "$src.orig" || exit 1
fi

awk '
function dump_hunk()
{
	if (!hunk) {
		return;
	}

	if (!hsrc_line)
		foffset = 1;

#	if (hsuffix !~ /\n$/) {
#		hsuffix = hsuffix "\n";
#	}
	printf("@@ -%d,%d +%d,%d %s\n", -hsrc_line, hsrc_count,
		-hsrc_line + foffset, hdest_count, hsuffix);

	if (hunchanged + hdel + hadd != hlines) {
		fflush();
		printf("%s %d: Warning: Unchanged %d deleted %d added %d != lines %d\n",
			FILENAME, FNR, hunchanged, hdel, hadd, hlines) > "/dev/stderr";
	}

	if (hunchanged + hdel != hsrc_count) {
		fflush();
		printf("%s %d: Warning: Unchanged %d deleted %d != hsrc_count %d\n",
			FILENAME, FNR, hunchanged, hdel, hsrc_count) > "/dev/stderr";
	}

	if (hunchanged + hadd != hdest_count) {
		fflush();
		printf("%s %d: Warning: Unchanged %d added %d != hdest_count %d\n",
			FILENAME, FNR, hunchanged, hadd, hdest_count) > "/dev/stderr";
	}

	for (i = 0; i < hlines; i++) {
		print hline[i];
		delete hline[i];
	}

	foffset += hdest_count - hsrc_count;
	hsrc_line = 0;
	hsrc_count = 0;
	hdest_line = 0;
	hdest_count = 0;
	hsuffix = "";

	hunchanged = hadd = hdel = 0;
	hlines = 0;
	hunk = 0;
}

/^(diff|====)/ {
	dump_hunk();
	print;
	foffset = 0;
	next;
}

/^@@/ {
	dump_hunk();
	n = split($2, a, /,/);
	hsrc_line = a[1]+0;
	hsrc_oldcount = a[2]+0;
	hsrc_count = 0;
	if (n != 2 || hsrc_line > 0 || hsrc_oldcount < 0) {
		fflush();
		printf("%s %d: Error: Corrupt hunk header (n %d hsrc_line %d hsrc_oldcount %d)\n",
			FILENAME, FNR, n, hsrc_line, hsrc_count) > "/dev/stderr";
	}

	n = split($3, a, /,/);
	hdest_line = a[1]+0;
	hdest_oldcount = a[2]+0;
	hdest_count = 0;
	if (n != 2 || hdest_line < 0 || hdest_oldcount < 0) {
		fflush();
		printf("%s %d: Error: Corrupt hunk header (hdest_line %d hdest_oldcount %d)\n",
			FILENAME, FNR, hdest_line, hdest_oldcount) > "/dev/stderr";
	}

	hsuffix = $0;
	sub(/^@@.*@@/, "@@", hsuffix);

	hlines = 0;
	hunk = 1;
	next;
}

(!hunk) || /^#/ {
	print;
	next;
}

/^-/ {
	hdel++;
	hsrc_count++;
}

/^+/ {
	hadd++;
	hdest_count++;
}

/^ / {
	hunchanged++;
	hsrc_count++;
	hdest_count++;
}

/^$/ || /^[^-+ ]/ {
	fflush();
	printf("%s %d: Warning: badly formatted line\n",
		FILENAME, FNR) > "/dev/stderr";
	exit(255);
##	hadd++;
##	hdest_count++;
#	next;
}

{
	hline[hlines++] = $0;
}

END {
	dump_hunk()
}
' "$src" > "$tmp" && mv "$tmp" "$dest"

      parent reply	other threads:[~2008-01-28 10:38 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-28  9:05 How to split a patch Paolo Ciarrocchi
2008-01-28  9:25 ` Junio C Hamano
2008-01-28  9:32   ` Paolo Ciarrocchi
2008-01-28  9:47     ` Matthieu Moy
2008-01-28 10:27       ` Junio C Hamano
2008-01-28 10:40         ` Junio C Hamano
2008-01-28 10:49           ` Mike Hommey
2008-01-28 10:44         ` Wincent Colaiuta
2008-01-28 12:47         ` Johannes Schindelin
2008-01-28 10:27       ` Wincent Colaiuta
2008-01-28 10:37     ` Boaz Harrosh [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=479DB087.30405@panasas.com \
    --to=bharrosh@panasas.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=paolo.ciarrocchi@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).