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.
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.
If you already have Mercurial installed, make sure you have version 1.7 or later. To check, enter hg --version at the command line.
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 .
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.
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)
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.
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.
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:
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.
hg
's gutsThere 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With