Here is my git command:
git rebase -i HEAD~2
I would expect to see the 2 most recent commits but I see this instead:
I also want to mention that while I have been attempting to squash certain commits, I consistently running into merge conflicts. I'm getting the feeling that these issues might be related.
I'm a bit of a git noob so any help would be much appreciated.
git log --graph --all --oneline --decorate
:
Commit Chain:
CodePudding user response:
Merge commits have more than one parent commit. ~
indicates the first parent of a commit. That is the left hand side of your graph. ~
only follows the first parents. HEAD~2
asks for the first grandparent.
~
is a good way to move through history skipping over merged branches.
* HEAD
|\
| *
| *
| *
| *
* | HEAD~1
|/
* HEAD~2
|\
| *
| *
|/
* HEAD~3
git rebase -i HEAD~2
is really git rebase -i HEAD~2..HEAD
so you're going to get all the commits reachable from HEAD
excluding all the commits reachable from HEAD~2
. That means HEAD
, HEAD~1
, and all the commits in the side branch.
^
is for selecting parents. HEAD^
is the first parent, same as HEAD~
. HEAD^2
selects the second parent, which is the first commit in the branch.
^
and ~
can be chained. If you want just two commits on the side branch, that's git rebase -i HEAD^2~2
. HEAD^2
selects the second parent of HEAD. So HEAD^2~2
is the first grandparent of the second parent of HEAD. It's easier with an illustration.
* HEAD
|\
| * HEAD^2
| * HEAD^2~ also HEAD^2^
| * HEAD^2~2 also HEAD^2^^
| * HEAD^2~3 also HEAD^2^^^
* | HEAD~1 also HEAD^1
|/
* HEAD~2 also HEAD^1~
|\
| *
| *
|/
* HEAD~3
Confused? That's ok. Rather than messing with all this, it's often easier to just rebase back to the branch you merged off of and leave the extra commits as pick
.
git rebase -i main
See gitrevisions for more.