##// END OF EJS Templates
convert: add bookmarks reading support to git backend
Edouard Gomez -
r13756:6b7077df default
parent child Browse files
Show More
@@ -1,170 +1,205 b''
1 # git.py - git support for the convert extension
1 # git.py - git support for the convert extension
2 #
2 #
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import os
8 import os
9 from mercurial import util
9 from mercurial import util
10 from mercurial.node import hex, nullid
10 from mercurial.node import hex, nullid
11 from mercurial.i18n import _
11 from mercurial.i18n import _
12
12
13 from common import NoRepo, commit, converter_source, checktool
13 from common import NoRepo, commit, converter_source, checktool
14
14
15 class convert_git(converter_source):
15 class convert_git(converter_source):
16 # Windows does not support GIT_DIR= construct while other systems
16 # Windows does not support GIT_DIR= construct while other systems
17 # cannot remove environment variable. Just assume none have
17 # cannot remove environment variable. Just assume none have
18 # both issues.
18 # both issues.
19 if hasattr(os, 'unsetenv'):
19 if hasattr(os, 'unsetenv'):
20 def gitopen(self, s):
20 def gitopen(self, s, noerr=False):
21 prevgitdir = os.environ.get('GIT_DIR')
21 prevgitdir = os.environ.get('GIT_DIR')
22 os.environ['GIT_DIR'] = self.path
22 os.environ['GIT_DIR'] = self.path
23 try:
23 try:
24 return util.popen(s, 'rb')
24 if noerr:
25 (stdin, stdout, stderr) = util.popen3(s)
26 return stdout
27 else:
28 return util.popen(s, 'rb')
25 finally:
29 finally:
26 if prevgitdir is None:
30 if prevgitdir is None:
27 del os.environ['GIT_DIR']
31 del os.environ['GIT_DIR']
28 else:
32 else:
29 os.environ['GIT_DIR'] = prevgitdir
33 os.environ['GIT_DIR'] = prevgitdir
30 else:
34 else:
31 def gitopen(self, s):
35 def gitopen(self, s, noerr=False):
32 return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
36 if noerr:
37 (sin, so, se) = util.popen3('GIT_DIR=%s %s' % (self.path, s))
38 return stdout
39 else:
40 util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
33
41
34 def gitread(self, s):
42 def gitread(self, s):
35 fh = self.gitopen(s)
43 fh = self.gitopen(s)
36 data = fh.read()
44 data = fh.read()
37 return data, fh.close()
45 return data, fh.close()
38
46
39 def __init__(self, ui, path, rev=None):
47 def __init__(self, ui, path, rev=None):
40 super(convert_git, self).__init__(ui, path, rev=rev)
48 super(convert_git, self).__init__(ui, path, rev=rev)
41
49
42 if os.path.isdir(path + "/.git"):
50 if os.path.isdir(path + "/.git"):
43 path += "/.git"
51 path += "/.git"
44 if not os.path.exists(path + "/objects"):
52 if not os.path.exists(path + "/objects"):
45 raise NoRepo(_("%s does not look like a Git repository") % path)
53 raise NoRepo(_("%s does not look like a Git repository") % path)
46
54
47 checktool('git', 'git')
55 checktool('git', 'git')
48
56
49 self.path = path
57 self.path = path
50
58
51 def getheads(self):
59 def getheads(self):
52 if not self.rev:
60 if not self.rev:
53 heads, ret = self.gitread('git rev-parse --branches --remotes')
61 heads, ret = self.gitread('git rev-parse --branches --remotes')
54 heads = heads.splitlines()
62 heads = heads.splitlines()
55 else:
63 else:
56 heads, ret = self.gitread("git rev-parse --verify %s" % self.rev)
64 heads, ret = self.gitread("git rev-parse --verify %s" % self.rev)
57 heads = [heads[:-1]]
65 heads = [heads[:-1]]
58 if ret:
66 if ret:
59 raise util.Abort(_('cannot retrieve git heads'))
67 raise util.Abort(_('cannot retrieve git heads'))
60 return heads
68 return heads
61
69
62 def catfile(self, rev, type):
70 def catfile(self, rev, type):
63 if rev == hex(nullid):
71 if rev == hex(nullid):
64 raise IOError()
72 raise IOError()
65 data, ret = self.gitread("git cat-file %s %s" % (type, rev))
73 data, ret = self.gitread("git cat-file %s %s" % (type, rev))
66 if ret:
74 if ret:
67 raise util.Abort(_('cannot read %r object at %s') % (type, rev))
75 raise util.Abort(_('cannot read %r object at %s') % (type, rev))
68 return data
76 return data
69
77
70 def getfile(self, name, rev):
78 def getfile(self, name, rev):
71 data = self.catfile(rev, "blob")
79 data = self.catfile(rev, "blob")
72 mode = self.modecache[(name, rev)]
80 mode = self.modecache[(name, rev)]
73 return data, mode
81 return data, mode
74
82
75 def getchanges(self, version):
83 def getchanges(self, version):
76 self.modecache = {}
84 self.modecache = {}
77 fh = self.gitopen("git diff-tree -z --root -m -r %s" % version)
85 fh = self.gitopen("git diff-tree -z --root -m -r %s" % version)
78 changes = []
86 changes = []
79 seen = set()
87 seen = set()
80 entry = None
88 entry = None
81 for l in fh.read().split('\x00'):
89 for l in fh.read().split('\x00'):
82 if not entry:
90 if not entry:
83 if not l.startswith(':'):
91 if not l.startswith(':'):
84 continue
92 continue
85 entry = l
93 entry = l
86 continue
94 continue
87 f = l
95 f = l
88 if f not in seen:
96 if f not in seen:
89 seen.add(f)
97 seen.add(f)
90 entry = entry.split()
98 entry = entry.split()
91 h = entry[3]
99 h = entry[3]
92 p = (entry[1] == "100755")
100 p = (entry[1] == "100755")
93 s = (entry[1] == "120000")
101 s = (entry[1] == "120000")
94 self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
102 self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
95 changes.append((f, h))
103 changes.append((f, h))
96 entry = None
104 entry = None
97 if fh.close():
105 if fh.close():
98 raise util.Abort(_('cannot read changes in %s') % version)
106 raise util.Abort(_('cannot read changes in %s') % version)
99 return (changes, {})
107 return (changes, {})
100
108
101 def getcommit(self, version):
109 def getcommit(self, version):
102 c = self.catfile(version, "commit") # read the commit hash
110 c = self.catfile(version, "commit") # read the commit hash
103 end = c.find("\n\n")
111 end = c.find("\n\n")
104 message = c[end + 2:]
112 message = c[end + 2:]
105 message = self.recode(message)
113 message = self.recode(message)
106 l = c[:end].splitlines()
114 l = c[:end].splitlines()
107 parents = []
115 parents = []
108 author = committer = None
116 author = committer = None
109 for e in l[1:]:
117 for e in l[1:]:
110 n, v = e.split(" ", 1)
118 n, v = e.split(" ", 1)
111 if n == "author":
119 if n == "author":
112 p = v.split()
120 p = v.split()
113 tm, tz = p[-2:]
121 tm, tz = p[-2:]
114 author = " ".join(p[:-2])
122 author = " ".join(p[:-2])
115 if author[0] == "<": author = author[1:-1]
123 if author[0] == "<": author = author[1:-1]
116 author = self.recode(author)
124 author = self.recode(author)
117 if n == "committer":
125 if n == "committer":
118 p = v.split()
126 p = v.split()
119 tm, tz = p[-2:]
127 tm, tz = p[-2:]
120 committer = " ".join(p[:-2])
128 committer = " ".join(p[:-2])
121 if committer[0] == "<": committer = committer[1:-1]
129 if committer[0] == "<": committer = committer[1:-1]
122 committer = self.recode(committer)
130 committer = self.recode(committer)
123 if n == "parent":
131 if n == "parent":
124 parents.append(v)
132 parents.append(v)
125
133
126 if committer and committer != author:
134 if committer and committer != author:
127 message += "\ncommitter: %s\n" % committer
135 message += "\ncommitter: %s\n" % committer
128 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
136 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
129 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
137 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
130 date = tm + " " + str(tz)
138 date = tm + " " + str(tz)
131
139
132 c = commit(parents=parents, date=date, author=author, desc=message,
140 c = commit(parents=parents, date=date, author=author, desc=message,
133 rev=version)
141 rev=version)
134 return c
142 return c
135
143
136 def gettags(self):
144 def gettags(self):
137 tags = {}
145 tags = {}
138 fh = self.gitopen('git ls-remote --tags "%s"' % self.path)
146 fh = self.gitopen('git ls-remote --tags "%s"' % self.path)
139 prefix = 'refs/tags/'
147 prefix = 'refs/tags/'
140 for line in fh:
148 for line in fh:
141 line = line.strip()
149 line = line.strip()
142 if not line.endswith("^{}"):
150 if not line.endswith("^{}"):
143 continue
151 continue
144 node, tag = line.split(None, 1)
152 node, tag = line.split(None, 1)
145 if not tag.startswith(prefix):
153 if not tag.startswith(prefix):
146 continue
154 continue
147 tag = tag[len(prefix):-3]
155 tag = tag[len(prefix):-3]
148 tags[tag] = node
156 tags[tag] = node
149 if fh.close():
157 if fh.close():
150 raise util.Abort(_('cannot read tags from %s') % self.path)
158 raise util.Abort(_('cannot read tags from %s') % self.path)
151
159
152 return tags
160 return tags
153
161
154 def getchangedfiles(self, version, i):
162 def getchangedfiles(self, version, i):
155 changes = []
163 changes = []
156 if i is None:
164 if i is None:
157 fh = self.gitopen("git diff-tree --root -m -r %s" % version)
165 fh = self.gitopen("git diff-tree --root -m -r %s" % version)
158 for l in fh:
166 for l in fh:
159 if "\t" not in l:
167 if "\t" not in l:
160 continue
168 continue
161 m, f = l[:-1].split("\t")
169 m, f = l[:-1].split("\t")
162 changes.append(f)
170 changes.append(f)
163 else:
171 else:
164 fh = self.gitopen('git diff-tree --name-only --root -r %s "%s^%s" --'
172 fh = self.gitopen('git diff-tree --name-only --root -r %s "%s^%s" --'
165 % (version, version, i + 1))
173 % (version, version, i + 1))
166 changes = [f.rstrip('\n') for f in fh]
174 changes = [f.rstrip('\n') for f in fh]
167 if fh.close():
175 if fh.close():
168 raise util.Abort(_('cannot read changes in %s') % version)
176 raise util.Abort(_('cannot read changes in %s') % version)
169
177
170 return changes
178 return changes
179
180 def getbookmarks(self):
181 bookmarks = {}
182
183 # Interesting references in git are prefixed
184 prefix = 'refs/heads/'
185 prefixlen = len(prefix)
186
187 # factor two commands
188 gitcmd = { 'remote/': 'git ls-remote --heads origin',
189 '': 'git show-ref'}
190
191 # Origin heads
192 for reftype in gitcmd:
193 try:
194 fh = self.gitopen(gitcmd[reftype], noerr=True)
195 for line in fh:
196 line = line.strip()
197 rev, name = line.split(None, 1)
198 if not name.startswith(prefix):
199 continue
200 name = '%s%s' % (reftype, name[prefixlen:])
201 bookmarks[name] = rev
202 except:
203 pass
204
205 return bookmarks
@@ -1,292 +1,297 b''
1
1
2 $ "$TESTDIR/hghave" git || exit 80
2 $ "$TESTDIR/hghave" git || exit 80
3 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
4 $ echo "convert=" >> $HGRCPATH
4 $ echo "convert=" >> $HGRCPATH
5 $ echo 'hgext.graphlog =' >> $HGRCPATH
5 $ echo 'hgext.graphlog =' >> $HGRCPATH
6 $ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
6 $ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
7 $ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
7 $ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
8 $ GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
8 $ GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
9 $ GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
9 $ GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
10 $ GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
10 $ GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
11 $ GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
11 $ GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
12 $ count=10
12 $ count=10
13 $ commit()
13 $ commit()
14 > {
14 > {
15 > GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
15 > GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
16 > GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
16 > GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
17 > git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
17 > git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
18 > count=`expr $count + 1`
18 > count=`expr $count + 1`
19 > }
19 > }
20 $ mkdir git-repo
20 $ mkdir git-repo
21 $ cd git-repo
21 $ cd git-repo
22 $ git init-db >/dev/null 2>/dev/null
22 $ git init-db >/dev/null 2>/dev/null
23 $ echo a > a
23 $ echo a > a
24 $ mkdir d
24 $ mkdir d
25 $ echo b > d/b
25 $ echo b > d/b
26 $ git add a d
26 $ git add a d
27 $ commit -a -m t1
27 $ commit -a -m t1
28
28
29 Remove the directory, then try to replace it with a file
29 Remove the directory, then try to replace it with a file
30 (issue 754)
30 (issue 754)
31
31
32 $ git rm -f d/b
32 $ git rm -f d/b
33 rm 'd/b'
33 rm 'd/b'
34 $ commit -m t2
34 $ commit -m t2
35 $ echo d > d
35 $ echo d > d
36 $ git add d
36 $ git add d
37 $ commit -m t3
37 $ commit -m t3
38 $ echo b >> a
38 $ echo b >> a
39 $ commit -a -m t4.1
39 $ commit -a -m t4.1
40 $ git checkout -b other HEAD~ >/dev/null 2>/dev/null
40 $ git checkout -b other HEAD~ >/dev/null 2>/dev/null
41 $ echo c > a
41 $ echo c > a
42 $ echo a >> a
42 $ echo a >> a
43 $ commit -a -m t4.2
43 $ commit -a -m t4.2
44 $ git checkout master >/dev/null 2>/dev/null
44 $ git checkout master >/dev/null 2>/dev/null
45 $ git pull --no-commit . other > /dev/null 2>/dev/null
45 $ git pull --no-commit . other > /dev/null 2>/dev/null
46 $ commit -m 'Merge branch other'
46 $ commit -m 'Merge branch other'
47 $ cd ..
47 $ cd ..
48 $ hg convert --datesort git-repo
48 $ hg convert --datesort git-repo
49 assuming destination git-repo-hg
49 assuming destination git-repo-hg
50 initializing destination git-repo-hg repository
50 initializing destination git-repo-hg repository
51 scanning source...
51 scanning source...
52 sorting...
52 sorting...
53 converting...
53 converting...
54 5 t1
54 5 t1
55 4 t2
55 4 t2
56 3 t3
56 3 t3
57 2 t4.1
57 2 t4.1
58 1 t4.2
58 1 t4.2
59 0 Merge branch other
59 0 Merge branch other
60 updating bookmarks
60 $ hg up -q -R git-repo-hg
61 $ hg up -q -R git-repo-hg
61 $ hg -R git-repo-hg tip -v
62 $ hg -R git-repo-hg tip -v
62 changeset: 5:c78094926be2
63 changeset: 5:c78094926be2
64 bookmark: master
63 tag: tip
65 tag: tip
64 parent: 3:f5f5cb45432b
66 parent: 3:f5f5cb45432b
65 parent: 4:4e174f80c67c
67 parent: 4:4e174f80c67c
66 user: test <test@example.org>
68 user: test <test@example.org>
67 date: Mon Jan 01 00:00:15 2007 +0000
69 date: Mon Jan 01 00:00:15 2007 +0000
68 files: a
70 files: a
69 description:
71 description:
70 Merge branch other
72 Merge branch other
71
73
72
74
73 $ count=10
75 $ count=10
74 $ mkdir git-repo2
76 $ mkdir git-repo2
75 $ cd git-repo2
77 $ cd git-repo2
76 $ git init-db >/dev/null 2>/dev/null
78 $ git init-db >/dev/null 2>/dev/null
77 $ echo foo > foo
79 $ echo foo > foo
78 $ git add foo
80 $ git add foo
79 $ commit -a -m 'add foo'
81 $ commit -a -m 'add foo'
80 $ echo >> foo
82 $ echo >> foo
81 $ commit -a -m 'change foo'
83 $ commit -a -m 'change foo'
82 $ git checkout -b Bar HEAD~ >/dev/null 2>/dev/null
84 $ git checkout -b Bar HEAD~ >/dev/null 2>/dev/null
83 $ echo quux >> quux
85 $ echo quux >> quux
84 $ git add quux
86 $ git add quux
85 $ commit -a -m 'add quux'
87 $ commit -a -m 'add quux'
86 $ echo bar > bar
88 $ echo bar > bar
87 $ git add bar
89 $ git add bar
88 $ commit -a -m 'add bar'
90 $ commit -a -m 'add bar'
89 $ git checkout -b Baz HEAD~ >/dev/null 2>/dev/null
91 $ git checkout -b Baz HEAD~ >/dev/null 2>/dev/null
90 $ echo baz > baz
92 $ echo baz > baz
91 $ git add baz
93 $ git add baz
92 $ commit -a -m 'add baz'
94 $ commit -a -m 'add baz'
93 $ git checkout master >/dev/null 2>/dev/null
95 $ git checkout master >/dev/null 2>/dev/null
94 $ git pull --no-commit . Bar Baz > /dev/null 2>/dev/null
96 $ git pull --no-commit . Bar Baz > /dev/null 2>/dev/null
95 $ commit -m 'Octopus merge'
97 $ commit -m 'Octopus merge'
96 $ echo bar >> bar
98 $ echo bar >> bar
97 $ commit -a -m 'change bar'
99 $ commit -a -m 'change bar'
98 $ git checkout -b Foo HEAD~ >/dev/null 2>/dev/null
100 $ git checkout -b Foo HEAD~ >/dev/null 2>/dev/null
99 $ echo >> foo
101 $ echo >> foo
100 $ commit -a -m 'change foo'
102 $ commit -a -m 'change foo'
101 $ git checkout master >/dev/null 2>/dev/null
103 $ git checkout master >/dev/null 2>/dev/null
102 $ git pull --no-commit -s ours . Foo > /dev/null 2>/dev/null
104 $ git pull --no-commit -s ours . Foo > /dev/null 2>/dev/null
103 $ commit -m 'Discard change to foo'
105 $ commit -m 'Discard change to foo'
104 $ cd ..
106 $ cd ..
105 $ glog()
107 $ glog()
106 > {
108 > {
107 > hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
109 > hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
108 > }
110 > }
109 $ splitrepo()
111 $ splitrepo()
110 > {
112 > {
111 > msg="$1"
113 > msg="$1"
112 > files="$2"
114 > files="$2"
113 > opts=$3
115 > opts=$3
114 > echo "% $files: $msg"
116 > echo "% $files: $msg"
115 > prefix=`echo "$files" | sed -e 's/ /-/g'`
117 > prefix=`echo "$files" | sed -e 's/ /-/g'`
116 > fmap="$prefix.fmap"
118 > fmap="$prefix.fmap"
117 > repo="$prefix.repo"
119 > repo="$prefix.repo"
118 > for i in $files; do
120 > for i in $files; do
119 > echo "include $i" >> "$fmap"
121 > echo "include $i" >> "$fmap"
120 > done
122 > done
121 > hg -q convert $opts --filemap "$fmap" --datesort git-repo2 "$repo"
123 > hg -q convert $opts --filemap "$fmap" --datesort git-repo2 "$repo"
122 > hg up -q -R "$repo"
124 > hg up -q -R "$repo"
123 > glog -R "$repo"
125 > glog -R "$repo"
124 > hg -R "$repo" manifest --debug
126 > hg -R "$repo" manifest --debug
125 > }
127 > }
126
128
127 full conversion
129 full conversion
128
130
129 $ hg -q convert --datesort git-repo2 fullrepo
131 $ hg -q convert --datesort git-repo2 fullrepo
130 $ hg up -q -R fullrepo
132 $ hg up -q -R fullrepo
131 $ glog -R fullrepo
133 $ glog -R fullrepo
132 @ 9 "Discard change to foo" files: foo
134 @ 9 "Discard change to foo" files: foo
133 |\
135 |\
134 | o 8 "change foo" files: foo
136 | o 8 "change foo" files: foo
135 | |
137 | |
136 o | 7 "change bar" files: bar
138 o | 7 "change bar" files: bar
137 |/
139 |/
138 o 6 "(octopus merge fixup)" files:
140 o 6 "(octopus merge fixup)" files:
139 |\
141 |\
140 | o 5 "Octopus merge" files: baz
142 | o 5 "Octopus merge" files: baz
141 | |\
143 | |\
142 o | | 4 "add baz" files: baz
144 o | | 4 "add baz" files: baz
143 | | |
145 | | |
144 +---o 3 "add bar" files: bar
146 +---o 3 "add bar" files: bar
145 | |
147 | |
146 o | 2 "add quux" files: quux
148 o | 2 "add quux" files: quux
147 | |
149 | |
148 | o 1 "change foo" files: foo
150 | o 1 "change foo" files: foo
149 |/
151 |/
150 o 0 "add foo" files: foo
152 o 0 "add foo" files: foo
151
153
152 $ hg -R fullrepo manifest --debug
154 $ hg -R fullrepo manifest --debug
153 245a3b8bc653999c2b22cdabd517ccb47aecafdf 644 bar
155 245a3b8bc653999c2b22cdabd517ccb47aecafdf 644 bar
154 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
156 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
155 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
157 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
156 88dfeab657e8cf2cef3dec67b914f49791ae76b1 644 quux
158 88dfeab657e8cf2cef3dec67b914f49791ae76b1 644 quux
157 $ splitrepo 'octopus merge' 'foo bar baz'
159 $ splitrepo 'octopus merge' 'foo bar baz'
158 % foo bar baz: octopus merge
160 % foo bar baz: octopus merge
159 @ 8 "Discard change to foo" files: foo
161 @ 8 "Discard change to foo" files: foo
160 |\
162 |\
161 | o 7 "change foo" files: foo
163 | o 7 "change foo" files: foo
162 | |
164 | |
163 o | 6 "change bar" files: bar
165 o | 6 "change bar" files: bar
164 |/
166 |/
165 o 5 "(octopus merge fixup)" files:
167 o 5 "(octopus merge fixup)" files:
166 |\
168 |\
167 | o 4 "Octopus merge" files: baz
169 | o 4 "Octopus merge" files: baz
168 | |\
170 | |\
169 o | | 3 "add baz" files: baz
171 o | | 3 "add baz" files: baz
170 | | |
172 | | |
171 +---o 2 "add bar" files: bar
173 +---o 2 "add bar" files: bar
172 | |
174 | |
173 | o 1 "change foo" files: foo
175 | o 1 "change foo" files: foo
174 |/
176 |/
175 o 0 "add foo" files: foo
177 o 0 "add foo" files: foo
176
178
177 245a3b8bc653999c2b22cdabd517ccb47aecafdf 644 bar
179 245a3b8bc653999c2b22cdabd517ccb47aecafdf 644 bar
178 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
180 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
179 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
181 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
180 $ splitrepo 'only some parents of an octopus merge; "discard" a head' 'foo baz quux'
182 $ splitrepo 'only some parents of an octopus merge; "discard" a head' 'foo baz quux'
181 % foo baz quux: only some parents of an octopus merge; "discard" a head
183 % foo baz quux: only some parents of an octopus merge; "discard" a head
182 @ 6 "Discard change to foo" files: foo
184 @ 6 "Discard change to foo" files: foo
183 |
185 |
184 o 5 "change foo" files: foo
186 o 5 "change foo" files: foo
185 |
187 |
186 o 4 "Octopus merge" files:
188 o 4 "Octopus merge" files:
187 |\
189 |\
188 | o 3 "add baz" files: baz
190 | o 3 "add baz" files: baz
189 | |
191 | |
190 | o 2 "add quux" files: quux
192 | o 2 "add quux" files: quux
191 | |
193 | |
192 o | 1 "change foo" files: foo
194 o | 1 "change foo" files: foo
193 |/
195 |/
194 o 0 "add foo" files: foo
196 o 0 "add foo" files: foo
195
197
196 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
198 354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
197 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
199 9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
198 88dfeab657e8cf2cef3dec67b914f49791ae76b1 644 quux
200 88dfeab657e8cf2cef3dec67b914f49791ae76b1 644 quux
199 $ echo
201 $ echo
200
202
201
203
202 test binary conversion (issue 1359)
204 test binary conversion (issue 1359)
203
205
204 $ mkdir git-repo3
206 $ mkdir git-repo3
205 $ cd git-repo3
207 $ cd git-repo3
206 $ git init-db >/dev/null 2>/dev/null
208 $ git init-db >/dev/null 2>/dev/null
207 $ python -c 'file("b", "wb").write("".join([chr(i) for i in range(256)])*16)'
209 $ python -c 'file("b", "wb").write("".join([chr(i) for i in range(256)])*16)'
208 $ git add b
210 $ git add b
209 $ commit -a -m addbinary
211 $ commit -a -m addbinary
210 $ cd ..
212 $ cd ..
211
213
212 convert binary file
214 convert binary file
213
215
214 $ hg convert git-repo3 git-repo3-hg
216 $ hg convert git-repo3 git-repo3-hg
215 initializing destination git-repo3-hg repository
217 initializing destination git-repo3-hg repository
216 scanning source...
218 scanning source...
217 sorting...
219 sorting...
218 converting...
220 converting...
219 0 addbinary
221 0 addbinary
222 updating bookmarks
220 $ cd git-repo3-hg
223 $ cd git-repo3-hg
221 $ hg up -C
224 $ hg up -C
222 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
225 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
223 $ python -c 'print len(file("b", "rb").read())'
226 $ python -c 'print len(file("b", "rb").read())'
224 4096
227 4096
225 $ cd ..
228 $ cd ..
226 $ echo
229 $ echo
227
230
228
231
229 test author vs committer
232 test author vs committer
230
233
231 $ mkdir git-repo4
234 $ mkdir git-repo4
232 $ cd git-repo4
235 $ cd git-repo4
233 $ git init-db >/dev/null 2>/dev/null
236 $ git init-db >/dev/null 2>/dev/null
234 $ echo >> foo
237 $ echo >> foo
235 $ git add foo
238 $ git add foo
236 $ commit -a -m addfoo
239 $ commit -a -m addfoo
237 $ echo >> foo
240 $ echo >> foo
238 $ GIT_AUTHOR_NAME="nottest"
241 $ GIT_AUTHOR_NAME="nottest"
239 $ commit -a -m addfoo2
242 $ commit -a -m addfoo2
240 $ cd ..
243 $ cd ..
241
244
242 convert author committer
245 convert author committer
243
246
244 $ hg convert git-repo4 git-repo4-hg
247 $ hg convert git-repo4 git-repo4-hg
245 initializing destination git-repo4-hg repository
248 initializing destination git-repo4-hg repository
246 scanning source...
249 scanning source...
247 sorting...
250 sorting...
248 converting...
251 converting...
249 1 addfoo
252 1 addfoo
250 0 addfoo2
253 0 addfoo2
254 updating bookmarks
251 $ hg -R git-repo4-hg log -v
255 $ hg -R git-repo4-hg log -v
252 changeset: 1:d63e967f93da
256 changeset: 1:d63e967f93da
257 bookmark: master
253 tag: tip
258 tag: tip
254 user: nottest <test@example.org>
259 user: nottest <test@example.org>
255 date: Mon Jan 01 00:00:21 2007 +0000
260 date: Mon Jan 01 00:00:21 2007 +0000
256 files: foo
261 files: foo
257 description:
262 description:
258 addfoo2
263 addfoo2
259
264
260 committer: test <test@example.org>
265 committer: test <test@example.org>
261
266
262
267
263 changeset: 0:0735477b0224
268 changeset: 0:0735477b0224
264 user: test <test@example.org>
269 user: test <test@example.org>
265 date: Mon Jan 01 00:00:20 2007 +0000
270 date: Mon Jan 01 00:00:20 2007 +0000
266 files: foo
271 files: foo
267 description:
272 description:
268 addfoo
273 addfoo
269
274
270
275
271
276
272 --sourceorder should fail
277 --sourceorder should fail
273
278
274 $ hg convert --sourcesort git-repo4 git-repo4-sourcesort-hg
279 $ hg convert --sourcesort git-repo4 git-repo4-sourcesort-hg
275 initializing destination git-repo4-sourcesort-hg repository
280 initializing destination git-repo4-sourcesort-hg repository
276 abort: --sourcesort is not supported by this data source
281 abort: --sourcesort is not supported by this data source
277 [255]
282 [255]
278
283
279 damage git repository and convert again
284 damage git repository and convert again
280
285
281 $ cat > damage.py <<EOF
286 $ cat > damage.py <<EOF
282 > import os
287 > import os
283 > for root, dirs, files in os.walk('git-repo4/.git/objects'):
288 > for root, dirs, files in os.walk('git-repo4/.git/objects'):
284 > if files:
289 > if files:
285 > path = os.path.join(root, files[0])
290 > path = os.path.join(root, files[0])
286 > os.remove(path)
291 > os.remove(path)
287 > break
292 > break
288 > EOF
293 > EOF
289 $ python damage.py
294 $ python damage.py
290 $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | \
295 $ hg convert git-repo4 git-repo4-broken-hg 2>&1 | \
291 > grep 'abort:' | sed 's/abort:.*/abort:/g'
296 > grep 'abort:' | sed 's/abort:.*/abort:/g'
292 abort:
297 abort:
@@ -1,82 +1,84 b''
1
1
2 $ "$TESTDIR/hghave" git || exit 80
2 $ "$TESTDIR/hghave" git || exit 80
3 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
4 $ echo "convert=" >> $HGRCPATH
4 $ echo "convert=" >> $HGRCPATH
5 $ echo 'hgext.graphlog =' >> $HGRCPATH
5 $ echo 'hgext.graphlog =' >> $HGRCPATH
6 $ echo '[convert]' >> $HGRCPATH
6 $ echo '[convert]' >> $HGRCPATH
7 $ echo 'hg.usebranchnames = True' >> $HGRCPATH
7 $ echo 'hg.usebranchnames = True' >> $HGRCPATH
8 $ echo 'hg.tagsbranch = tags-update' >> $HGRCPATH
8 $ echo 'hg.tagsbranch = tags-update' >> $HGRCPATH
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 $ count=10
15 $ count=10
16 $ action()
16 $ action()
17 > {
17 > {
18 > GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
18 > GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
19 > GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
19 > GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
20 > git "$@" >/dev/null 2>/dev/null || echo "git command error"
20 > git "$@" >/dev/null 2>/dev/null || echo "git command error"
21 > count=`expr $count + 1`
21 > count=`expr $count + 1`
22 > }
22 > }
23 $ glog()
23 $ glog()
24 > {
24 > {
25 > hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
25 > hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
26 > }
26 > }
27 $ convertrepo()
27 $ convertrepo()
28 > {
28 > {
29 > hg convert --datesort git-repo hg-repo
29 > hg convert --datesort git-repo hg-repo
30 > }
30 > }
31
31
32 Build a GIT repo with at least 1 tag
32 Build a GIT repo with at least 1 tag
33
33
34 $ mkdir git-repo
34 $ mkdir git-repo
35 $ cd git-repo
35 $ cd git-repo
36 $ git init >/dev/null 2>&1
36 $ git init >/dev/null 2>&1
37 $ echo a > a
37 $ echo a > a
38 $ git add a
38 $ git add a
39 $ action commit -m "rev1"
39 $ action commit -m "rev1"
40 $ action tag -m "tag1" tag1
40 $ action tag -m "tag1" tag1
41 $ cd ..
41 $ cd ..
42
42
43 Do a first conversion
43 Do a first conversion
44
44
45 $ convertrepo
45 $ convertrepo
46 initializing destination hg-repo repository
46 initializing destination hg-repo repository
47 scanning source...
47 scanning source...
48 sorting...
48 sorting...
49 converting...
49 converting...
50 0 rev1
50 0 rev1
51 updating tags
51 updating tags
52 updating bookmarks
52
53
53 Simulate upstream updates after first conversion
54 Simulate upstream updates after first conversion
54
55
55 $ cd git-repo
56 $ cd git-repo
56 $ echo b > a
57 $ echo b > a
57 $ git add a
58 $ git add a
58 $ action commit -m "rev2"
59 $ action commit -m "rev2"
59 $ action tag -m "tag2" tag2
60 $ action tag -m "tag2" tag2
60 $ cd ..
61 $ cd ..
61
62
62 Perform an incremental conversion
63 Perform an incremental conversion
63
64
64 $ convertrepo
65 $ convertrepo
65 scanning source...
66 scanning source...
66 sorting...
67 sorting...
67 converting...
68 converting...
68 0 rev2
69 0 rev2
69 updating tags
70 updating tags
71 updating bookmarks
70
72
71 Print the log
73 Print the log
72
74
73 $ cd hg-repo
75 $ cd hg-repo
74 $ glog
76 $ glog
75 o 3 "update tags" files: .hgtags
77 o 3 "update tags" files: .hgtags
76 |
78 |
77 | o 2 "rev2" files: a
79 | o 2 "rev2" files: a
78 | |
80 | |
79 o | 1 "update tags" files: .hgtags
81 o | 1 "update tags" files: .hgtags
80 /
82 /
81 o 0 "rev1" files: a
83 o 0 "rev1" files: a
82
84
General Comments 0
You need to be logged in to leave comments. Login now