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?
Quite extended concept differences from Mercurial’s official wiki.
Another question from stackoverflow: Git equivalents of most common Mercurial commands?
Comment follow up:
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/objectsdirectory. 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: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:
You have already noted that the
nodeids are not the one inhg log.And now, inspect the contents with:
The revision history (more or less what you see with
hg log) is stored in.hg/store/00changelog.i(inspect it withhg debugindex .hg/store/00changelog.i, you will see the same IDs as the one inhg login thenodeidcolumn). To show one raw history entry with idXXXX, typehg debugdata .hg/store/00changelog.i XXXXin a terminal. (look at first line, it will be used later asYYYY)The state of the tree is stored in
.hg/store/00manifest.i. The correspondingnodeidin the manifest isYYYY.This will show a list of “filename+nodeid” appended. Let’s choose file
foo/barand note thenodeidappended to it and consider it isZZZZ(linefoo/barZZZZ).Last step, access to the content of the
foo/barfile: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
blobidcan collide with atreeid(orcommitidortagid) but that is highly improbable. In Mercurial, achangesetidcan collide only with anotherchangesetid(ditto for manifests (tree) and files (blob)) which is even more improbable.