remote-hg: use notes to keep track of Hg revisions
Keep track of Mercurial revisions as Git notes under the 'refs/notes/hg' ref. This way, the user can easily see which Mercurial revision corresponds to certain Git commit. Unfortunately, there's no way to efficiently update the notes after doing an export (push), so they'll have to be updated when importing (fetching). Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Felipe Contreras committed
Aug 29, 2013 at 17:29 UTC
c587d655122a287a6796d493d176128f05374156
1 file changed
+34
-1
contrib/remote-helpers/git-remote-hg
+34
-1
@@ -23,7 +23,11 @@ import subprocess
23
import urllib
24
import atexit
25
import urlparse, hashlib
26
+import time as ptime
27
28
+#
29
+# If you want to see Mercurial revisions as Git commit notes:
30
+# git config core.notesRef refs/notes/hg
31
#
32
# If you are not in hg-git-compat mode and want to disable the tracking of
33
# named branches:
@@ -126,6 +130,7 @@ class Marks:
130
self.rev_marks = {}
131
self.last_mark = 0
132
self.version = 0
133
+ self.last_note = 0
134
135
def load(self):
136
if not os.path.exists(self.path):
@@ -137,6 +142,7 @@ class Marks:
142
self.marks = tmp['marks']
143
self.last_mark = tmp['last-mark']
144
self.version = tmp.get('version', 1)
145
+ self.last_note = tmp.get('last-note', 0)
146
147
for rev, mark in self.marks.iteritems():
148
self.rev_marks[mark] = rev
@@ -150,7 +156,7 @@ class Marks:
156
self.version = 2
157
158
def dict(self):
153
- return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark, 'version' : self.version }
159
+ return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark, 'version' : self.version, 'last-note' : self.last_note }
160
161
def store(self):
162
json.dump(self.dict(), open(self.path, 'w'))
@@ -512,6 +518,31 @@ def export_ref(repo, name, kind, head):
518
print "from :%u" % rev_to_mark(head)
519
print
520
521
+ pending_revs = set(revs) - notes
522
+ if pending_revs:
523
+ note_mark = marks.next_mark()
524
+ ref = "refs/notes/hg"
525
+
526
+ print "commit %s" % ref
527
+ print "mark :%d" % (note_mark)
528
+ print "committer remote-hg <> %s" % (ptime.strftime('%s %z'))
529
+ desc = "Notes for %s\n" % (name)
530
+ print "data %d" % (len(desc))
531
+ print desc
532
+ if marks.last_note:
533
+ print "from :%u" % marks.last_note
534
+
535
+ for rev in pending_revs:
536
+ notes.add(rev)
537
+ c = repo[rev]
538
+ print "N inline :%u" % rev_to_mark(c)
539
+ msg = c.hex()
540
+ print "data %d" % (len(msg))
541
+ print msg
542
+ print
543
+
544
+ marks.last_note = note_mark
545
+
546
marks.set_tip(ename, head.hex())
547
548
def export_tag(repo, tag):
@@ -1113,6 +1144,7 @@ def main(args):
1144
global filenodes
1145
global fake_bmark, hg_version
1146
global dry_run
1147
+ global notes, alias
1148
1149
alias = args[1]
1150
url = args[2]
@@ -1152,6 +1184,7 @@ def main(args):
1184
except:
1185
hg_version = None
1186
dry_run = False
1187
+ notes = set()
1188
1189
repo = get_repo(url, alias)
1190
prefix = 'refs/hg/%s' % alias