Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move a hunk of a commit to another commit in a single rebase

Tags:

git

Using GIT, I'd like to move a hunk of a commit to a different one, while automatically retaining commit metadata, using a single interactive rebase.

For example, having these 2 commits:

first commit X:

  context
+ foo
  context

second commit Y:

  context
+ bar
  context
+ baz
  context

I would like to move the bar hunk from commit Y into the previous commit X, without having to manually reset author, committer, log, etc.

The simplest way I can think of requires 2 interactive rebases:

  1. First rebase: split Y commit into Z (bar) and Y' (baz), the last one using commit -c Y to retain the metadata.
  2. Second rebase: squash X and Z together into X', and leave Y' as is.

Which would leave this result: first commit X' (same metadata as X):

  context
+ foo
  context
+ bar
  context

second commit Y' (same metadata as Y):

  context
+ baz
  context
like image 912
STenyaK Avatar asked May 14 '14 07:05

STenyaK


1 Answers

I'm pretty sure they're both on the same branch. Use git diff, git apply and git add --patch.

git rebase -i $theolderofthetwo^ branch-with-X-and-Y

(edit: had ghastly error in the above, it actually does what it's supposed to now).

Mark the X commit for edit. If the Y commit is older, mark it for edit.

If the Y commit is older,

git diff HEAD HEAD^ -- foobarbaz | git apply
git add --patch
git checkout -- foobarbaz
git commit --amend; git rebase --continue

In the X commit (wherever it is):

git diff Y^! -- foobarbaz  | git apply
git add --patch
git checkout -- foobarbaz
git commit --amend; git rebase --continue

If the Y commit is newer, by the time rebase reaches it that hunk is already in X' no edit is necessary, Y' won't have that hunk -- or rather, it will have that hunk, it just won't be a diff.edit


The author name and date get preserved anyway.

like image 93
jthill Avatar answered Sep 23 '22 12:09

jthill