Reputation: 21007
I've been reading a little about --squash
ing commits, but they all seem to be go hand in hand with a --rebase
.
I have a feature branch with a set of commits like this:
(Feature) A --> B --> C --> D --> E --> F --> G
/
(Master) M1 --> M2 --> M3
Suppose I want to merge back to the Master
branch, but I want to clean up the commits on my feature first.
Is it possible to:
OR
Either way, can I do a squash directly on my feature, WITHOUT immidiately initializing a Merge
or Rebase
with it?
If so, how can I do this with Git?
Upvotes: 29
Views: 24258
Reputation: 57006
This works if the commits are local and have not been pushed yet:
git reset --soft HEAD~x
git commit -m "whatever"
Where x is the number of commits you want to squash
Not sure how this would work if the commits you want to squash are on the remote also - if that was the case you "might" need to:
git push -f
after running the above commands. The usual warnings of git push -f
apply - if there is a need to force push make sure you do sanity checks with git log first (as a force push overwrites the code on the remote)!
Upvotes: 9
Reputation: 14477
Solution: It is possible to squash multiple commits into single one without rebasing. The best option is to create a new temporary branch from master, then merge the messy branch squashed in only single commit into the temporary branch, then making a pointer to it in your working branch and after delete the temporary one.
Lets assume:
master
is your master branch, feature
is your messy working branchtemp
is your temporary branchHow to do it?
git checkout -b <temp> <master>
git merge --squash <feature>
git commit -m "your single message"
git checkout <feature>
git reset --hard <temp>
git push -f
git branch -D <temp>
Before:
(Feature) A --> B --> C --> D --> E --> F --> G
/
(Master) M1 --> M2 --> M3
After:
AG -->
/
(Master) M1 --> M2 --> M3
Upvotes: 7
Reputation: 5392
In my team's workflow we often merge with upstream in the middle of a bunch of commits, and rebasing could get ugly. I've found this helpful to squash all commits that are ahead of master down into one:
# Commit any working changes on branch "mybranchname", then...
git checkout master
git checkout -b mybranchname_temp
git merge --squash mybranchname
git commit -am "Message describing all squashed commits"
git branch -m mybranchname mybranchname_unsquashed
git branch -m mybranchname
# Optional cleanup:
git branch -D mybranchname_unsquashed
# If squashing already-pushed commits...
git push -f
Upvotes: 23
Reputation: 3454
Yes and no.
Yes, you can avoid changing the parent of commit 'A' but I believe you can't avoid git rebase
. You can do interactive rebase on the same root:
git rebase -i M2 Feature
Then you can do whatever you want and at the end branch Feature
will still start from commit M2.
Upvotes: 6