質問

I'm studiyng Mercurial but I don't understand how it detects the file conflicts.

When a centralized SCM (as SubVersion) detects a conflit between two versions of a file in my project, it means the version number of mine local file is minor then version number of same file in the remote repository, because another developer (p.e. John Smith) has committed before me (by the same initial version number).

In a decentralized SCM (Mercurial, Git, etc), I haven't a central repository, then:

  • I clone a repository, downloading a number version A of file from the remote server;
  • John Smith clones the same repository, downloading the same number version A of file from the remote server;
  • John Smith codes a little and commit in him local;
  • After, I commit in mine local;

How Git understands that our files are direct descendant from number version A? The Mercurial/Git/Bazaar/etc has'nt an internal number what identifies: how they understand when a modified file is in conflict or not?

役に立ちましたか?

解決

Any conflicts are only detected after you and John Smith communicate with each other (using hg push and hg pull) and one of you then want to merge the two lines of work (using hg merge).

After you pull the change by John Smith into your local repository, the changeset graph might look like this:

... [a] --- [b]
       \
        `---------- [c]

where you made changeset b and John Smith made c, both based on changeset a. Between a and b, you changed the file helloworld.c and between a and c John Smith changed the same file. Mercurial is now able to tell that there might be a potential conflict here (an overlapping edit) and it will tell you when you run hg merge.

The system is not based on version numbers associated with the files — it's based on the above changeset graph. Concretely, when you merge b with c, Mercurial will find the greatest common ancestor, which is a. It will then look at the manifest (a list of the files (and their version) present in a given changeset) in a, b, and c and notice that the file helloworld.c existed in three different versions. That tells Mercurial that it needs to do a three-way merge with a being the base version, and b and c being the local and other versions. By default, it tries to do the merge internally, but it will call external merge tools (like KDiff3) if that fails.

他のヒント

If you really want to know how it works I recommend Chapter 4 of the book "Mercurial: The Definite Guide"

In short, Mercurial creates a unique identifier for each version. It is unique across all repositories - based on hashing. Both you and John Smith will have the same identifier for version A in your repositories. Your local changes will have different identifiers. When one of you decides to pull and merge changes, Mercurial is able to determine that both of you made changes to the same version A. Both changes are compared to base version A. It is easy then to check if resulting patches are conflicting or not.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top