Is there a way to squash and merge master into the same branch? Effectively taking all the pending commits and putting them into 1 commit?
My original idea is a script that takes my-branch
and does a git checkout master && git pull && git checkout my-branch-squashed
and then git merge --squash my-branch
(deal with any merge conflicts) and then finally delete my-branch
and rename my-branch-squash
to my-branch
This seem very round-about and possibly bad, so I am trying to see if there is any other way. The intent I am trying to solve is that when I put branches on github and they are "squashed and merged" into master, the branch that exists on the local machine doesn't match the branch that was merged into master, so when using git branch --merged ${1-master} | grep -v " ${1-master}$" | xargs -r git branch -d;
it doesnt correctly delete the branches that have already been merged into master. What I want is a way to auto-delete old branches that have been merged into master
3 Answers
Answers 1
You can do that using git rebase
, and fixup the commits you want to merge:
$ git rebase -i HEAD~5 pick c2e2c87 commit 1 f 689d474 commit 2 f aa9d9b4 commit 3 f 888a009 commit 4 f d396e75 commit 5 # Rebase 2f7f53e..d396e75 onto 2f7f53e (5 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
You can use git rebase -i --root
in order to rebase from the first commit.
Answers 2
If all you really want is to squash your local development history before submitting a pull-request, the simplest way is to just develop on a local feature branch which is different from whatever upstream branch you want to affect.
Then, the procedure for squashing it onto master is
git checkout master git merge --squash feature
(replace master
with integration
or whatever).
I'd use rebase -i
for fine control, but for this simple case we can use git's knowledge of your history to figure out the last common ancestor automatically.
Answers 3
Setting aside the issues with the merge-squash workflow, which have already been discussed thoroughly in many places, in light of workflows often being out of your control.
There is a method you can use and though it is not 100% effective, it does have a fairly good track record in my experience and always fails safe.
Without ancestry to rely on, you need is a way of determining if two snapshots are identical. You can use the hash of the commits' trees with this command:
git show --format="%T" <committish>
In order to check if a branch can be deleted, first merge master into your branch. If there is a conflict in this merge, or there was a conflict in the original squash, you won't be able to use this method (this is the less than 100% effective part).
Thanks to the nature of git, it does not matter what order a set of patches are applied if no conflicts occur. So if the result of this merge should be identical to the head of master if your branch has been merged. This can be confirmed by comparing the tree hashes of the two branch heads you can find out if any unmerged code exists on your branch.
This could be boiled down into an command for single use that can be easily aliased like:
if [ $(git show --format="%T" origin/master) = $(git show --format="%T" HEAD) ]; then echo Merged; else echo Unmerged; fi
Or built into a shell script that will loop through all your local branches, merge them, test them, and delete the ones that have been merged.
All that being said, using interactive rebase to flatten your branch and getting the maintainer to use a fast forward only merge strategy on the pull requests would make all this unnecessary.
0 comments:
Post a Comment