2012-02-02 4 views
3

Est-il possible d'obtenir un ID de fichier immutable pour un fichier dans le référentiel?ID du fichier mercurial

J'ai besoin d'un identifiant qui survivra à un changement de nom de fichier. Donc s'il y avait le fichier Test01.txt et il a été renommé Test02.txt (en utilisant l'élément de menu Renommer TortoiseHG ou la commande hg rename). Je veux avoir un ID qui correspondra à Test01.txt à la révision 1 et Test02.txt à la révision 2.

Répondre

4

Mercurial ne donne aucun ID aux fichiers. Ceci est différent de certains autres systèmes, tels que Bazaar, où chaque fichier (et répertoire) a un ID unique qui suit le fichier tout au long de sa durée de vie.

La structure dans un référentiel mercuriel est le suivant:

  • chaque entrée dans la changelog a un seul pointeur vers
    • une entrée dans le manifeste , qui a un pointeur pour le fichier à
      • une entrée dans FileLog du fichier

Donc, si vous ajoutez Test01.txt dans la révision 0, alors vous aurez une chaîne comme celui-ci

[email protected] -> [email protected] -> [email protected] 

Si vous renommez maintenant et faites un commit, vous allez créer une nouvelle changelog et entrée manifeste, et de créer une nouvelle FileLog pour Test02.txt:

[email protected] -> [email protected] -> [email protected] 

La nouvelle entrée filelog Test02.txt fait référence à l'entrée Test01.txt. Voici comment Mercurial peut garder une trace de renommages:

$ hg debugdata Test02.txt 0 

copy: Test01.txt 
copyrev: 0936f74a58571dd87ad343cc3d6ae8434ad86fc4 

test01 

Le meilleur « fichier ID », vous pouvez parler est donc l'ID de la première entrée dans le journal de fichier d'origine. Vous pouvez creuser avec hg debugindex:

$ hg debugindex Test01.txt 
    rev offset length base linkrev nodeid  p1   p2 
    0   0  8  0  0 0936f74a5857 000000000000 000000000000 

La colonne « nodeid » vous donne les ID des revlog entries dans le FileLog pour Test01.txt. Ici, nous voyons que la première révision du fichier a l'ID 0936f74a5857. Ceci est juste un court préfixe de 12 caractères du hachage SHA-1 complet de 40 caractères. Le "linkrev" vous indique que cette version du fichier est référencée par changeset 0. Vous pouvez rechercher les données dans cette entrée changelog avec hg debugdata -c 0, mais pour notre fins la commande hg log normale a également les informations:

$ hg log -r 0 --debug 
changeset: 0:8e62ecaada0e5ba9efec234d0d9a66583347becf 
phase:  draft 
parent:  -1:0000000000000000000000000000000000000000 
parent:  -1:0000000000000000000000000000000000000000 
manifest: 0:0537c846cd545da8f826b9d94fdb2fdae457bd07 
user:  Martin Geisler <[email protected]> 
date:  Thu Feb 02 09:00:18 2012 +0100 
files+:  Test01.txt 
extra:  branch=default 
description: 
01 

Nous sommes intéressés par l'ID manifeste.Vous pouvez maintenant rechercher les données dans l'entrée correcte manifeste avec:

$ hg debugdata -m 0537c846cd545da8f826b9d94fdb2fdae457bd07 
Test01.txt0936f74a58571dd87ad343cc3d6ae8434ad86fc4 

Il y a vraiment un octet NUL entre le nom du fichier et l'ID FileLog, mais ce n'est pas visible dans votre terminal. Vous avez maintenant l'ID filelog complet pour la première révision du fichier Test01.txt. Vous devez également passer de Test02.txt à Test01.txt. Vous pouvez utiliser hg log --follow et hg debugrename pour cela: utilisez hg log pour obtenir les révisions concernant le fichier, et utilisez hg debugrename pour voir de quoi le fichier a été renommé à chaque étape.

+0

Réponse incroyable, vous avez fait ma journée! – adontz

+1

Mais si vous copiez le fichier, aura-t-il le même ID de fichier? C'est-à-dire que le hachage est basé sur le contenu du fichier ou est-il salé avec, par ex. l'ID de changeset? –

+1

@LaurensHolst: Bonne question! L'ID dont je parle ici est le hachage qui est calculé lorsque la première entrée de filelog (révision) est ajoutée. L'entrée se compose uniquement du contenu du fichier afin que les fichiers ayant un contenu identique obtiennent le même identifiant de fichier. –