1

Suppose developers are using git centralized workflow and github has 2 files a.txt and b.txt.

Now dev1 pushes c.txt successfully. Now if dev2 pushes d.txt, it's non fast-forward and he can't push and RIGHTLY SO, because he must first merge changes of dev1 locally and then push.

Now another scenario, Suppose dev1 creates branch featureC and has file c.txt in it along with a.txt, b.txt and pushes. Similarlty dev2 creates branch featureD and has file d.txt in it along with a.txt, b.txt and pushes.

Now pull request is made to merge featureC with master and it's successful. Again pull request is made to merge featureD with master and this SHOULD NOT be successful, but IT IS. IT CAN'T BE!! HOW COULD IT BE? Doesn't it match the above scenario?

Gauranga Rathod
  • 348
  • 5
  • 16

2 Answers2

1

The situation you describe

dev1:

a---b - master
     \
      c - featureC

dev2:

a---b - master
     \
      d - featureD

centralized repo:

a---b - master

In your first scenario (which you seem to agree with), it looks like both devs are trying to push directly to the same branch on the centarlized repo:

After dev1 pushes its local master to the centralized one:

a---b---c - master

Then if dev2 has locally a---b---d - master and tries to push that to master on the centralized repo, git complains. What should it do?

This:

a---b---d - master #nope

would be wrong since c is discarded.

This:

a---b---c    #nope
     \
      +---d

would also be wrong, where should master point to? No way for git to know. Hence the complaint, master has diverged.


Now to your second scenario.

I'll assume the pull requests results in pulls in the centralized repo.

"pull request is made to merge featureC with master and it's successful":

centralized repo:

      c - featureC
     / \
a---b---x - master

Then "pull request is made to merge featureD with master":

      c - featureC
     / \
a---b---x---y - master
     \     /
      +---d - featureD

I see no reason why this should not work! Since in the centralized repo, featureD is merged in a master that is up-to-date, and master has not diverged.

Gauthier
  • 40,309
  • 11
  • 63
  • 97
  • Thanks for answering Gauthier. but in scenario 2, feature branches are being created locally and then both featureC and featureD are pushed to github. No problem so far. But when these branches are merged with master in github using pull request, still there is no complaint and works just fine and that's what concerns me. – Gauranga Rathod Jun 22 '15 at 09:16
  • @GaurangaRathod: ok, so I've updated the log graphes. It's still no problem to merge `D` to `master` in the centralized repo (`pull` is really a `merge` in this case, since `D` is already in the repo). `master` is on `x`, and you merge `D` with `master`, and get `y`. `master` does never diverge with this workflow, and the diverge is why it fails in your first scenario. – Gauthier Jun 22 '15 at 10:34
  • I get that master doesn't diverge and so it won't conflict, but could you give me a scenario where I put something in my newly created branch, push it to github and when I merge it via pull request, it complains. I don't think it's possible. – Gauranga Rathod Jun 22 '15 at 11:11
  • No it's not possible. It's the way it's supposed to work. You only have problem when you push two different things to the same branch without being up-to-date the second time. – Gauthier Jun 22 '15 at 11:15
  • "You only have problem when you push two different things to the same branch without being up-to-date the second time". Agreed on this, but creating branches and merging them via pull request also essentially does a merge. So why is there no conflict there in that case??? – Gauranga Rathod Jun 22 '15 at 11:39
  • "You only have problem when you **push** two different things to the same branch". With the pull request you are not pushing, you are pulling/merging. You have a `master` that is up to date, and you add a merge commit on top of it. – Gauthier Jun 22 '15 at 11:48
  • Note also that you need to be careful with using the word "conflict". A conflict is when `git` does not know how to merge branches that applied different changes at the same location. What we are talking about is something different, pushing and pulling and created diverged branches. – Gauthier Jun 22 '15 at 11:51
  • Got it now. Thanks a bunch. – Gauranga Rathod Jun 22 '15 at 12:21
1

There is a substant difference between push and pull. When you want to push commits onto a remote branch, you local repo needs all commits from the remote and of course the commits you want to push. That is not the case when dev2 pushes the commit for d.txt, while not knowing anything of the previous commit, that introduced c.txt.

Now with pull requests, the situation is different. You always can savely pull anything that does not conflict, which is the case when the commits affect different files only.

Actually it's a pull request, in your first case, when git tells dev2 to pull (merge) before he pushes.

You can always pull (fast-forward or merge) when there are no conflicts but you can only push when your branch is up-to-date with the remote branch you want to push to.

How to understand what gets commited

It's quite easy for a developer in a local repository to see what changes actually are requested by a commit. Assumed dev1 branched to featureA to develop some feature from master, this morning. In the evening he wants to see all changes he did and when he checked in, he yould do

git format-patch master..featureA

All commits numbered in order are written to files NUMBER-TITLE.patch.

All these patches can be merged to origin/master regardless of the state of origin/master (if there are already new changes went to origin/master, or not), when no patch fails to apply to origin/master, ordered by the number.

ikrabbe
  • 1,909
  • 12
  • 25
  • Thanks for answering Ikrabbe. I just created a featureE branch locally. In that I deleted a.txt, changed b.txt and added e.txt. Now I pushed this branch successfully to github and then created pull request to merge this branch to master. Now this must conflict according to your opinion as we are making changes to the same file, but as it turns out, it doesn't conflict. I guess no matter what I put in some new branch and push it and merge it via pull request, github won't complain. This doesn't seem to be appropriate behavior. – Gauranga Rathod Jun 22 '15 at 11:08
  • @GaurangaRathod: why is it not appropriate? You work in a branch, you say you want these changes into `master`. Why should it fail? It does not matter what the changes are, deletion, modification, addition, ... Merging to `master` is saying you want all the changes of the branch into `master`. – Gauthier Jun 22 '15 at 11:24
  • 1
    @GaurangaRathod I haven't said that changes to the same file will conflict but I said that changes to diffenerent files will never conflict. Changes to the same file might conflict or might not. Also one commit can never conflict as there is nothing to conflict with, assumed that you commited just on top of the HEAD. But if you want to merge two commits that both are created from the same status, they might conflict. For example when you send a pull request to remove a.txt and a pull request to change a.txt, when you want to merge those two you will get a conflict. – ikrabbe Jun 22 '15 at 11:35
  • Oh yes, you're right. I created two pull requests which change same file in different ways and one pull request can't merge automatically as it conflicts. Thanks for your help again :) – Gauranga Rathod Jun 22 '15 at 12:17