##// END OF EJS Templates
convert: read git output in binary mode under Windows (issue 1359)
Patrick Mezard -
r7222:c1dc903d default
parent child Browse files
Show More
@@ -1,142 +1,142 b''
1 # git support for the convert extension
1 # git support for the convert extension
2
2
3 import os
3 import os
4 from mercurial import util
4 from mercurial import util
5
5
6 from common import NoRepo, commit, converter_source, checktool
6 from common import NoRepo, commit, converter_source, checktool
7
7
8 class convert_git(converter_source):
8 class convert_git(converter_source):
9 # Windows does not support GIT_DIR= construct while other systems
9 # Windows does not support GIT_DIR= construct while other systems
10 # cannot remove environment variable. Just assume none have
10 # cannot remove environment variable. Just assume none have
11 # both issues.
11 # both issues.
12 if hasattr(os, 'unsetenv'):
12 if hasattr(os, 'unsetenv'):
13 def gitcmd(self, s):
13 def gitcmd(self, s):
14 prevgitdir = os.environ.get('GIT_DIR')
14 prevgitdir = os.environ.get('GIT_DIR')
15 os.environ['GIT_DIR'] = self.path
15 os.environ['GIT_DIR'] = self.path
16 try:
16 try:
17 return util.popen(s)
17 return util.popen(s, 'rb')
18 finally:
18 finally:
19 if prevgitdir is None:
19 if prevgitdir is None:
20 del os.environ['GIT_DIR']
20 del os.environ['GIT_DIR']
21 else:
21 else:
22 os.environ['GIT_DIR'] = prevgitdir
22 os.environ['GIT_DIR'] = prevgitdir
23 else:
23 else:
24 def gitcmd(self, s):
24 def gitcmd(self, s):
25 return util.popen('GIT_DIR=%s %s' % (self.path, s))
25 return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
26
26
27 def __init__(self, ui, path, rev=None):
27 def __init__(self, ui, path, rev=None):
28 super(convert_git, self).__init__(ui, path, rev=rev)
28 super(convert_git, self).__init__(ui, path, rev=rev)
29
29
30 if os.path.isdir(path + "/.git"):
30 if os.path.isdir(path + "/.git"):
31 path += "/.git"
31 path += "/.git"
32 if not os.path.exists(path + "/objects"):
32 if not os.path.exists(path + "/objects"):
33 raise NoRepo("%s does not look like a Git repo" % path)
33 raise NoRepo("%s does not look like a Git repo" % path)
34
34
35 checktool('git', 'git')
35 checktool('git', 'git')
36
36
37 self.path = path
37 self.path = path
38
38
39 def getheads(self):
39 def getheads(self):
40 if not self.rev:
40 if not self.rev:
41 return self.gitcmd('git rev-parse --branches').read().splitlines()
41 return self.gitcmd('git rev-parse --branches').read().splitlines()
42 else:
42 else:
43 fh = self.gitcmd("git rev-parse --verify %s" % self.rev)
43 fh = self.gitcmd("git rev-parse --verify %s" % self.rev)
44 return [fh.read()[:-1]]
44 return [fh.read()[:-1]]
45
45
46 def catfile(self, rev, type):
46 def catfile(self, rev, type):
47 if rev == "0" * 40: raise IOError()
47 if rev == "0" * 40: raise IOError()
48 fh = self.gitcmd("git cat-file %s %s" % (type, rev))
48 fh = self.gitcmd("git cat-file %s %s" % (type, rev))
49 return fh.read()
49 return fh.read()
50
50
51 def getfile(self, name, rev):
51 def getfile(self, name, rev):
52 return self.catfile(rev, "blob")
52 return self.catfile(rev, "blob")
53
53
54 def getmode(self, name, rev):
54 def getmode(self, name, rev):
55 return self.modecache[(name, rev)]
55 return self.modecache[(name, rev)]
56
56
57 def getchanges(self, version):
57 def getchanges(self, version):
58 self.modecache = {}
58 self.modecache = {}
59 fh = self.gitcmd("git diff-tree --root -m -r %s" % version)
59 fh = self.gitcmd("git diff-tree --root -m -r %s" % version)
60 changes = []
60 changes = []
61 seen = {}
61 seen = {}
62 for l in fh:
62 for l in fh:
63 if "\t" not in l:
63 if "\t" not in l:
64 continue
64 continue
65 m, f = l[:-1].split("\t")
65 m, f = l[:-1].split("\t")
66 if f in seen:
66 if f in seen:
67 continue
67 continue
68 seen[f] = 1
68 seen[f] = 1
69 m = m.split()
69 m = m.split()
70 h = m[3]
70 h = m[3]
71 p = (m[1] == "100755")
71 p = (m[1] == "100755")
72 s = (m[1] == "120000")
72 s = (m[1] == "120000")
73 self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
73 self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
74 changes.append((f, h))
74 changes.append((f, h))
75 return (changes, {})
75 return (changes, {})
76
76
77 def getcommit(self, version):
77 def getcommit(self, version):
78 c = self.catfile(version, "commit") # read the commit hash
78 c = self.catfile(version, "commit") # read the commit hash
79 end = c.find("\n\n")
79 end = c.find("\n\n")
80 message = c[end+2:]
80 message = c[end+2:]
81 message = self.recode(message)
81 message = self.recode(message)
82 l = c[:end].splitlines()
82 l = c[:end].splitlines()
83 manifest = l[0].split()[1]
83 manifest = l[0].split()[1]
84 parents = []
84 parents = []
85 for e in l[1:]:
85 for e in l[1:]:
86 n, v = e.split(" ", 1)
86 n, v = e.split(" ", 1)
87 if n == "author":
87 if n == "author":
88 p = v.split()
88 p = v.split()
89 tm, tz = p[-2:]
89 tm, tz = p[-2:]
90 author = " ".join(p[:-2])
90 author = " ".join(p[:-2])
91 if author[0] == "<": author = author[1:-1]
91 if author[0] == "<": author = author[1:-1]
92 author = self.recode(author)
92 author = self.recode(author)
93 if n == "committer":
93 if n == "committer":
94 p = v.split()
94 p = v.split()
95 tm, tz = p[-2:]
95 tm, tz = p[-2:]
96 committer = " ".join(p[:-2])
96 committer = " ".join(p[:-2])
97 if committer[0] == "<": committer = committer[1:-1]
97 if committer[0] == "<": committer = committer[1:-1]
98 committer = self.recode(committer)
98 committer = self.recode(committer)
99 message += "\ncommitter: %s\n" % committer
99 message += "\ncommitter: %s\n" % committer
100 if n == "parent": parents.append(v)
100 if n == "parent": parents.append(v)
101
101
102 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
102 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
103 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
103 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
104 date = tm + " " + str(tz)
104 date = tm + " " + str(tz)
105
105
106 c = commit(parents=parents, date=date, author=author, desc=message,
106 c = commit(parents=parents, date=date, author=author, desc=message,
107 rev=version)
107 rev=version)
108 return c
108 return c
109
109
110 def gettags(self):
110 def gettags(self):
111 tags = {}
111 tags = {}
112 fh = self.gitcmd('git ls-remote --tags "%s"' % self.path)
112 fh = self.gitcmd('git ls-remote --tags "%s"' % self.path)
113 prefix = 'refs/tags/'
113 prefix = 'refs/tags/'
114 for line in fh:
114 for line in fh:
115 line = line.strip()
115 line = line.strip()
116 if not line.endswith("^{}"):
116 if not line.endswith("^{}"):
117 continue
117 continue
118 node, tag = line.split(None, 1)
118 node, tag = line.split(None, 1)
119 if not tag.startswith(prefix):
119 if not tag.startswith(prefix):
120 continue
120 continue
121 tag = tag[len(prefix):-3]
121 tag = tag[len(prefix):-3]
122 tags[tag] = node
122 tags[tag] = node
123
123
124 return tags
124 return tags
125
125
126 def getchangedfiles(self, version, i):
126 def getchangedfiles(self, version, i):
127 changes = []
127 changes = []
128 if i is None:
128 if i is None:
129 fh = self.gitcmd("git diff-tree --root -m -r %s" % version)
129 fh = self.gitcmd("git diff-tree --root -m -r %s" % version)
130 for l in fh:
130 for l in fh:
131 if "\t" not in l:
131 if "\t" not in l:
132 continue
132 continue
133 m, f = l[:-1].split("\t")
133 m, f = l[:-1].split("\t")
134 changes.append(f)
134 changes.append(f)
135 fh.close()
135 fh.close()
136 else:
136 else:
137 fh = self.gitcmd('git diff-tree --name-only --root -r %s "%s^%s" --'
137 fh = self.gitcmd('git diff-tree --name-only --root -r %s "%s^%s" --'
138 % (version, version, i+1))
138 % (version, version, i+1))
139 changes = [f.rstrip('\n') for f in fh]
139 changes = [f.rstrip('\n') for f in fh]
140 fh.close()
140 fh.close()
141
141
142 return changes
142 return changes
@@ -1,132 +1,149 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 "$TESTDIR/hghave" git || exit 80
3 "$TESTDIR/hghave" git || exit 80
4
4
5 echo "[extensions]" >> $HGRCPATH
5 echo "[extensions]" >> $HGRCPATH
6 echo "convert=" >> $HGRCPATH
6 echo "convert=" >> $HGRCPATH
7 echo 'hgext.graphlog =' >> $HGRCPATH
7 echo 'hgext.graphlog =' >> $HGRCPATH
8
8
9 GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
9 GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
10 GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
10 GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
11 GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
11 GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
12 GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
12 GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
13 GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
13 GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
14 GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
14 GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
15
15
16 count=10
16 count=10
17 commit()
17 commit()
18 {
18 {
19 GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
19 GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
20 GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
20 GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
21 git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
21 git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
22 count=`expr $count + 1`
22 count=`expr $count + 1`
23 }
23 }
24
24
25 mkdir git-repo
25 mkdir git-repo
26 cd git-repo
26 cd git-repo
27 git init-db >/dev/null 2>/dev/null
27 git init-db >/dev/null 2>/dev/null
28 echo a > a
28 echo a > a
29 mkdir d
29 mkdir d
30 echo b > d/b
30 echo b > d/b
31 git add a d
31 git add a d
32 commit -a -m t1
32 commit -a -m t1
33
33
34 # Remove the directory, then try to replace it with a file
34 # Remove the directory, then try to replace it with a file
35 # (issue 754)
35 # (issue 754)
36 git rm -f d/b
36 git rm -f d/b
37 commit -m t2
37 commit -m t2
38 echo d > d
38 echo d > d
39 git add d
39 git add d
40 commit -m t3
40 commit -m t3
41
41
42 echo b >> a
42 echo b >> a
43 commit -a -m t4.1
43 commit -a -m t4.1
44
44
45 git checkout -b other HEAD^ >/dev/null 2>/dev/null
45 git checkout -b other HEAD^ >/dev/null 2>/dev/null
46 echo c > a
46 echo c > a
47 echo a >> a
47 echo a >> a
48 commit -a -m t4.2
48 commit -a -m t4.2
49
49
50 git checkout master >/dev/null 2>/dev/null
50 git checkout master >/dev/null 2>/dev/null
51 git pull --no-commit . other > /dev/null 2>/dev/null
51 git pull --no-commit . other > /dev/null 2>/dev/null
52 commit -m 'Merge branch other'
52 commit -m 'Merge branch other'
53 cd ..
53 cd ..
54
54
55 hg convert --datesort git-repo
55 hg convert --datesort git-repo
56
56
57 hg -R git-repo-hg tip -v
57 hg -R git-repo-hg tip -v
58
58
59 count=10
59 count=10
60 mkdir git-repo2
60 mkdir git-repo2
61 cd git-repo2
61 cd git-repo2
62 git init-db >/dev/null 2>/dev/null
62 git init-db >/dev/null 2>/dev/null
63
63
64 echo foo > foo
64 echo foo > foo
65 git add foo
65 git add foo
66 commit -a -m 'add foo'
66 commit -a -m 'add foo'
67
67
68 echo >> foo
68 echo >> foo
69 commit -a -m 'change foo'
69 commit -a -m 'change foo'
70
70
71 git checkout -b Bar HEAD^ >/dev/null 2>/dev/null
71 git checkout -b Bar HEAD^ >/dev/null 2>/dev/null
72 echo quux >> quux
72 echo quux >> quux
73 git add quux
73 git add quux
74 commit -a -m 'add quux'
74 commit -a -m 'add quux'
75
75
76 echo bar > bar
76 echo bar > bar
77 git add bar
77 git add bar
78 commit -a -m 'add bar'
78 commit -a -m 'add bar'
79
79
80 git checkout -b Baz HEAD^ >/dev/null 2>/dev/null
80 git checkout -b Baz HEAD^ >/dev/null 2>/dev/null
81 echo baz > baz
81 echo baz > baz
82 git add baz
82 git add baz
83 commit -a -m 'add baz'
83 commit -a -m 'add baz'
84
84
85 git checkout master >/dev/null 2>/dev/null
85 git checkout master >/dev/null 2>/dev/null
86 git pull --no-commit . Bar Baz > /dev/null 2>/dev/null
86 git pull --no-commit . Bar Baz > /dev/null 2>/dev/null
87 commit -m 'Octopus merge'
87 commit -m 'Octopus merge'
88
88
89 echo bar >> bar
89 echo bar >> bar
90 commit -a -m 'change bar'
90 commit -a -m 'change bar'
91
91
92 git checkout -b Foo HEAD^ >/dev/null 2>/dev/null
92 git checkout -b Foo HEAD^ >/dev/null 2>/dev/null
93 echo >> foo
93 echo >> foo
94 commit -a -m 'change foo'
94 commit -a -m 'change foo'
95
95
96 git checkout master >/dev/null 2>/dev/null
96 git checkout master >/dev/null 2>/dev/null
97 git pull --no-commit -s ours . Foo > /dev/null 2>/dev/null
97 git pull --no-commit -s ours . Foo > /dev/null 2>/dev/null
98 commit -m 'Discard change to foo'
98 commit -m 'Discard change to foo'
99
99
100 cd ..
100 cd ..
101
101
102 glog()
102 glog()
103 {
103 {
104 hg glog --template '#rev# "#desc|firstline#" files: #files#\n' "$@"
104 hg glog --template '#rev# "#desc|firstline#" files: #files#\n' "$@"
105 }
105 }
106
106
107 splitrepo()
107 splitrepo()
108 {
108 {
109 msg="$1"
109 msg="$1"
110 files="$2"
110 files="$2"
111 opts=$3
111 opts=$3
112 echo "% $files: $msg"
112 echo "% $files: $msg"
113 prefix=`echo "$files" | sed -e 's/ /-/g'`
113 prefix=`echo "$files" | sed -e 's/ /-/g'`
114 fmap="$prefix.fmap"
114 fmap="$prefix.fmap"
115 repo="$prefix.repo"
115 repo="$prefix.repo"
116 for i in $files; do
116 for i in $files; do
117 echo "include $i" >> "$fmap"
117 echo "include $i" >> "$fmap"
118 done
118 done
119 hg -q convert $opts --filemap "$fmap" --datesort git-repo2 "$repo"
119 hg -q convert $opts --filemap "$fmap" --datesort git-repo2 "$repo"
120 glog -R "$repo"
120 glog -R "$repo"
121 hg -R "$repo" manifest --debug
121 hg -R "$repo" manifest --debug
122 }
122 }
123
123
124 echo '% full conversion'
124 echo '% full conversion'
125 hg -q convert --datesort git-repo2 fullrepo
125 hg -q convert --datesort git-repo2 fullrepo
126 glog -R fullrepo
126 glog -R fullrepo
127 hg -R fullrepo manifest --debug
127 hg -R fullrepo manifest --debug
128
128
129 splitrepo 'octopus merge' 'foo bar baz'
129 splitrepo 'octopus merge' 'foo bar baz'
130
130
131 splitrepo 'only some parents of an octopus merge; "discard" a head' 'foo baz quux'
131 splitrepo 'only some parents of an octopus merge; "discard" a head' 'foo baz quux'
132
132
133 echo
134 echo '% test binary conversion (issue 1359)'
135 mkdir git-repo3
136 cd git-repo3
137 git init-db >/dev/null 2>/dev/null
138 python -c 'file("b", "wb").write("".join([chr(i) for i in range(256)])*16)'
139 git add b
140 commit -a -m addbinary
141 cd ..
142
143 echo '% convert binary file'
144 hg convert git-repo3 git-repo3-hg
145
146 cd git-repo3-hg
147 hg up -C
148 python -c 'print len(file("b", "rb").read())'
149
@@ -1,90 +1,100 b''
1 rm 'd/b'
1 rm 'd/b'
2 assuming destination git-repo-hg
2 assuming destination git-repo-hg
3 initializing destination git-repo-hg repository
3 initializing destination git-repo-hg repository
4 scanning source...
4 scanning source...
5 sorting...
5 sorting...
6 converting...
6 converting...
7 5 t1
7 5 t1
8 4 t2
8 4 t2
9 3 t3
9 3 t3
10 2 t4.1
10 2 t4.1
11 1 t4.2
11 1 t4.2
12 0 Merge branch other
12 0 Merge branch other
13 changeset: 5:4ab1af49a271
13 changeset: 5:4ab1af49a271
14 tag: tip
14 tag: tip
15 parent: 3:0222ab0998d7
15 parent: 3:0222ab0998d7
16 parent: 4:5333c870e3c2
16 parent: 4:5333c870e3c2
17 user: test <test@example.org>
17 user: test <test@example.org>
18 date: Mon Jan 01 00:00:15 2007 +0000
18 date: Mon Jan 01 00:00:15 2007 +0000
19 files: a
19 files: a
20 description:
20 description:
21 Merge branch other
21 Merge branch other
22
22
23 committer: test <test@example.org>
23 committer: test <test@example.org>
24
24
25
25
26 % full conversion
26 % full conversion
27 o 9 "Discard change to foo" files: foo
27 o 9 "Discard change to foo" files: foo
28 |\
28 |\
29 | o 8 "change foo" files: foo
29 | o 8 "change foo" files: foo
30 | |
30 | |
31 o | 7 "change bar" files: bar
31 o | 7 "change bar" files: bar
32 |/
32 |/
33 o 6 "(octopus merge fixup)" files:
33 o 6 "(octopus merge fixup)" files:
34 |\
34 |\
35 | o 5 "Octopus merge" files: baz
35 | o 5 "Octopus merge" files: baz
36 | |\
36 | |\
37 o | | 4 "add baz" files: baz
37 o | | 4 "add baz" files: baz
38 | | |
38 | | |
39 +---o 3 "add bar" files: bar
39 +---o 3 "add bar" files: bar
40 | |
40 | |
41 o | 2 "add quux" files: quux
41 o | 2 "add quux" files: quux
42 | |
42 | |
43 | o 1 "change foo" files: foo
43 | o 1 "change foo" files: foo
44 |/
44 |/
45 o 0 "add foo" files: foo
45 o 0 "add foo" files: foo
46
46
47 245a3b8bc653999c2b22cdabd517ccb47aecafdf 644 bar
47 245a3b8bc653999c2b22cdabd517ccb47aecafdf 644 bar
48 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
48 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
49 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
49 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
50 88dfeab657e8cf2cef3dec67b914f49791ae76b1 644 quux
50 88dfeab657e8cf2cef3dec67b914f49791ae76b1 644 quux
51 % foo bar baz: octopus merge
51 % foo bar baz: octopus merge
52 o 8 "Discard change to foo" files: foo
52 o 8 "Discard change to foo" files: foo
53 |\
53 |\
54 | o 7 "change foo" files: foo
54 | o 7 "change foo" files: foo
55 | |
55 | |
56 o | 6 "change bar" files: bar
56 o | 6 "change bar" files: bar
57 |/
57 |/
58 o 5 "(octopus merge fixup)" files:
58 o 5 "(octopus merge fixup)" files:
59 |\
59 |\
60 | o 4 "Octopus merge" files: baz
60 | o 4 "Octopus merge" files: baz
61 | |\
61 | |\
62 o | | 3 "add baz" files: baz
62 o | | 3 "add baz" files: baz
63 | | |
63 | | |
64 +---o 2 "add bar" files: bar
64 +---o 2 "add bar" files: bar
65 | |
65 | |
66 | o 1 "change foo" files: foo
66 | o 1 "change foo" files: foo
67 |/
67 |/
68 o 0 "add foo" files: foo
68 o 0 "add foo" files: foo
69
69
70 245a3b8bc653999c2b22cdabd517ccb47aecafdf 644 bar
70 245a3b8bc653999c2b22cdabd517ccb47aecafdf 644 bar
71 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
71 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
72 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
72 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
73 % foo baz quux: only some parents of an octopus merge; "discard" a head
73 % foo baz quux: only some parents of an octopus merge; "discard" a head
74 o 6 "Discard change to foo" files: foo
74 o 6 "Discard change to foo" files: foo
75 |
75 |
76 o 5 "change foo" files: foo
76 o 5 "change foo" files: foo
77 |
77 |
78 o 4 "Octopus merge" files:
78 o 4 "Octopus merge" files:
79 |\
79 |\
80 | o 3 "add baz" files: baz
80 | o 3 "add baz" files: baz
81 | |
81 | |
82 | o 2 "add quux" files: quux
82 | o 2 "add quux" files: quux
83 | |
83 | |
84 o | 1 "change foo" files: foo
84 o | 1 "change foo" files: foo
85 |/
85 |/
86 o 0 "add foo" files: foo
86 o 0 "add foo" files: foo
87
87
88 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
88 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
89 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
89 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
90 88dfeab657e8cf2cef3dec67b914f49791ae76b1 644 quux
90 88dfeab657e8cf2cef3dec67b914f49791ae76b1 644 quux
91
92 % test binary conversion (issue 1359)
93 % convert binary file
94 initializing destination git-repo3-hg repository
95 scanning source...
96 sorting...
97 converting...
98 0 addbinary
99 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 4096
General Comments 0
You need to be logged in to leave comments. Login now