94 fnodes = _getfnodes(ui, repo, nodes) |
93 fnodes = _getfnodes(ui, repo, nodes) |
95 fnodes = _filterfnodes(fnodes, nodes) |
94 fnodes = _filterfnodes(fnodes, nodes) |
96 return fnodes |
95 return fnodes |
97 |
96 |
98 |
97 |
99 def _nulltonone(value): |
98 def _nulltonone(repo, value): |
100 """convert nullid to None |
99 """convert nullid to None |
101 |
100 |
102 For tag value, nullid means "deleted". This small utility function helps |
101 For tag value, nullid means "deleted". This small utility function helps |
103 translating that to None.""" |
102 translating that to None.""" |
104 if value == nullid: |
103 if value == repo.nullid: |
105 return None |
104 return None |
106 return value |
105 return value |
107 |
106 |
108 |
107 |
109 def difftags(ui, repo, oldfnodes, newfnodes): |
108 def difftags(ui, repo, oldfnodes, newfnodes): |
121 newtags = _tagsfromfnodes(ui, repo, newfnodes) |
120 newtags = _tagsfromfnodes(ui, repo, newfnodes) |
122 |
121 |
123 # list of (tag, old, new): None means missing |
122 # list of (tag, old, new): None means missing |
124 entries = [] |
123 entries = [] |
125 for tag, (new, __) in newtags.items(): |
124 for tag, (new, __) in newtags.items(): |
126 new = _nulltonone(new) |
125 new = _nulltonone(repo, new) |
127 old, __ = oldtags.pop(tag, (None, None)) |
126 old, __ = oldtags.pop(tag, (None, None)) |
128 old = _nulltonone(old) |
127 old = _nulltonone(repo, old) |
129 if old != new: |
128 if old != new: |
130 entries.append((tag, old, new)) |
129 entries.append((tag, old, new)) |
131 # handle deleted tags |
130 # handle deleted tags |
132 for tag, (old, __) in oldtags.items(): |
131 for tag, (old, __) in oldtags.items(): |
133 old = _nulltonone(old) |
132 old = _nulltonone(repo, old) |
134 if old is not None: |
133 if old is not None: |
135 entries.append((tag, old, None)) |
134 entries.append((tag, old, None)) |
136 entries.sort() |
135 entries.sort() |
137 return entries |
136 return entries |
138 |
137 |
450 valid = (tiprev, tipnode, scmutil.filteredhash(repo, tiprev)) |
449 valid = (tiprev, tipnode, scmutil.filteredhash(repo, tiprev)) |
451 |
450 |
452 repoheads = repo.heads() |
451 repoheads = repo.heads() |
453 # Case 2 (uncommon): empty repo; get out quickly and don't bother |
452 # Case 2 (uncommon): empty repo; get out quickly and don't bother |
454 # writing an empty cache. |
453 # writing an empty cache. |
455 if repoheads == [nullid]: |
454 if repoheads == [repo.nullid]: |
456 return ([], {}, valid, {}, False) |
455 return ([], {}, valid, {}, False) |
457 |
456 |
458 # Case 3 (uncommon): cache file missing or empty. |
457 # Case 3 (uncommon): cache file missing or empty. |
459 |
458 |
460 # Case 4 (uncommon): tip rev decreased. This should only happen |
459 # Case 4 (uncommon): tip rev decreased. This should only happen |
497 validated_fnodes = set() |
496 validated_fnodes = set() |
498 unknown_entries = set() |
497 unknown_entries = set() |
499 for node in nodes: |
498 for node in nodes: |
500 fnode = fnodescache.getfnode(node) |
499 fnode = fnodescache.getfnode(node) |
501 flog = repo.file(b'.hgtags') |
500 flog = repo.file(b'.hgtags') |
502 if fnode != nullid: |
501 if fnode != repo.nullid: |
503 if fnode not in validated_fnodes: |
502 if fnode not in validated_fnodes: |
504 if flog.hasnode(fnode): |
503 if flog.hasnode(fnode): |
505 validated_fnodes.add(fnode) |
504 validated_fnodes.add(fnode) |
506 else: |
505 else: |
507 unknown_entries.add(node) |
506 unknown_entries.add(node) |
508 cachefnode[node] = fnode |
507 cachefnode[node] = fnode |
509 |
508 |
510 if unknown_entries: |
509 if unknown_entries: |
511 fixed_nodemap = fnodescache.refresh_invalid_nodes(unknown_entries) |
510 fixed_nodemap = fnodescache.refresh_invalid_nodes(unknown_entries) |
512 for node, fnode in pycompat.iteritems(fixed_nodemap): |
511 for node, fnode in pycompat.iteritems(fixed_nodemap): |
513 if fnode != nullid: |
512 if fnode != repo.nullid: |
514 cachefnode[node] = fnode |
513 cachefnode[node] = fnode |
515 |
514 |
516 fnodescache.write() |
515 fnodescache.write() |
517 |
516 |
518 duration = util.timer() - starttime |
517 duration = util.timer() - starttime |
630 m = munge(name) |
629 m = munge(name) |
631 else: |
630 else: |
632 m = name |
631 m = name |
633 |
632 |
634 if repo._tagscache.tagtypes and name in repo._tagscache.tagtypes: |
633 if repo._tagscache.tagtypes and name in repo._tagscache.tagtypes: |
635 old = repo.tags().get(name, nullid) |
634 old = repo.tags().get(name, repo.nullid) |
636 fp.write(b'%s %s\n' % (hex(old), m)) |
635 fp.write(b'%s %s\n' % (hex(old), m)) |
637 fp.write(b'%s %s\n' % (hex(node), m)) |
636 fp.write(b'%s %s\n' % (hex(node), m)) |
638 fp.close() |
637 fp.close() |
639 |
638 |
640 prevtags = b'' |
639 prevtags = b'' |
760 any potentially expensive computation being performed. |
759 any potentially expensive computation being performed. |
761 |
760 |
762 If an .hgtags does not exist at the specified revision, nullid is |
761 If an .hgtags does not exist at the specified revision, nullid is |
763 returned. |
762 returned. |
764 """ |
763 """ |
765 if node == nullid: |
764 if node == self._repo.nullid: |
766 return nullid |
765 return node |
767 |
766 |
768 ctx = self._repo[node] |
767 ctx = self._repo[node] |
769 rev = ctx.rev() |
768 rev = ctx.rev() |
770 |
769 |
771 self.lookupcount += 1 |
770 self.lookupcount += 1 |
824 # Populate missing entry. |
823 # Populate missing entry. |
825 try: |
824 try: |
826 fnode = ctx.filenode(b'.hgtags') |
825 fnode = ctx.filenode(b'.hgtags') |
827 except error.LookupError: |
826 except error.LookupError: |
828 # No .hgtags file on this revision. |
827 # No .hgtags file on this revision. |
829 fnode = nullid |
828 fnode = self._repo.nullid |
830 return fnode |
829 return fnode |
831 |
830 |
832 def setfnode(self, node, fnode): |
831 def setfnode(self, node, fnode): |
833 """Set the .hgtags filenode for a given changeset.""" |
832 """Set the .hgtags filenode for a given changeset.""" |
834 assert len(fnode) == 20 |
833 assert len(fnode) == 20 |