Move a hunk of a commit to another commit in a single rebase
git
Solution
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.
Problem
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: - First rebase: split Y commit into Z (`bar`) and Y' (`baz`), the last one using `commit -c Y` to retain the metadata. - 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 ```