user3687001
user3687001

Reputation: 345

git rebase for keeping most recent commit

I have commits A, B, C and D and I need to just keep the most recent one which is D. I see that one way is by using git rebase -i --root as you can pick and squash commits.

Although I don't understand the difference between pick and squash that much, it made my wondering that since the commits are incremental thus commit D includes all changes in between, why do you have to go through git rebase for keeping the most recent commit and not just delete the rest of the commits?

Or am I missing something fundamental about git? Can you have commits that are unrelated between each other? i.e someday use commit B and in another situation use the most recent commit D?

Upvotes: 1

Views: 1100

Answers (1)

user4815162342
user4815162342

Reputation: 154926

git commits aren't really incremental, each commit contains the entire tree. It is only the user interface that presents a commit in terms of differences from its parent. In that sense, you don't have to go through git rebase to keep the most recent commit and discard the rest, you can also use the git commit-tree plumbing command to create the commit. The full equivalent of the rebase would be a line like this:

git reset --hard $(git commit-tree HEAD: -m message)

That dense line does the following:

  • HEAD: refers to the tree object contained in the current head commit.

  • git commit-tree TREE -m MESSAGE creates a new parentless commit that contains the specified tree, in our case the tree of HEAD. Its output is the SHA1 of the newly created commit.

  • git reset --hard COMMIT resets the current branch and the working tree to the specified commit, in this case the newly created root commit.

Creating commits without history is discouraged by git because such commits make it hard for git to operate on the data. Commands like git annotate and git merge rely heavily on history being available, and without those git is a much less useful tool.

Upvotes: 6

Related Questions