threads / discuss / 26986

How to split a big commit

Subject: How to split a big commit

## tl;dr

6 messages between Apr 4, 2011 and Apr 5, 2011.

replies: 5people: 4as markdown or json

Nguyen Thai Ngoc Duy· Apr 4, 2011, 11:52 UTC · lore

After a lot of small commits and a few mixed up large commits, it was too messy that I merged them all into one big commit then started spliting it into smaller, reasonable patches. Just wonder if anybody else faces the same thing and how they deal with it. I used "git reset --soft <big commit>^" and "git add -N" because there were new files, but it was clumsy.

-- 
Duy
Ramkumar Ramachandra· Apr 4, 2011, 13:00 UTC · re: Nguyen Thai Ngoc Duy · lore

Re: How to split a big commit

Hi Nguyen,
Nguyen Thai Ngoc Duy writes:
Show 6 quoted lines
> After a lot of small commits and a few mixed up large commits, it was
> too messy that I merged them all into one big commit then started
> spliting it into smaller, reasonable patches. Just wonder if anybody
> else faces the same thing and how they deal with it. I used "git reset
> --soft <big commit>^" and "git add -N" because there were new files,
> but it was clumsy.

To split a big commit, I simply reverse-diff-apply the changes that I don't want in the big commit, and I stage all changes. Then, I again reverse-diff-apply all the staged changes, and keep that in the unstaged portion. Your repository should look like this now:

commit bigcommit
diff --git a/bigfile b/bigfile
+Desirable change
+Undesirable change

Staged changes:
diff --git a/bigfile b/bigfile
-Undesirable change

Unstaged changes:
diff --git a/bigfile b/bigfile
+Undesirable change

Now simply 'commit --amend' to remove the undesirable change from the
bigcommit, and commit the unstaged changes to produce a new
commit. Final result:

commit bigcommit
diff --git a/bigfile b/bigfile
+Desirable change

commit newcommit
diff --git a/bigfile b/bigfile
+Undesirable change

I can afford to do this kind of jugglery very easily because I use
Magit with Emacs.  After highlighting the relevant portions,
reverse-diff-apply is one keystroke :) But yes, you're probably right-
there should be an easier way to do this.  Maybe a 'git split' that
allows you to interactively select the portions of an existing commit
that you'd like to exclude from the commit and turn into a new commit?

Hope that helps.

-- Ram
Nguyen Thai Ngoc Duy· Apr 4, 2011, 14:25 UTC · re: Ramkumar Ramachandra · lore

Re: How to split a big commit

On Mon, Apr 4, 2011 at 8:00 PM, Ramkumar Ramachandra <artagnon@gmail.com> wrote:
> To split a big commit, I simply reverse-diff-apply the changes that I
> don't want in the big commit, and I stage all changes.  Then, I again
> reverse-diff-apply all the staged changes, and keep that in the
> unstaged portion.
Won't work for me. The reverse part would be way larger than the to-commit part.
> ...
> I can afford to do this kind of jugglery very easily because I use
> Magit with Emacs.  After highlighting the relevant portions,
> reverse-diff-apply is one keystroke :)

Hmm.. interesting. Never got around to actually use magit. I may have a good reason now.

> But yes, you're probably right-
> there should be an easier way to do this.  Maybe a 'git split' that
> allows you to interactively select the portions of an existing commit
> that you'd like to exclude from the commit and turn into a new commit?

Hmm..yeah something like grep for chunks, then automatically splitting those chunks out would be nice.

I have another use for such a tool too. When .po files are automatically updated by intltool (gnome translation helper tool), comment lines are all changed because they contain source line and those line likely change. With this tool I can filter out comment-only changes.

Thanks for the idea.
-- 
Duy
Jonathan Nieder· Apr 5, 2011, 00:08 UTC · re: Nguyen Thai Ngoc Duy · lore

Re: How to split a big commit

Hi Duy,
Nguyen Thai Ngoc Duy wrote:
Show 6 quoted lines
> After a lot of small commits and a few mixed up large commits, it was
> too messy that I merged them all into one big commit then started
> spliting it into smaller, reasonable patches. Just wonder if anybody
> else faces the same thing and how they deal with it. I used "git reset
> --soft <big commit>^" and "git add -N" because there were new files,
> but it was clumsy.

I tend to do "git reset HEAD^ -- ." and then "git add -N ." and "git add -p", for what it's worth.

Lasse Makholm· Apr 5, 2011, 02:31 UTC · re: Jonathan Nieder · lore

Re: How to split a big commit

On 5 April 2011 02:08, Jonathan Nieder <jrnieder@gmail.com> wrote:
Show 13 quoted lines
> Hi Duy,
>
> Nguyen Thai Ngoc Duy wrote:
>
>> After a lot of small commits and a few mixed up large commits, it was
>> too messy that I merged them all into one big commit then started
>> spliting it into smaller, reasonable patches. Just wonder if anybody
>> else faces the same thing and how they deal with it. I used "git reset
>> --soft <big commit>^" and "git add -N" because there were new files,
>> but it was clumsy.
>
> I tend to do "git reset HEAD^ -- ." and then "git add -N ." and
> "git add -p", for what it's worth.

In addition, after you've added some hunks, use git stash to stow away all the other changes to test each new commit seperately.

/Lasse
Nguyen Thai Ngoc Duy· Apr 5, 2011, 02:52 UTC · re: Jonathan Nieder · lore

Re: How to split a big commit

On Tue, Apr 5, 2011 at 7:08 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:
Show 13 quoted lines
> Hi Duy,
>
> Nguyen Thai Ngoc Duy wrote:
>
>> After a lot of small commits and a few mixed up large commits, it was
>> too messy that I merged them all into one big commit then started
>> spliting it into smaller, reasonable patches. Just wonder if anybody
>> else faces the same thing and how they deal with it. I used "git reset
>> --soft <big commit>^" and "git add -N" because there were new files,
>> but it was clumsy.
>
> I tend to do "git reset HEAD^ -- ." and then "git add -N ." and
> "git add -p", for what it's worth.
But you would need to undo "git add -N" for those files you don't want in yet?
-- 
Duy

← back to recent threads