Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mercurial repository identification

Tags:

mercurial

I need to be able to uniquely identify a Mercurial repository and have that identifier placed in a file that is included when cloned. If I can put the identifier in a file in the .hg folder that is preferable to simply adding a normal file to the repo.

I understand that I can get a near certain identifier from the first changes that are committed. I know that the hgrc file cannot be used to store the identifier, because it is not cloned.

So, my question is: Is there another file in the .hg folder that is cloned that I can use to put the identifier? Thanks.

like image 646
RandyR Avatar asked Jun 10 '11 13:06

RandyR


People also ask

What is a Mercurial repository?

Mercurial is a free, distributed version control system. It's also referred to as a revision control system or Mercurial source control. It is used by software development teams to manage and track changes across projects.

How do I know my Mercurial version?

If you already have Mercurial installed, make sure you have version 1.7 or later. To check, enter hg --version at the command line.

What is the repository root?

The repository root directory is the parent directory of the . hg directory. Mercurial stores its internal data structures – the metadata – inside that . hg directory. All of the files and directories that coexist with the .

How to identify a Mercurial repository fairly uniquely?

If you would like to be able to identify a Mercurial repository “fairly uniquely” using a short string as an identifier, you can use the first revision in the repository. This is likely to be unique, and so it is useful in many cases. There are a few caveats.

How does mercurial update the working directory of a source repository?

Mercurial will update the working directory to the first applicable revision from this list: null if -U or the source repository has no changesets if -u . and the source repository is local, the first parent of the source repository's working directory the changeset specified with -u (if a branch name, this means the latest head of that branch)

How to commit modified subrepositories in mercurial?

Mercurial can be made to instead commit all modified subrepositories by specifying -S/--subrepos, or setting "ui.commitsubrepos=True" in a configuration file (see hg help config). After there are no longer any modified subrepositories, it records their state and finally commits it in the parent repository.

What are mercurial's log-like commands?

All of Mercurial's “ log -like” commands let you use styles and templates: hg incoming, hg log, hg outgoing and so on. At its simplest, a Mercurial template is a piece of text.


1 Answers

From first read, it sounds like you want to be able to make sure that a clone of the repository is a clone of the correct repository and not some stand-in impostor. However, if the identification information you're thinking of using is cloned with everything else, then an impostor would still pass this test. You'd need to keep that identifier separate so that it can be compared against information in the clone.

Whether that is your purpose or not, any file in .hg that is cloned you may not want to edit. You'd have to add a file to be tracked in the other areas of the repo, outside of .hg. However, you don't really need an extra file at all, as the changeset hash is not just near certain, but very certain, so the information for handily identifying a repository is built-in to the repository itself.

On the commandline, you can get either the short or full versions of the very first changeset's hash identifier:

> hg id -i -r0
89abf5502e3c

> hg log -r0 --template "{node}"
89abf5502e3c5c65e532db04d8d87141f0ac8b73

If I am correct about your desire to compare 2 identifiers so that you or someone else knows a clone of the repository is a true clone and not a false clone, you would have the same changset id available separately so that someone can use one of the above commands to see the id of their clone and compare it to what you say it should be. This is much like how many websites with downloadable executable files show a hash identifier next to the download link so that you can hash the file yourself and compare the result to the hash on the website.

Edit regarding your comment that sheds light on the purpose of this:

Since you need to be able to read it from a file, there are a couple options:

Tracked file in repository root

There is one file you might consider, other than creating your own: .hgtags.

hg tag -r0 ident

...would tag the very first revision, allowing you to use ident as a reference to that changeset rather than -r0. Mercurial always uses tag information from the latest version of .hgtags, no matter what changeset the working directory is updated to, but that may not matter to your app. hg tag appends a line such as this to the .hgtags file, creating the file if it doesn't exist:

a247494248c4b96a571bbd12e90eade3bf559281 ident

This is most handy if you don't have a tags files yet in your repos, because it will be the first line in the file for easy finding. You might think could simply write this file yourself, but then you'd still have to call hg to get the changeset id and again at some point for adding it to tracking and then committing: hg tag does all that for you.

If there is already the possibility of a tags file to consider, that's ok, too, because they tend to be relatively short and you just need to look for the 1 line that ends with your chosen tag name. Mercurial is designed for append-only operations to .hgtags, but everything would still work fine if you inserted the line for this tag as the very first line if .hgtags already exists because: 1. The tag will never be moved or removed. 2. You'll be using a tag name not already used in the file.

Reading hg's guts

There are files that normally only Mercurial itself touches deeper in .hg that can be read to get the first changeset's hash. I looked into Mercurial's File Formats, Revlog, and RevlogNG, and at least for 2 of my own repos, .hg\store\00changelog.i contains the first changeset's hash at offset 0x20 (20 byte length). Probably, at least since Mercurial 0.9, it will be the same in all repos. RevlogNG also notes the first 4 bytes of that file will indicate Revlog version number and flags. While the changeset id is only 20 bytes long currently, the actual field for it is 32 bytes long, probably for future expansion to a longer hash.

Since this option requires no alteration of existing repositories and only involves reading the first 52-64 bytes of the main index, it's the one I'd probably go with. If I was catching this requirement in the early stages of the product before any repos it manages were out in the wild, I would lean toward the custom file approach because I would probably have my own metadata file created and added from the beginning of the repo.

like image 177
Joel B Fant Avatar answered Nov 05 '22 05:11

Joel B Fant