According to the Github for Mac blog announcement,
Once you're ready to share your commits, or pull in remote commits — just press the Sync Branch button. We'll perform a smarter version of
pull --rebase && push
that reduces merge commits but doesn't rewrite your merges.
What is "a smarter version" of pull --rebase && push
? What exactly are they doing? Is it possible to do this "smarter" thing on the command line?
The blog post "Rebasing Merge Commits in Git" (from Glen Maddern) illustrates the danger of a git pull --rebase
when you have made local merges:
If you do a git pull --rebase
of master
on top of origin/master
now, you would delete your local merge.
See the next picture after the rebase: no more merge commit.
This is bad for a whole lot of reasons.
- For one, the feature commits are actually duplicated, when really I only wanted to rebase the merge. If you later merge the feature branch in again, both commits will be in the history of
master
.- And
origin/feature
, which supposed to be finished and inmaster
, is left dangling.
Unlike the awesome history that you get from following a good branching/merging model, you’ve actually got misleading history.
For example, if someone looks at the branches onorigin
, it’ll appear thatorigin/feature
hasn’t been merged into master, even though it has! Which can cause all kinds of problems if that person then does a deploy. It’s just bad news all round.
That is what Github for (Mac|Windows) would detect and avoid.
If you didn't detect it in time, the same blog post mentions the following recover:
[master] git reset --hard origin/master
HEAD is now at 9f3e34d sneaky extra commit
[master] git merge --no-ff feature
Actual Solution:
You can achieve the desired result:
Instead of using
git pull --rebase
, use agit fetch origin
andgit rebase -p origin/master
I suppose the "smarter version" of pull --rebase
is that combination of "fetch + rebase preserving the merge".
Glen also proposes the following aliases to counter the fact that this sequence of command would no longer use the tracking information associated to a local branch.
function git_current_branch() {
git symbolic-ref HEAD 2> /dev/null | sed -e 's/refs\/heads\///'
}
alias gpthis='git push origin HEAD:$(git_current_branch)'
alias grb='git rebase -p'
alias gup='git fetch origin && grb origin/$(git_current_branch)'
Jason Weathered posted a "http://jasoncodes.com/posts/gup-git-rebase", but now refers to git-up, from Aanand Prasad.
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