Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
147 views
in Technique[技术] by (71.8m points)

How git works when two peers push changes to same remote simultaneously

I am new to git, I usually use P4 which has center repository, while git is distributed VCS.

I am interested in how git works when two peers push changes to same remote simultaneously. Assume each peer resolved all conflicts before push. I guess the later one will be rejected if git reports conflicts!

However, from what I understand, git is internally a key/value store, much like the current popular NOSQL database especially Couch-DB which supports p2p replication.

Actually I want to ask, how does git process conflicts in the case that clients push changes to remote git repository? Is the push rejected?

From Mark's answer, I think the push should be rejected.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Short answer

Yes, one of the pushes will be rejected - whichever one is later, even if it's just by a microsecond, as Jefromi mentions in his comment. However, it will be rejected because the remote repository sees that the history of the later push doesn't include the history of the earlier one, rather than because it sees any conflict in the content that's being pushed.

More detailed answer

Usually a push will be rejected if it wouldn't "fast-forward" the branch, in Git terminology. This means that if your master is at A and the remote repository's is at B, then the push will only succeed if B is an ancestor of A. (I say "usually" because you can add options to "force" the push if the remote repository allows that, but that's not the typical case.)

In the case you describe, supposing all three repositories initially have the same history:

P -- Q -- R

And you have added a commit S:

P -- Q -- R -- S

... while someone else has added a commit T:

P -- Q -- R -- T

If that other person gets there first when pushing (that is, Git on the server handles their push first), then their push will be accepted because R is an ancestor of T, so the remote repository will then also have the history P -- Q -- R -- T. If you subsequently try to push, you will get an error because T is not an ancestor of S. Typically, on seeing that ! [rejected] error you will either run git pull or git pull --rebase to make sure that you are ahead of master in the remote repository.

git pull will create a merge commit M to make your history look like:

P -- Q -- R -- T -- M
                  /
            -- S -

... while git pull --rebase will reapply the changes that you introduced on top of T to create a new commit, S':

P -- Q -- R -- T -- S'

In either of those cases, you should be able to push again, because T is an ancestor of both M and S'. (That is assuming no one else has pushed again in the mean time!)

By only allowing fast-forwards there never has to be resolution of conflicts on the remote side - if there are any conflicts, you'll be prompted to resolve them locally when you run git pull.

It might be worth noting that the update applied to the remote repository in response to a push is atomic, so in the example situation we've described above where S and T are being pushed at the same time, it will always be the case that one of them is completely applied while the other one will fail, having not effect.

A note about your key/value store point

While Git's object database is implemented as a key/value store, which maps object names (also referred to as hashes or SHA1sums) to the content of objects, in my experience it's easy for people learning Git to make confusing assumptions about how Git behaves when they hear "it's like a key value store" - it sounds as if this might be happening in your case, so I'd suggest that thinking about Git at that level isn't the most helpful approach for understanding this issue.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...