git: Moving partial changes between commits
What’s there
We have two commits. For illustration purposes I’ve trimmed the log output down:
$ git log --stat commit 19c698a9ee91a5f03f1c3240fc957e6b328931f5 WIP: adding tests parts/tests/functional/conftest.py | 4 ++-- parts/tests/functional/test_frobfrob.py | 43 ++++++++++ frobfrob.py | 14 +++++++++++++- commit c7ef6c3014ca9d049dea46fbed44010acf53ae79 prepare frob frob schemas parts/tests/functional/conftest.py | 31 +++++++++++++ frobfrob/models.py | 32 +++++++++++++ commit 5b30d351f51fda40d37d2f7dc25d2367bd37845a [...]
Now I want to move the changes made to conftest.py
from commit c7ef6c3014ca9d049dea46fbed44010acf53ae79
into commit 19c698a9ee91a5f03f1c3240fc957e6b328931f5
(or HEAD).
Pluck out the commit
In order to pluck out the changes to conftest.py
, we’ll reset the file against the previous commit 5b30d351f51fda40d37d2f7dc25d2367bd37845a
(you could also use HEAD~3).
$ git reset 5b30d351f51fda40d37d2f7dc25d2367bd37845a parts/tests/functional/conftest.py Unstaged changes after reset: M parts/tests/functional/conftest.py $ git status -s MM parts/tests/functional/conftest.py
As you can see, we will have staged changes and unstaged changes. The staged changes remove the additions to the conftest.py
file and the unstaged changes add our code to conftest.py
Remove and Add
We now create two commits:-
Use the staged changes for a new commit which we’ll squash with
c7ef6c3014ca9d049dea46fbed44010acf53ae79
. -
Stage the unstaged changes and create another commit which we’ll squash with
19c698a9ee91a5f03f1c3240fc957e6b328931f5
orHEAD
.
# 1. commit Message is something like: squash: removes changes to conftest.py $ git commit # 2. commit # stage changes $ git add -p # commit, message will be something like: squash: adds changes to conftest.py $ git commit # we end up with two additional commits $ git log --oneline 492ff22 Adds changes to conftest 8485946 removes conftest files 19c698a WIP: adding tests c7ef6c3 prepare frob frob schemas
Interactive rebase put’s it all together
Now use an interactive rebase to squash the changes with the right commits:$ git rebase -i HEAD~5