Reputation: 11
Suppose I have a Base commit B1 and on top of it I create local commits say C1,C2,C3. There are two ways for pushing the latest changes (C1,C2,C3) into git:-
I want to know which way is better and which way is worse and why?
Upvotes: 1
Views: 634
Reputation: 4484
I would assume that by squash
you mean rebase
n commits and then squash them.
So, the way I see it, here is what the different approaches offer.
1. Using reset
When you are using reset, what you are doing is moving what HEAD
is pointing to.
Reset current HEAD to the specified state.
The first thing reset will do is move what
HEAD
points to. This isn’t the same as changingHEAD
itself (which is what checkout does); reset moves the branch thatHEAD
is pointing to. This means ifHEAD
is set to the master branch (i.e. you’re currently on the master branch), running git reset9e5e6a4
will start by making master point to9e5e6a4
.
Given the three parameters you can pass to the command, --soft
--hard
--mixed
, you might completely loose your work, or you can have your changes in the "Changes to be committed"
state.
The benefit of this approach is that it's easy and quick. You tell git where you want HEAD
to point to, and the rest of the changes (in this case all 3 commits) would be mashed together into one big change. Then commit and push. Pretty easy.
The downside of this is that it gives you a limited control over your squash (because this is the goal of the operation, to squash). You don't see the commit hashes, you don't see the 3 commit messages, you are not given the option to re-order them, to reword/fixup any of the commits.
2. Using rebase
NOTE: Here I am talking about an interactive rebase
, again with the idea to properly squash commits.
When you rebase
interactively in git, you are given a list of all of the commits you have specified to rebase
. They are ordered, formatted, and below them, you have a set of commands you can specify for each commit. Because we are interested in squashing, we can pick our commit to squash into, and the rest we can tag with squash
.
What this allows us to do is to see the commits we are squashing. We can read the messages they have, we can see our history. At this point we might say that we actually want to reorder them, or to just reword the messages. Git gives us more flexibility to have the history we want to (although some might tell you that changing git history is a bad thing, and that argument sure has merit sometimes).
But even when we just want to squash all of the commits, git then makes us write a new commit message, and we can see all of the commit messages from the commits we want to squash. No need to hunt or remember previous messages.
The downside of this approach is that it might be more difficult to use the git-interactive menu and that it might take you a bit longer to do a squash
.
Personally, I believe that both strategies work, but it feels like rebase
-ing is more in-tune for squashing commits. It just depends in what situation you are in. If you think that you might be better off with resetting and re-committing, then go for that. But I think that using an interactive rebase
might save you from messing things up in your history.
Edit I didn't see that the comments pointed out correctly that squashing is not the only way to push commits to your remote. Maybe that's the most straightforward and easy way :)
Upvotes: 2