The issue is that I need to look whether the branches which I want to merge are not published.
If they aren't published, you should rebase them.
But checking if a rebase is actually possible is a tiny bit tricky:
First, after fetching, you easily can check if you have local commits not yet pushed:
git log origin/master..master
o--o--o (origin/master)
/
x--x--x--y--y (master)
It is perfectly ok to rebase in this instance, except if master
was already pushed to another branch from your repo.
But you also can check that easily with:
git branch -r --contains master
If any remote (-r
) branch contains the branch you want to rebase, then it is a less safe idea, and a merge is preferable.
But, if the remote branch itself was rebased (and forced pushed), then you need to be careful, as detailed in "How do you deal with a public repository that has already been rebased?":
o--o--o (OLD origin/master)
/
x--x--X--y--y (master)
\
o'--o'--o' (origin/master, as seen after a 'git fetch')
Rebasing blindly master
on top of origin/master
would replay commit X
, which was left out when origin/master
was rebased. Not good.
Today (January 2014), the only way to deal with this case is to:
- make a 'tmp' marker branch on
origin/master
,
git fetch
,
- check if
git branch --contain tmp
lists origin/master
(which has been fetched and is possibly with a different history if it was rebased and forced pushed).
Tomorrow (git 1.9, Q1 2014), you won't have to mark your remote branch before fetching:
fork_point=$(git merge-base --fork-point origin/upstreamBranch yourBranch)
# return X
git rebase --onto origin/upstreamBranch $fork_point yourBranch
To recap:
After a git fetch
(after marking origin/master
before the fetch),
- if
git log origin/master..master
returns commits from master
which aren't part of origin/master
(meaning those local commits haven't been pushed to origin/master
)
- AND if
git branch -r --contains master
is empty (meaning master
wasn't pushed anywhere else, on any remote tracking branch you can see through a git fetch
)
Then:
- if
origin/master
include the marker branch 'tmp
' (meaning origin/master
itself wasn't rebased), you can git rebase origin/master master
.
- else: you can
git rebase --onto origin/master $(git merge-base tmp master) master
(you need tmp
here to rebase just your branch. Git 1.9 will make the need for a tmp branch needless)
In any other cases: merge origin/master
to master
.