This is 3rd set of git notes.
It’s about magic command
rebase in interactive mode with ability to
suqash and related note about
reset during rebase.
I have situation, when I made a few commits from Bitbucket web site, then pulled code to local working copy, made a few commits locally and pushed, then again a few commits from Bitbucket and pulled locally. So I ended up with a mess in commits tree. And I wanted to squash it. I wanted to use
git rebase -i origin/master but I failed, because in fact git expected my current local commit to present. So that origin/master would be behind my local commits. But I didn’t have origin/master changes. So git answered me
noop when I hit rebase.
So I decided to reset code. And I made it like this:
git reset --soft HEAD~6
In my case 6 – is number of commits, back to latest “normal” commit. In fact I could use SHA of that commit, which is 100% equal.
But the magic here is
--soft, which in fact DOES reset git INDEX but update files with content of last commit I have. And it’s remain as “added for commit”.
Original explanation from git docs (git reset):
Does not touch the index file or the working tree at all (but resets the head to , just like all modes do). This leaves all your changed files “Changes to be committed”, as git status would put it.
and about “–hard”:
Resets the index and working tree. Any changes to tracked files in the working tree since are discarded.
squash => rebase => commit –allow-empty
You should definitely know “squash” awesome feature of git. I use it when I messed up with dozen commits locally, and I want to have only one, with proper commit message. I get used to this also.
But this time, I have situation, when there were commits with so called “empty content”.
Here is message from git, when I do
git rebase -i HEAD~4 (where one commits was about empty file, removal):
You asked to amend the most recent commit, but doing so would make
it empty. You can repeat your command with –allow-empty, or you can
remove the commit entirely with “git reset HEAD^”.
rebase in progress; onto bacbdfc
You are currently rebasing branch ‘gh-pages’ on ‘bacbdfc’.
Could not apply 1fe14870b4461d2957e0468f45000228972b8b41… Updates
And this is info about –allow-empty param of commit command.
Usually recording a commit that has the exact same tree as its sole parent commit is a mistake, and the command prevents you from making such a commit. This option bypasses the safety, and is primarily for use by foreign SCM interface scripts.
Like –allow-empty this command is primarily for use by foreign SCM interface scripts. It allows you to create a commit with an empty commit message without using plumbing commands like git-commit-tree.
I faced with such situation first time. And in fact I made these steps to finish my rebase:
$ git rebase -i HEAD~4
add s/squash before commit messages and :wq
comment not needed commit messages
then git asked/told me about empty commits
$ git commit -m "Yes, I really do want those empty commits" --allow-empty $ git rebase --continue
There is also info from
git rebase command.
Keep the commits that do not change anything from its parents in the result.
Not tired with this. Also not tried with git cherry-pick. So this is kinda TODO for the next time.
- My Git Notes #1, Git Notes #2.
- Small article about “–alow-empty”
- About “git rebase -i” by Attlassian.