Mercurial > hg > mercurial-crew-with-dirclash
annotate hgext/convert/git.py @ 5192:33015dac5df5
convert: fix mercurial_sink.putcommit
Changeset 4ebc8693ce72 added some code to putcommit to avoid creating a
revision that touches no files, but this can break regular conversions
from some repositories:
- conceptually, since we're converting a repo, we should try to make
the new hg repo as similar as possible to the original repo - we
should create a new changeset, even if the original revision didn't
touch any files (maybe the commit message had some important bit);
- even if a "regular" revision that doesn't touch any file may seem
weird (and maybe even broken), it's completely legitimate for a merge
revision to not touch any file, and, if we just skip it, the
converted repo will end up with wrong history and possibly an extra
head.
As an example, say the crew and main hg repos are sync'ed. Somebody
sends an important patch to the mailing list. Matt quickly applies
and pushes it. But at the same time somebody also applies it to crew
and pushes it. Suppose the commit message ended up being a bit
different (say, there was a typo and somebody didn't fix it) or that
the date ended up being different (because of different patch-applying
scripts): the changeset hashes will be different, but the manifests
will be the same.
Since both changesets were pushed to public repos, it's hard to recall
them. If both are merged, the manifest from the resulting merge
revision will have the exact same contents as its parents - i.e. the
merge revision really doesn't touch any file at all.
To keep the file filtering stuff "working", the generic code was changed
to skip empty revisions if we're filtering the repo, fixing a bug in the
process (we want parents[0] instead of tip).
author | Alexis S. L. Carvalho <alexis@cecm.usp.br> |
---|---|
date | Fri, 17 Aug 2007 20:18:05 -0300 |
parents | ef338e34a906 |
children | 7d3dcdd92a1a |
rev | line source |
---|---|
4534
cc9b79216a76
Split convert extension into common and repository type modules
Brendan Cully <brendan@kublai.com>
parents:
4532
diff
changeset
|
1 # git support for the convert extension |
3825
158fce02dc40
Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents:
2649
diff
changeset
|
2 |
4534
cc9b79216a76
Split convert extension into common and repository type modules
Brendan Cully <brendan@kublai.com>
parents:
4532
diff
changeset
|
3 import os |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
4 |
4534
cc9b79216a76
Split convert extension into common and repository type modules
Brendan Cully <brendan@kublai.com>
parents:
4532
diff
changeset
|
5 from common import NoRepo, commit, converter_source |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
6 |
4447
af013ae3ca10
use documented convert-repo interface
Daniel Holth <dholth@fastmail.fm>
parents:
4446
diff
changeset
|
7 class convert_git(converter_source): |
4760
2d0a823cbba5
convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents:
4753
diff
changeset
|
8 def gitcmd(self, s): |
2d0a823cbba5
convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents:
4753
diff
changeset
|
9 return os.popen('GIT_DIR=%s %s' % (self.path, s)) |
2d0a823cbba5
convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents:
4753
diff
changeset
|
10 |
4753
07efcce17d28
convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents:
4752
diff
changeset
|
11 def __init__(self, ui, path, rev=None): |
4806
15a3cbfc6568
convert: call superclass init from engine init functions
Brendan Cully <brendan@kublai.com>
parents:
4761
diff
changeset
|
12 super(convert_git, self).__init__(ui, path, rev=rev) |
15a3cbfc6568
convert: call superclass init from engine init functions
Brendan Cully <brendan@kublai.com>
parents:
4761
diff
changeset
|
13 |
3947
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
14 if os.path.isdir(path + "/.git"): |
0fab73b3f453
convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents:
3916
diff
changeset
|
15 path += "/.git" |
4752
20ec5cc02f18
convert: ove recode method into converter_source
Brendan Cully <brendan@kublai.com>
parents:
4721
diff
changeset
|
16 if not os.path.exists(path + "/objects"): |
20ec5cc02f18
convert: ove recode method into converter_source
Brendan Cully <brendan@kublai.com>
parents:
4721
diff
changeset
|
17 raise NoRepo("couldn't open GIT repo %s" % path) |
316 | 18 self.path = path |
19 | |
20 def getheads(self): | |
4761
f52bfe566583
convert: import all branches from git repositories
Brendan Cully <brendan@kublai.com>
parents:
4760
diff
changeset
|
21 if not self.rev: |
f52bfe566583
convert: import all branches from git repositories
Brendan Cully <brendan@kublai.com>
parents:
4760
diff
changeset
|
22 return self.gitcmd('git-rev-parse --branches').read().splitlines() |
f52bfe566583
convert: import all branches from git repositories
Brendan Cully <brendan@kublai.com>
parents:
4760
diff
changeset
|
23 else: |
f52bfe566583
convert: import all branches from git repositories
Brendan Cully <brendan@kublai.com>
parents:
4760
diff
changeset
|
24 fh = self.gitcmd("git-rev-parse --verify %s" % self.rev) |
f52bfe566583
convert: import all branches from git repositories
Brendan Cully <brendan@kublai.com>
parents:
4760
diff
changeset
|
25 return [fh.read()[:-1]] |
316 | 26 |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
27 def catfile(self, rev, type): |
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
28 if rev == "0" * 40: raise IOError() |
4760
2d0a823cbba5
convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents:
4753
diff
changeset
|
29 fh = self.gitcmd("git-cat-file %s %s 2>/dev/null" % (type, rev)) |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
30 return fh.read() |
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
31 |
316 | 32 def getfile(self, name, rev): |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
33 return self.catfile(rev, "blob") |
316 | 34 |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
35 def getmode(self, name, rev): |
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
36 return self.modecache[(name, rev)] |
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
37 |
316 | 38 def getchanges(self, version): |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
39 self.modecache = {} |
4760
2d0a823cbba5
convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents:
4753
diff
changeset
|
40 fh = self.gitcmd("git-diff-tree --root -m -r %s" % version) |
316 | 41 changes = [] |
42 for l in fh: | |
43 if "\t" not in l: continue | |
44 m, f = l[:-1].split("\t") | |
45 m = m.split() | |
46 h = m[3] | |
47 p = (m[1] == "100755") | |
4082
6b2909e84203
convert-repo converts symlinks from git
Daniel Holth <dholth@fastmail.fm>
parents:
4062
diff
changeset
|
48 s = (m[1] == "120000") |
6b2909e84203
convert-repo converts symlinks from git
Daniel Holth <dholth@fastmail.fm>
parents:
4062
diff
changeset
|
49 self.modecache[(f, h)] = (p and "x") or (s and "l") or "" |
3957
558f52943cd2
convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents:
3955
diff
changeset
|
50 changes.append((f, h)) |
5076
ef338e34a906
convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents:
4873
diff
changeset
|
51 return (changes, {}) |
316 | 52 |
53 def getcommit(self, version): | |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
54 c = self.catfile(version, "commit") # read the commit hash |
316 | 55 end = c.find("\n\n") |
56 message = c[end+2:] | |
4752
20ec5cc02f18
convert: ove recode method into converter_source
Brendan Cully <brendan@kublai.com>
parents:
4721
diff
changeset
|
57 message = self.recode(message) |
316 | 58 l = c[:end].splitlines() |
59 manifest = l[0].split()[1] | |
60 parents = [] | |
61 for e in l[1:]: | |
4532
c3a78a49d7f0
Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4521
diff
changeset
|
62 n, v = e.split(" ", 1) |
316 | 63 if n == "author": |
64 p = v.split() | |
1385
adb3de56635b
convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents:
1335
diff
changeset
|
65 tm, tz = p[-2:] |
316 | 66 author = " ".join(p[:-2]) |
67 if author[0] == "<": author = author[1:-1] | |
4752
20ec5cc02f18
convert: ove recode method into converter_source
Brendan Cully <brendan@kublai.com>
parents:
4721
diff
changeset
|
68 author = self.recode(author) |
692
695dd9a491da
convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents:
450
diff
changeset
|
69 if n == "committer": |
431 | 70 p = v.split() |
1385
adb3de56635b
convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents:
1335
diff
changeset
|
71 tm, tz = p[-2:] |
431 | 72 committer = " ".join(p[:-2]) |
73 if committer[0] == "<": committer = committer[1:-1] | |
4752
20ec5cc02f18
convert: ove recode method into converter_source
Brendan Cully <brendan@kublai.com>
parents:
4721
diff
changeset
|
74 committer = self.recode(committer) |
3910
4bc5a2405b12
convert-repo: fix recoding of committer
Matt Mackall <mpm@selenic.com>
parents:
3825
diff
changeset
|
75 message += "\ncommitter: %s\n" % committer |
316 | 76 if n == "parent": parents.append(v) |
1385
adb3de56635b
convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents:
1335
diff
changeset
|
77 |
adb3de56635b
convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents:
1335
diff
changeset
|
78 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:] |
2093
5cc414722587
convert-repo: fix reversed time zone offset
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1715
diff
changeset
|
79 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm)) |
1385
adb3de56635b
convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents:
1335
diff
changeset
|
80 date = tm + " " + str(tz) |
4721
96614af3c679
convert: "unknown" is a string
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4687
diff
changeset
|
81 author = author or "unknown" |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
82 |
4873
28b23b9073a8
convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents:
4809
diff
changeset
|
83 c = commit(parents=parents, date=date, author=author, desc=message, |
28b23b9073a8
convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents:
4809
diff
changeset
|
84 rev=version) |
3955
9af4b853ed4d
convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents:
3954
diff
changeset
|
85 return c |
316 | 86 |
694 | 87 def gettags(self): |
88 tags = {} | |
4760
2d0a823cbba5
convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents:
4753
diff
changeset
|
89 fh = self.gitcmd('git-ls-remote --tags "%s" 2>/dev/null' % self.path) |
4062
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
90 prefix = 'refs/tags/' |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
91 for line in fh: |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
92 line = line.strip() |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
93 if not line.endswith("^{}"): |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
94 continue |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
95 node, tag = line.split(None, 1) |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
96 if not tag.startswith(prefix): |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
97 continue |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
98 tag = tag[len(prefix):-3] |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
99 tags[tag] = node |
516f883e3d79
convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4047
diff
changeset
|
100 |
694 | 101 return tags |