Skip to content

Latest commit

 

History

History
127 lines (109 loc) · 5.73 KB

File metadata and controls

127 lines (109 loc) · 5.73 KB

Mercurial

Omdat Mercurial and Git een redelijk overeenkomend model hebben om versies te representeren en omdat Git iets flexibeler is, is het converteren van een repository uit Mercurial naar Git minder omslachtig, gebruik makend van een instrument dat "hg-fast-export" heet, waar je een kopie van nodig gaat hebben:

$ git clone https://github.com/frej/fast-export.git

De eerste stap in de conversie is om een volledige kloon van de Mercurial repository die je wilt converteren te maken:

$ hg clone <remote repo URL> /tmp/hg-repo

De volgende stap is om een auteur-mapping bestand te maken. Mercurial is wat minder streng dan Git voor wat het in het auteur veld zet voor changesets, dus dit is een goed moment om schoon schip te maken. Het aanmaken hiervan is een enkele commando regel in een bash shell:

$ cd /tmp/hg-repo
$ hg log | grep user: | sort | uniq | sed 's/user: *//' > ../authors

Dit duurt een paar tellen, afhankelijk van de lengte van de geschiedenis van je project, en nadien ziet het /tmp/authors bestand er ongeveer zo uit:

bob
bob@localhost
bob <bob@company.com>
bob jones <bob <AT> company <DOT> com>
Bob Jones <bob@company.com>
Joe Smith <joe@company.com>

In dit voorbeeld, heeft dezelfde persoon (Bob) changesets aangemaakt onder vier verschillende namen, waarvan er één er wel correct uitziet, en één ervan zou voor een Git commit helemaal niet geldig zijn. Hg-fast-export laat ons dit corrigeren door elke regel in een instructie te veranderen: "<invoer>"="<uitvoer>", waarbij <invoer> in een <uitvoer> wordt gewijzigd. Binnen de <invoer> en <uitvoer> tekenreeksen, worden alle 'escaped' reeksen die door de python string_escape encoding worden begrepen ondersteund. Als het auteur mapping-bestand geen passende <invoer> regel heeft, wordt deze ongewijzigd doorgestuurd naar Git. Als alle gebruikersnamen er goed uitzien, hebben we dit bestand helemaal niet nodig. In ons voorbeeld, willen we dat ons bestand er zo uit ziet:

"bob"="Bob Jones <bob@company.com>"
"bob@localhost"="Bob Jones <bob@company.com>"
"bob <bob@company.com>"="Bob Jones <bob@company.com>"
"bob jones <bob <AT> company <DOT> com>"="Bob Jones <bob@company.com>"

Hetzelfde soort mapping bestand kan worden gebruikt om branches en tags te hernoemen als de Mercurial naam niet wordt toegestaan door Git.

De volgende stap is om onze nieuwe Git repository aan te maken en het volgende export script aan te roepen:

$ git init /tmp/converted
$ cd /tmp/converted
$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors

De -r vlag vertelt hg-fast-export waar het de Mercurial repository kan vinden die we willen converteren, en de -A vlag vertelt het waar het auteur-mapping bestand te vinden is. Het script verwerkt Mercurial changesets en converteert ze in een script voor de "fast-import" functie (die we iets later zullen bespreken). Dit duurt even (al is het veel sneller dan het via het netwerk zou zijn), en de uitvoer is nogal breedsprakig:

$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
Loaded 4 authors
master: Exporting full revision 1/22208 with 13/0/0 added/changed/removed files
master: Exporting simple delta revision 2/22208 with 1/1/0 added/changed/removed files
master: Exporting simple delta revision 3/22208 with 0/1/0 added/changed/removed files
[…]
master: Exporting simple delta revision 22206/22208 with 0/4/0 added/changed/removed files
master: Exporting simple delta revision 22207/22208 with 0/2/0 added/changed/removed files
master: Exporting thorough delta revision 22208/22208 with 3/213/0 added/changed/removed files
Exporting tag [0.4c] at [hg r9] [git :10]
Exporting tag [0.4d] at [hg r16] [git :17]
[…]
Exporting tag [3.1-rc] at [hg r21926] [git :21927]
Exporting tag [3.1] at [hg r21973] [git :21974]
Issued 22315 commands
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:     120000
Total objects:       115032 (    208171 duplicates                  )
      blobs  :        40504 (    205320 duplicates      26117 deltas of      39602 attempts)
      trees  :        52320 (      2851 duplicates      47467 deltas of      47599 attempts)
      commits:        22208 (         0 duplicates          0 deltas of          0 attempts)
      tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:         109 (         2 loads     )
      marks:        1048576 (     22208 unique    )
      atoms:           1952
Memory total:          7860 KiB
       pools:          2235 KiB
     objects:          5625 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =      90430
pack_report: pack_mmap_calls          =      46771
pack_report: pack_open_windows        =          1 /          1
pack_report: pack_mapped              =  340852700 /  340852700
---------------------------------------------------------------------

$ git shortlog -sn
   369  Bob Jones
   365  Joe Smith

Meer valt er eigenlijk niet over te vertellen. Alle Mercurial tags zijn geconverteerd naar Git tags, en Mercurial branches en boekleggers (bookmarks) zijn geconverteerd naar Git branches. Nu ben je klaar om de repository naar zijn nieuwe server-thuis te sturen:

$ git remote add origin git@my-git-server:myrepository.git
$ git push origin --all