3

Here is the situation: (P means people here).

P1 and P2 created their own branches, devP1 and devP2, from master.
P2 just ended their work, so they merge with local master then they pushes on the remote master repository. All is fine.

But then, P1 ends their work too, so they are doing the same thing, merging with the local master, then trying to push. But obviously, the remote master is ahead than their local one, and they can't push.

In this case, I used to just pull the master branch in those kind of situation, but someone recently told me this was very bad because I was creating a merge commit, which one was irrelevant or at least meaningless.

That's when they lost me and I haven't been able to understand what I'm supposed to do in those kind of situation. Is someone can explain to me what to do here? Some kind of rebase maybe? But I can't really rebase a remote branch right?

Thanks for your help and explanation. I haven't been able to find this anywhere.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
  • make sure to "remember" your branches commitid - in case something goes awry when rebasing with --hard so you still can access your last branches commit for a soft rebase with changes.- – Patrick Artner Dec 10 '17 at 14:32

3 Answers3

1

I suspect what your interlocutor had in mind was in fact using a git rebase instead of a merge. Consider the following simple diagram which will demonstrate what a rebase is.

master: ... A -- B -- D
local:  ... A -- B -- C

The above diagram attempts to represent the state of the branches when P1 attempted to push his work. Both his local branch and the remote master are identical up until commit B. But P2 has pushed commit D on top of master, and then P1 made commit C locally. If P1 were to pull the remote master, merge, and then push, we would have the following diagram:

master: ... A -- B -- D -- M'
local:  ... A -- B -- C -- M

Now we see that both the local and remote master branches have merge commits (labelled as M and M'). However, there is an alternative here. P1 could have rebased his local branch on the remote master branch, via this:

git checkout local
# do a fetch if not up to date already
# git fetch origin
git rebase origin/master

Now here is what the diagram would look like after rebasing:

master: ... A -- B -- D
local:  ... A -- B -- D -- C'     (C' labelled as such because it is a new commit)

Pay attention here, because what rebasing has done is to rollback the local branch to the most recent common commit between itself and master, which is commit B. Then, it replays the commits from master, which in this case is just commit D. Finally, it applies the commits which were unique to the local branch, in this case commit C.

The nice thing about this, which you can hopefully see, is that P1 can now just do a normal git push to bring his commit into the remote master:

git push origin master

This would leave the diagram looking like this:

master: ... A -- B -- D -- C'
local:  ... A -- B -- D -- C'

Now there is no merge commit on the remote master branch.

Note that rebasing usually involves rewriting the history a branch, and this can have complications if the branch being rewritten has already been shared publicly. In the case of P2, if his local branch is being used only by him, then there is no penalty for rebasing it. The remote master branch was not rewritten by the exercise we did above. But this may not always be the case, and is something to keep in mind.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • Thanks, looks like this is what I was looking for. – Rockleader01 Dec 10 '17 at 14:48
  • Feel free to ask questions if you have them. It is tough to thoroughly explain rebasing even in a single SO answer. – Tim Biegeleisen Dec 10 '17 at 14:48
  • I already knew the rebase so it's fine. I just didn't see the "trick" considering using the rebase instead of pull to avoir this merge commit. – Rockleader01 Dec 10 '17 at 14:55
  • @Rockleader01 Yes, the trick is basically to shuffle the commits so that your local branch ends up in a position where it is ahead of the remote target branch. Then, "magically" all you have to do is push, with no merge commits. – Tim Biegeleisen Dec 10 '17 at 14:57
0

As far as i know, u have two options: 1. Pull master, merge devP1 into master and push master. 2. Fetch devP2. Rebase devP1 onto devP2. Merge devP1 into master and oush master.

Edit: P1 can do this too. Hard reset master back to original. Pull master. Rebase devP1 onto master. Merge devP1 into master and push master.

Aayush Karki
  • 781
  • 3
  • 10
  • 25
0

You can do the merge not with local master, but with remote master

git fetch --all
git merge origin/master <--no-ff>

Or you can rebase your work, which can be done with pull as well

git fetch --all
git rebase origin/master

If you have rule that you are merging every branch and you merged with remote branch, but someone was still faster than you with the push, you can reset the last merge and do it again

git reset --hard HEAD^
git merge....
git push origin master

There are many ways how to do this. There is no correct way. Some companies enforce the rule that you have to merge all changes to master with --no-ff, some companies prefer to use rebase. Botw ways are correct, the difference is what you will be able to tell from the git history.

If anything will go wrong, you don't have to remember the previous commit which was ok. You can always run git reflog.

PS: git pull is just shortcut for git fetch --all && git merge ... or git pull --rebase for git fetch --all && git rebase ...

martin.malek
  • 2,166
  • 2
  • 19
  • 31