changeset 187:5f196f80ffb3

Store git tags in .hg/git-tags and let localtags be *local*
author Abderrahim Kitouni <a.kitouni@gmail.com>
date Thu, 18 Jun 2009 22:38:09 +0100
parents f4caf22b87cd
children 5d48a2310e16
files git_handler.py hgrepo.py
diffstat 2 files changed, 57 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/git_handler.py
+++ b/git_handler.py
@@ -23,6 +23,7 @@
         self.repo = dest_repo
         self.ui = ui
         self.mapfile = 'git-mapfile'
+        self.tagsfile = 'git-tags'
 
         if ui.config('git', 'intree'):
             self.gitdir = self.repo.wjoin('.git')
@@ -37,6 +38,7 @@
         self.init_if_missing()
         self.load_git()
         self.load_map()
+        self.load_tags()
 
     # make the git data directory
     def init_if_missing(self):
@@ -74,6 +76,20 @@
             file.write("%s %s\n" % (gitsha, hgsha))
         file.rename()
 
+
+    def load_tags(self):
+        self.tags = {}
+        if os.path.exists(self.repo.join(self.tagsfile)):
+            for line in self.repo.opener(self.tagsfile):
+                sha, name = line.strip().split(' ', 1)
+                self.tags[name] = sha
+
+    def save_tags(self):
+        file = self.repo.opener(self.tagsfile, 'w+', atomictemp=True)
+        for name, sha in sorted(self.tags.iteritems()):
+            file.write("%s %s\n" % (sha, name))
+        file.rename()
+
     ## END FILE LOAD AND SAVE METHODS
 
     ## COMMANDS METHODS
@@ -90,7 +106,7 @@
 
         if refs:
             self.import_git_objects(remote_name, refs)
-            self.import_local_tags(refs)
+            self.import_tags(refs)
             self.update_hg_bookmarks(refs)
             if remote_name:
                 self.update_remote_branches(remote_name, refs)
@@ -695,11 +711,8 @@
 
     def export_hg_tags(self):
         for tag, sha in self.repo.tags().iteritems():
-            if tag[-3:] == '^{}':
-                continue
-            if tag == 'tip':
-                continue
-            self.git.set_ref('refs/tags/' + tag, self.map_git_get(hex(sha)))
+            if self.repo.tagtype(tag) == 'git':
+                self.git.set_ref('refs/tags/' + tag, self.map_git_get(hex(sha)))
 
     # Make sure there's a refs/remotes/remote_name/name
     #           for every refs/heads/name
@@ -711,12 +724,11 @@
         refs = self.git.get_refs()
         return dict(filter(is_local_head, refs.items()))
 
-    # take refs just fetched, add local tags for all tags not in .hgtags
-    def import_local_tags(self, refs):
+    def import_tags(self, refs):
         keys = refs.keys()
         if not keys:
-            return None
-        for k in keys[0:]:
+            return
+        for k in keys[:]:
             ref_name = k
             parts = k.split('/')
             if (parts[0] == 'refs' and parts[1] == 'tags'):
@@ -728,13 +740,15 @@
                     sha = None
                     if isinstance (obj, Commit): # lightweight
                         sha = self.map_hg_get(refs[k])
-                    if isinstance (obj, Tag): # annotated
+                        self.tags[ref_name] = sha
+                    elif isinstance (obj, Tag): # annotated
                         (obj_type, obj_sha) = obj.get_object()
                         obj = self.git.get_object(obj_sha)
                         if isinstance (obj, Commit):
                             sha = self.map_hg_get(obj_sha)
-                    if sha:
-                        self.repo.tag(ref_name, hex_to_sha(sha), '', True, None, None)
+                            # TODO: better handling for annotated tags
+                            self.tags[ref_name] = sha
+        self.save_tags()
 
     def update_hg_bookmarks(self, refs):
         try:
--- a/hgrepo.py
+++ b/hgrepo.py
@@ -151,4 +151,34 @@
         else:
             super(hgrepo, self).push(remote, force, revs)
 
+    def tag(self, names, node, message, local, user, date):
+        if local:
+            super(hgrepo, self).tag(names, node, message, local, user, date)
+            return
+
+        if isinstance(names, str):
+            names = (names,)
+
+        allchars = ''.join(names)
+        for c in self.tag_disallowed:
+            if c in allchars:
+                raise util.Abort('%r cannot be used in a tag name' % c)
+
+        git = GitHandler(self, self.ui)
+        for name in names:
+            git.tags[name] = hex(node)
+
+        git.save_tags()
+
+    def tags(self):
+        if self.tagscache:
+            return self.tagscache
+
+        git = GitHandler(self, self.ui)
+        tagscache = super(hgrepo, self).tags()
+        tagscache.update(dict([(tag, bin(rev)) for (tag,rev) in git.tags.iteritems()]))
+        tagstypes = dict([(tag, 'git') for tag in git.tags])
+        self._tagstypecache.update(tagstypes)
+        return tagscache
+
 instance = hgrepo