Size: 6083
Comment: illustate -> illustrate
|
Size: 7397
Comment: show arrows in parent direction
|
Deletions are marked like this. | Additions are marked like this. |
Line 4: | Line 4: |
''(Translations: [:BrazilianPortugueseUnderstandingMercurial:Brazilian Portuguese], [:ChineseUnderstandingMercurial:Chinese], [:FrenchUnderstandingMercurial:French], [:GermanUnderstandingMercurial:German], [:ItalianUnderstandingMercurial:Italian], [:JapaneseUnderstandingMercurial:Japanese], [:KoreanUnderstandingMercurial:Korean], [:RussianUnderstandingMercurial:Russian], [:SpanishUnderstandingMercurial:Spanish] )'' |
|
Line 8: | Line 21: |
Mercurial repositories contain a working directory coupled with a store: | Mercurial [:Repository:repositories] contain a [:WorkingDirectory:working directory] coupled with a store: {{{#!dot digraph G { rankdir = LR; compound=true; background="#999999"; subgraph cluster_0 { label="working directory"; style=filled; color=lightgrey; node [style=filled,color=white]; edge [style=invis]; "main.c" -> "main.h" -> ".hgignore" -> ".hgtags"; } subgraph cluster_1 { label = "store"; labelloc = b; style=filled; color="#eeeeee"; node [shape=box, style=filled, color=lightgray]; "rev 0" -> "rev 1" -> "rev 2" -> "rev 3" [dir=back, label="parent"]; } "main.c" -> "rev 2" [ltail=cluster_0, label="parent", labeldistance=5, minlen=2]; } }}} The store contains the '''complete''' history of the project. Unlike traditional [:SCM:SCMs], where there's only one central copy of this history, every working directory is paired with a private copy of the history. This allows development to go on in parallel. The working directory contains a copy of the project's files at a given point in time (eg rev 2), ready for editing. Because [:Tag:tags] and ignored files are revision-controlled, they are also included. == Committing Changes == When you [:Commit:commit], the state of the working directory relative to its [:Parent:parents] is recorded as a new [:Revision:revision]: |
Line 15: | Line 62: |
subgraph cluster_1 { style=filled; color="#eeeeee"; node [shape=box,style=filled,color=lightgray]; "rev 0" -> "rev 1" -> "rev 2" -> "rev 3"; label = "store"; } |
|
Line 23: | Line 63: |
label="working directory"; | |
Line 28: | Line 69: |
label="working directory"; } "rev 2" -> ".hgtags" [lhead = cluster_0 constraint=false] } }}} The store contains the '''complete''' history of the project. Unlike traditional SCMs, where there's only one central copy of this history, every working directory is paired with a private copy of the history. This allows development to go on in parallel. The working directory contains a copy of the project's files at a given point in time (eg rev 2), ready for editing. Because tags and ignored files are revision-controlled, they are also included. == Committing Changes == When you '''commit''', the state of the working directory relative to its parents is recorded as a new revision: {{{#!dot digraph G { compound=true; rankdir = LR background="#999999"; |
} |
Line 49: | Line 71: |
label = "store"; labelloc = b; |
|
Line 52: | Line 76: |
"rev 0" -> "rev 1" -> "rev 2" -> "rev 3"; "rev 2" -> "rev 4"; label = "store"; } subgraph cluster_0 { style=filled; color=lightgrey; node [style=filled,color=white]; edge [style=invis]; "main.c"-> "main.h" -> ".hgignore" -> ".hgtags" label="working directory"; } "rev 2" -> ".hgtags" [style = dotted lhead = cluster_0 constraint=false] "rev 4" -> ".hgtags" [lhead = cluster_0 constraint=false] ".hgtags" -> "rev 4" [color = red label = "commit" ltail = cluster_0 constraint=false] } }}} Note here that revision 4 is a '''branch''' off revision 2, which was the revision in the working directory. Now revision 4 is the working directory's '''parent'''. |
"rev 0" -> "rev 1" -> "rev 2" -> "rev 3" [dir=back]; "rev 2" -> "rev 4" [dir=back]; } "rev 2" -> ".hgtags" [dir=back, style=dotted, lhead=cluster_0, label="parent before commit"] "rev 4" -> ".hgtags" [dir=back, color=red, lhead=cluster_0, headlabel="commit", labelfontcolor=red ] } }}} Note here that revision 4 is a '''[:Branch:branch]''' of revision 2, which was the revision in the working directory. Now revision 4 is the working directory's '''parent'''. |
Line 74: | Line 88: |
Mercurial groups related changes to multiple files into single atomic '''changesets''', which are '''revisions''' of the whole project. These each get a sequential revision number. Because Mercurial allows distributed parallel development, these revision numbers may disagree between users. So Mercurial also assigns each revision a global '''changeset ID'''. Changeset IDs are 40-digit hexadecimal numbers, but they can be abbreviated to any unambiguous prefix, like "e38487". {{{#!dot digraph { rankdir = LR node [shape=box] "rev 0:838e" -> "rev 1:34ef" -> "rev 2:4563" "rev 1:34ef" -> "rev 3:fe56" "rev 2:4563" -> "rev 4:ac98" "rev 3:fe56" -> "rev 4:ac98" "rev 4:ac98" -> "rev 5:0345" "rev 4:ac98" -> "rev 6:19e3 (tip)" |
Mercurial groups related changes to multiple files into single atomic [:ChangeSet:changesets], which are revisions of the whole project. These each get a sequential [:RevisionNumber:revision number]. Because Mercurial allows distributed parallel development, these revision numbers may disagree between users. So Mercurial also assigns each revision a global [:ChangeSetID:changeset ID]. Changeset IDs are 40-digit hexadecimal numbers, but they can be abbreviated to any unambiguous prefix, like "e38487". {{{#!dot digraph { rankdir = LR node [shape=box] "rev 0:838e" -> "rev 1:34ef" -> "rev 2:4563" [dir=back] "rev 1:34ef" -> "rev 3:fe56" [dir=back] "rev 2:4563" -> "rev 4:ac98" [dir=back] "rev 3:fe56" -> "rev 4:ac98" [dir=back] "rev 4:ac98" -> "rev 5:0345" [dir=back] "rev 4:ac98" -> "rev 6:19e3 (tip)" [dir=back] |
Line 91: | Line 105: |
Branches and merges in the revision history can occur at any point. Each unmerged branch creates a new '''head''' of the revision history. Here, revisions 5 and 6 are heads. Mercurial considers revision 6 to be the '''tip''' of the repository, the head with the highest revision number. |
Branches and [:Merge:merges] in the revision history can occur at any point. Each unmerged branch creates a new [:Head:head] of the revision history. Here, revisions 5 and 6 are heads. Mercurial considers revision 6 to be the [:Tip:tip] of the repository, the head with the highest revision number. |
Line 103: | Line 117: |
a->b->c->d } }}} Bob '''clones''' this repo, and ends up with a complete copy of Alice's store (though his working directory is independent!): {{{#!dot digraph { label="Bob's Repo" rankdir = LR node [shape=box] a->b->c->d } }}} Bob then '''commits''' a couple changes: {{{#!dot digraph { label="Bob's Repo" rankdir = LR node [shape=box] a->b->c->d->e->f |
a->b->c->d [dir=back] } }}} Bob [:Clone:clones] this repo, and ends up with a complete copy of Alice's store (though his working directory is independent!): {{{#!dot digraph { label="Bob's Repo" rankdir = LR node [shape=box] a->b->c->d [dir=back] } }}} Bob then [:Commit:commits] a couple changes: {{{#!dot digraph { label="Bob's Repo" rankdir = LR node [shape=box] a->b->c->d->e->f [dir=back] |
Line 138: | Line 152: |
a->b->c->d->g | a->b->c->d->g [dir=back] |
Line 143: | Line 157: |
Bob then '''pulls''' Alice's repo to synchronize. This copies all of Alice's changes into Bob's repo: {{{#!dot digraph { label="Bob's Repo" rankdir = LR node [shape=box] a->b->c->d->e->f e [color=blue] f [color=blue] d->g |
Bob then [:Pull:pulls] Alice's repo to synchronize. This copies all of Alice's changes into Bob's repo: {{{#!dot digraph { label="Bob's Repo" rankdir = LR node [shape=box] a->b->c->d->e->f [dir=back] e [color=blue] f [color=blue] d->g [dir=back] |
Line 158: | Line 172: |
Because Alice's '''g''' is the newest head in Bob's repository, it's now the '''tip'''. Bob then does a '''merge''' which combines the last change he was working on ('''f''') with the tip, commits the result, and ends up with: {{{#!dot digraph { label="Bob's Repo" rankdir = LR node [shape=box] a->b->c->d->e->f e [color=blue] f [color=blue] d->g |
Because Alice's '''g''' is the newest head in Bob's repository, it's now the '''tip'''. Bob then does a [:Merge:merge] which combines the last change he was working on ('''f''') with the tip, commits the result, and ends up with: {{{#!dot digraph { label="Bob's Repo" rankdir = LR node [shape=box] a->b->c->d->e->f [dir=back] e [color=blue] f [color=blue] d->g [dir=back] |
Line 170: | Line 184: |
f->h g->h |
f->h [dir=back] g->h [dir=back] |
Line 183: | Line 197: |
a->b->c->d->g d->e->f |
a->b->c->d->g [dir=back] d->e->f [dir=back] |
Line 188: | Line 202: |
f->h g->h |
f->h [dir=back] g->h [dir=back] |
Line 196: | Line 210: |
Mercurial is a completely decentralized system, and thus has no internal notion of a central repository. Thus users are free to define their own topologies for sharing changes: | Mercurial is a completely decentralized system, and thus has no internal notion of a central repository. Thus users are free to define their own topologies for sharing changes (see CommunicatingChanges): |
Line 216: | Line 230: |
== What Mercurial can't do == Many SVN/CVS users expect to host related projects together in one repository. This is really not what hg was made for, so you should try a different way of working. This especially means, that you cannot check out only one directory of a repository. If you absolutely need to host multiple projects in a kind of meta-repository though, you could try the ForestExtension. |
Mercurial's decentralized development model can be confusing to new users. This page attempts to illustrate some of the basic concepts. See the ["Tutorial"] for step-by-step instructions.
(Translations: [:BrazilianPortugueseUnderstandingMercurial:Brazilian Portuguese], [:ChineseUnderstandingMercurial:Chinese], [:FrenchUnderstandingMercurial:French], [:GermanUnderstandingMercurial:German], [:ItalianUnderstandingMercurial:Italian], [:JapaneseUnderstandingMercurial:Japanese], [:KoreanUnderstandingMercurial:Korean], [:RussianUnderstandingMercurial:Russian], [:SpanishUnderstandingMercurial:Spanish] )
What's in a Repository
Mercurial [:Repository:repositories] contain a [:WorkingDirectory:working directory] coupled with a store:
The store contains the complete history of the project. Unlike traditional [:SCM:SCMs], where there's only one central copy of this history, every working directory is paired with a private copy of the history. This allows development to go on in parallel.
The working directory contains a copy of the project's files at a given point in time (eg rev 2), ready for editing. Because [:Tag:tags] and ignored files are revision-controlled, they are also included.
Committing Changes
When you [:Commit:commit], the state of the working directory relative to its [:Parent:parents] is recorded as a new [:Revision:revision]:
Note here that revision 4 is a [:Branch:branch] of revision 2, which was the revision in the working directory. Now revision 4 is the working directory's parent.
Revisions, Changesets, Heads, and Tip
Mercurial groups related changes to multiple files into single atomic [:ChangeSet:changesets], which are revisions of the whole project. These each get a sequential [:RevisionNumber:revision number]. Because Mercurial allows distributed parallel development, these revision numbers may disagree between users. So Mercurial also assigns each revision a global [:ChangeSetID:changeset ID]. Changeset IDs are 40-digit hexadecimal numbers, but they can be abbreviated to any unambiguous prefix, like "e38487".
Branches and [:Merge:merges] in the revision history can occur at any point. Each unmerged branch creates a new [:Head:head] of the revision history. Here, revisions 5 and 6 are heads. Mercurial considers revision 6 to be the [:Tip:tip] of the repository, the head with the highest revision number.
Cloning, Making Changes, Merging, and Pulling
Let's start with a user Alice, who has a store that looks like:
Bob [:Clone:clones] this repo, and ends up with a complete copy of Alice's store (though his working directory is independent!):
Bob then [:Commit:commits] a couple changes:
Alice then makes her own change in parallel:
Bob then [:Pull:pulls] Alice's repo to synchronize. This copies all of Alice's changes into Bob's repo:
Because Alice's g is the newest head in Bob's repository, it's now the tip. Bob then does a [:Merge:merge] which combines the last change he was working on (f) with the tip, commits the result, and ends up with:
Now if Alice pulls from Bob, she will get Bob's changes e, f, and h, and they will be fully synchronized:
A Decentralized System
Mercurial is a completely decentralized system, and thus has no internal notion of a central repository. Thus users are free to define their own topologies for sharing changes (see CommunicatingChanges):
What Mercurial can't do
Many SVN/CVS users expect to host related projects together in one repository. This is really not what hg was made for, so you should try a different way of working. This especially means, that you cannot check out only one directory of a repository. If you absolutely need to host multiple projects in a kind of meta-repository though, you could try the ForestExtension.
For a hands-on introduction to using Mercurial, see the ["Tutorial"].