Let's say Im working on a feature, in a branch called foo_baz
.
I commit multiple times as I work on the feature.
I periodically push foo_baz
, a remote-tracking branch, to a remote repo. IE origin/foo_baz
.
I progress to the point where I want to merge all commits from foo_baz
into master
and push to origin/master
. Here's the question:
Can I merge foo_baz
into master
such that all commits are still separate in foo_baz
's histroy, but that in master
's history, they are all one, squashed commit?
Edit:
I'm a bit of a git beginner, so please forgive me if there's something totally obvious that I'm missing. I dug around on the web but couldn't find a direct answer to my question.
Git squash with a commit id The last command opens the interactive Git rebase tool which lists all of the commits in the branch. You must type the word pick next to the commit you want all others to be squashed into. Then type 'squash', or just the letter 's', next to each commit to squash.
As a general rule, when merging a pull request from a feature branch with a messy commit history, you should squash your commits. There are exceptions, but in most cases, squashing results in a cleaner Git history that's easier for the team to read.
You might indeed be looking for --squash
(as in the other answers), but you might be looking for --no-ff
instead.
Here's the difference between the two. Suppose you start with two commits:
A --- B <-- branch "master", when you start
and then make two more on your new branch foo_baz
:
A --- B <-- master
\
C --- D <-- foo_baz
Now (once back on master
), you have these two options (among others). You can git merge --squash foo_baz && git commit
which will give you the following:
A --- B ----------- E <-- master
\
C --- D <-- foo_baz
or you can git merge --no-ff
:
A --- B ----------- E <-- "master" after merge --no-ff
\ /
C --- D <-- foo_baz
Both give you a new commit E
—in the first case, from the separate git commit
command—but the first one suppresses the multi-parent-ing action, so that in end, when you look back on this a year from now, it looks like you just copied all the changes from the branch. The tree (all the files you get when you git checkout
the branches) will be the same in both D
and E
(in this particular case anyway, where there are no changes to B on master
before the merge action), but they're different commits.
The difference from a straight git merge
is that the latter will generally produce a "fast forward", which looks like this:
A --- B
\
C --- D <-- foo_baz, master
where the angled line can be straightened out, giving you a history where both branches look exactly the same.
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