I have two consequential commits, somewhere in the local history, and one file was mistakenly added into the second. I want to fix the situation.
I do not understand how should I use the interactive rebase. I did git rebase -i HEAD~10
and choosen to edit the commit with file in order to check it out from there. I use git guit but, see no files in the commit area. I can choose to amend the previous commit then I see the files. But, I cannot add the misplaced file to that previous commit since I do not see the file in the current commit to start with.
On your computer, move the file to a new location within the directory that was created locally on your computer when you cloned the repository. Open Terminal . Use git status to check the old and new file locations. Stage the file for commit to your local repository.
If this is your last commit and you want to completely delete the file from your local and the remote repository, you can: remove the file git rm <file> commit with amend flag: git commit --amend.
So, when rebasing, choose to edit both the commit where you added the file by mistake, and the one you want to add it to in that order. If the file is in a later commit, but should be in an earlier one, you will have to reorder the lines. For example, I start with
pick 8de731b Commit with missing file.
pick bbef925 Commit with too many files.
pick 52490ce More history.
I need to change it to
edit bbef925 Commit with too many files.
edit 8de731b Commit with missing file.
pick 52490ce More history.
Then,
# In the commit containing an extra file
git reset HEAD^ badfile.c
git commit --amend
git rebase --continue
# Now in the commit to add it to
git add badfile.c
git commit --amend
git rebase --continue
Unfortunately, when editing history in one branch, I don't know of any way to avoid editing history in all branches. Rebasing should be done as early as possible to avoid problems like this. In my simple case here, I can merge master and the other branch, but the commits don't merge, then I have to rebase in master, and reorder and squash the commits, like this:
pick 7cd915f Commit with missing file.
fixup 8de731b Commit with missing file. #This was the higher of the two entries
pick 8b92c5a Commit with too many files.
fixup bbef925 Commit with too many files. #This was the higher of the two entries
pick 94c3f7f More history.
fixup 52490ce More history. #This was the higher of the two entries
Late edit: I just noticed I was accidentally reordering the commit history as a carryover from my original answer. Swapping the lines in the rebase changes the order you commit; after editing, you can rebase again and swap them back to go back to the original commit order.
If I don't get it wrong, what you want is move some change that was included commit 2 to commit 1.
I find the easiest way to do that is doing two consecutive interactive rebases.
In the first one, you split commit 2 into two commits: the first including just the change you want to move, and the second including all the rest. We have now commits 1, 2.1, and 2.2.
Then you rebase again, and this time choose to squash commit 2.1 into 1.
As I often stumble upon this issue, I wrote a script for this. It works fully automatically. You can find it on Github. Copy it to the local filesystem, add it to PATH and you'll be able to run it as:
mv-changes <source-commit> <destination-commit> <path>...
You can also run the script in Git-Bash shell on Windows.
Note that, if there are changes of <path>
in intermediate commits between source-commit
and destination-commit
, it will not work.
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