1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
import os
from datetime import datetime
from .utils import trace, require_command, do_ex
from .git import GitWorkdir
from .hg import HgWorkdir
class GitWorkdirHgClient(GitWorkdir, HgWorkdir):
COMMAND = "hg"
@classmethod
def from_potential_worktree(cls, wd):
require_command(cls.COMMAND)
root, err, ret = do_ex("hg root", wd)
if ret:
print(err)
return
return cls(root)
def is_dirty(self):
out, _, _ = self.do_ex("hg id -T '{dirty}'")
return bool(out)
def get_branch(self):
branch, err, ret = self.do_ex("hg id -T {bookmarks}")
if ret:
trace("branch err", branch, err, ret)
return
return branch
def get_head_date(self):
date_part, err, ret = self.do_ex("hg log -r . -T {shortdate(date)}")
if ret:
trace("head date err", date_part, err, ret)
return
return datetime.strptime(date_part, r"%Y-%m-%d").date()
def is_shallow(self):
return False
def fetch_shallow(self):
pass
def get_hg_node(self):
node, _, ret = self.do_ex("hg log -r . -T {node}")
if not ret:
return node
def node(self):
hg_node = self.get_hg_node()
if hg_node is None:
return
git_node = None
with open(os.path.join(self.path, ".hg/git-mapfile")) as file:
for line in file:
if hg_node in line:
git_node, hg_node = line.split()
break
if git_node is None:
# trying again after hg -> git
self.do_ex("hg gexport")
return self.node()
return git_node[:7]
def count_all_nodes(self):
revs, _, _ = self.do_ex("hg log -r 'ancestors(.)' -T '.'")
return len(revs) + 1
def default_describe(self):
"""
Tentative to reproduce the output of
`git describe --dirty --tags --long --match *[0-9]*`
"""
hg_tags, _, ret = self.do_ex(
[
"hg",
"log",
"-r",
"(reverse(ancestors(.)) and tag(r're:[0-9]'))",
"-T",
"{tags}{if(tags, ' ', '')}",
]
)
if ret:
return None, None, None
hg_tags = hg_tags.split()
git_tags = {}
with open(os.path.join(self.path, ".hg/git-tags")) as file:
for line in file:
node, tag = line.split()
git_tags[tag] = node
# find the first hg tag which is also a git tag
for tag in hg_tags:
if tag in git_tags:
break
out, _, ret = self.do_ex("hg log -r " + tag + "::. -T .")
if ret:
return None, None, None
distance = len(out) - 1
node = self.node()
desc = f"{tag}-{distance}-g{node}"
if self.is_dirty():
desc += "-dirty"
return desc, None, 0
|