tags:

views:

250

answers:

4

Let's say that there are two people working on a git branch, they check out at the same time but one of them commits first and then the other commits after, will the newest commit still be merged with the former commit. or can multiple people work on the same branch simultanious?

A: 

Multiple people can work on the same branch at the same time. When you pull (or have the other person push) their changes to you git will merge the changes together resulting in a branch with both of your changes.

Chealion
+8  A: 

Well, when you clone a git repository (is that what you meant by "check out"?), you're effectively creating a new branch. Git branches are local to each repository, not global. Having said that, you have a protocol for how updates to branches are transmitted between repositories-- when you pull from a remote, by default the remote's "master" branch gets merged into your "master" branch, for instance. And when you push, your "master" branch can be appended to the remote's master branch. So your master and remote's master ("origin/master", if you will) are different branches, but related by convention.

Getting back to the point--- you notice I said your master branch can be appended when you push to a remote. If two people have taken a copy of origin/master and made independent changes (remember this is just like making changes on two branches locally), once one person has pushed their changes, the other's person's changes aren't a simple append onto origin/master any more--- they have to be merged. This can't happen when you push, only when you pull (confusingly, "pull" isn't quite the opposite of "push": "fetch" is the opposite of push- a pull is a fetch followed by a merge (or a rebase)).

So if you're in this situation, whoever is trying to push their changes first needs to pull back from the updated origin/master, merge or rebase their version of master, and then push. By default you can't remove someone's changes to a branch and replace them with your own: you need to at least do "git push -f" to do that, and the remote repository can have settings or hooks to make it considerably harder.

Or the two of them could cooperate beforehand: one of them pull the other's changes, do the merge, and then push the result. This can be a good thing to do if it's likely the changes are going to overlap or affect each other. Remember the First Law of version control systems: a VCS is not a replacement for communication.

araqnid
"a VCS is not a replacement for communication." That's probably the best comment I've read all week.
docgnome
+2  A: 

In Git, branches are strictly local. One developer cannot change another developer's remote branches (see note at bottom). However, in the case of a bare repository, you can "push" your changes to it in order to update the remote repository's branches, if your changes will result in a fast-forward.

But if two developers are committing to the same remote repository, then only one will be able to fast-forward the remote branch without first bringing their branch back up-to-date.

For example, let's say Alice and Bob are both working on the master branch in their local repositories, each cloned from a shared (bare) repository on a server. If Alice finishes her work first, when she pushes her committed changes to the shared bare repository, it will fast-forward the bare repo's master branch.

Now Bob cannot fast-forward the bare repo's master branch without first updating his local branch to include the commits that Alice has added (because the commits he's added are not ancestors of the commits that Alice created).

One way Bob can do this is to pull (or preferably rebase) from the bare repo after Alice has pushed her commits. This will merge Alice's changes into Bob's branch and make it possible for Bob to fast-forward the bare repo's master branch with a push.

Other workflows are possible: Alice and Bob could cooperatively pull from each other directly without using a shared bare repository. There are almost endless possibilities, really. But in general, merging in Git is done by pulling changes.

[note: it actually is possible to push into non-bare repositories, and thereby update other people's branches, however this often yields unintuitive results, is not considered a typical git workflow, and is generally not encouraged]

Dan Moulding
+1  A: 

A shorter answer is this:

commit -m "my changes"

Retrieve the shared version

git fetch sharedrepo

one of these two to sync your local branch with the other repo

git merge sharedrepo/sharedbranch
git rebase sharedrepo/sharedbranch

Rebase serializes the history if you do not want a lot of branches in the final history. Both options may force you to solve conflicts before you are done.

After merge/rebase and resolving conflicts you push back to repo

git push sharedrepo HEAD:sharedbranch

Do not use -f here as this should be a fast-forward. If you are unlucky someone else may have pushed a new version. If that happens you restart this procedure.

robinr