I've taken a look at these previous questions already:
They don't exactly address a particular issue though - there are other changes in the index! When running the rebase
command, git complains: Cannot rebase: You have unstaged changes.
The commit previous to the last one (do I refer to that as "2 HEADs ago"?) was a refactor commit. I currently have in the index many unstaged changes, but only some of which I want to add to the previous to last commit.
I'm imagining the way to do this would be to:
stash
all of my current changesrebase -i
to the previous to last commit (changing index and moving Head, right?)add -p
and commit --amend
to selectively modify this old commitrebase --continue
to finish (updates children, moves Head back to where I started, what happens to index?)Is this correct? If it is, how do I do step 3? If it isn't, what should I be doing instead?
Also, note that I'm still learning about git and am still not 100% sure I'm referencing things in git (Head, index, stash, etc) properly.
For anyone else this may help, these are the steps I actually took:
git stash
all of my current changesgit rebase -i <ID>
to the parent of the previous to last commit, changing index and moving Headgit stash apply
load the stash into my index without changing Head
git reset HEAD <file>
to unload files staging. Make sure staging is clear.add -p
and commit --amend
to selectively stage changes and commit themgit reset --hard
to discard index so it matches Headgit rebase --continue
to finish. updates children, moves Head back to very start, but with changes
With git1.8.4 (July 2013), you can choose to:
"
git rebase
" learned "--[no-]autostash
" option to save local changes instead of refusing to run (to which people's normal response was to stash them and re-run).
So in your case, this could work (and save your work in progress in the meantime):
git rebase --autostash -i <ID>
See commit 587947750bd73544a6a99811f0ddfd64e1ff1445:
This new feature allows a rebase to be executed on a dirty worktree or index.
It works by creating a temporary "dangling merge commit" out of the worktree and index changes (via 'git stash create'), and automatically applying it after a successful rebase or abort.
rebase
stores the SHA-1 hex of the temporary merge commit, along with the rest of the rebase state, in either.git/{rebase-merge,rebase-apply}/autostash
depending on the kind of rebase.
Since$state_dir
is automatically removed at the end of a successful rebase or abort, so is theautostash
.The advantage of this approach is that we do not affect the normal stash's reflogs, making the
autostash
invisible to the end-user.
This means that you can use 'git stash' during a rebase as usual.When the
autostash
application results in a conflict, we push$state_dir/autostash
onto the normal stash and remove$state_dir
ending the rebase.
The user can inspect the stash, and pop or drop at any time.
Note: git 2.0.1 (Jult 25th, 2014) handle the autostash case.
See commit e4244eb from Ramkumar Ramachandra (artagnon
) (also in his blog):
rebase -i
: handle "Nothing to do" case with autostash
When a user invokes
$ git rebase -i @~3
with dirty files and
rebase.autostash
turned on, and exits the$EDITOR
with an empty buffer, the autostash fails to apply.Although the primary focus of rr/rebase-autostash was to get the
git-rebase--backend.sh
scripts to return control togit-rebase.sh
, it missed this case ingit-rebase--interactive.sh
.
Since this case is unlike the other cases which return control for housekeeping, assign it a special return status and handle that return value explicitly in git-rebase.sh.
git config rebase.autostash true
to make rebase [-i]
work in a dirty worktree.This new feature allows a rebase to be executed on a dirty worktree or index.
It works by creating a temporary "dangling merge commit" out of the worktree and index changes (via 'git stash create
'), and automatically applying it after a successful rebase or abort.rebase stores the SHA-1 hex of the temporary merge commit, along with the rest of the rebase state, in either
.git/{rebase-merge,rebase-apply}/autostash
depending on the kind of rebase. Since$state_dir
is automatically removed at the end of a successful rebase or abort, so is theautostash
.The advantage of this approach is that we do not affect the normal stash's reflogs, making the autostash invisible to the end-user. This means that you can use '
git stash
' during a rebase as usual.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With