Reputation: 56362
I've been using git for a while now, and since it is the only DVCS I have ever used, I've learned to rely a lot on the way it works for my workflow.
I'm in a new company now, and they use Mercurial, so I need to understand Mercurial's model and how it differs from git, to adapt my workflow and avoid making costly mistakes.
So what resources can I use for this?
Upvotes: 5
Views: 584
Reputation: 6114
Quite extended concept differences from Mercurial's official wiki.
Another question from stackoverflow: Git equivalents of most common Mercurial commands?
If I resume: "model", "differences", "philosophy behind the differences" and influences on the "workflow". In the differences I can think of, there is:
Storage differs greatly in implementation, but not in concepts (as you asked for "model", I will put more details):
Git stores data as "objects" ("commit object", "tree object", "blob object" or "tag object", stored as file uniquely identified by there name which is a SHA1 hash). This is some kind of "filesystem hash table". With recent versions, those objects can be packed to have less small files under the .git/objects
directory. I will not go further, my understanding stop here as I never found use to know how bits are laid. You can have a pretty printing in the object's content with:
git show -s --format=raw <commitid> # changeset content
git ls-tree <treeid> # list tree content
git show <fileid> # blob content
Mercurial stores history of each files individually as "filelog" in the "revlog(NG)" format. You can manually inspect file names under .hg/store/data
(revlogNG). Note that special and uppercase characters are "tilda-underscore encoded".
You can list revisions of a file with:
hg debugindex .hg/store/data/<file>.i # hg debugindex <file> also works but you see less of internals
You have already noted that the nodeid
s are not the one in hg log
.
And now, inspect the contents with:
hg debugdata .hg/store/data/<file>.i <nodeid>
The revision history (more or less what you see with hg log
) is stored in .hg/store/00changelog.i
(inspect it with hg debugindex .hg/store/00changelog.i
, you will see the same IDs as the one in hg log
in the nodeid
column). To show one raw history entry with id XXXX
, type hg debugdata .hg/store/00changelog.i XXXX
in a terminal. (look at first line, it will be used later as YYYY
)
The state of the tree is stored in .hg/store/00manifest.i
. The corresponding nodeid
in the manifest is YYYY
.
hg debugdata .hg/store/00manifest.i YYYY
This will show a list of "filename+nodeid" appended. Let's choose file foo/bar
and note the nodeid
appended to it and consider it is ZZZZ
(line foo/barZZZZ
).
Last step, access to the content of the foo/bar
file:
hg debugdata .hg/store/data/foo/bar.i ZZZZ
For the differences in philosophy clearly visible from this basic data storage analysis:
When Git commits, it make (potentially a lot of) new files (which can be packed later). When Mercurial commits, it appends to existing files.
In Git a blobid
can collide with a treeid
(or commitid
or tagid
) but that is highly improbable. In Mercurial, a changesetid
can collide only with another changesetid
(ditto for manifests (tree) and files (blob)) which is even more improbable.
Upvotes: 8