annotate hgext/fastexport.py @ 45816:4b79e92a5ef8

tests: test more cases where a file got replaced by a copy This adds a test where a file is modified on one branch and is renamed onto another file in another branch. That should ideally be automatically resolved (by propagating the modification to the rename destination). Alternatively, it could be considered a modify/delete conflict. It should at least not be automatically resolved by ignoring the modification. However, that is what actually happens with the changeset-centric algorithm since I broke it in b4057d001760 (merge: when rename was made on both sides, use ancestor as merge base, 2020-01-22). Before that commit, it resulted in a modify/delete conflict. The filelog-centric algorithm was broken already before that commit. Differential Revision: https://phab.mercurial-scm.org/D8652
author Martin von Zweigbergk <martinvonz@google.com>
date Mon, 22 Jun 2020 22:47:33 -0700
parents edffab2cf0ea
children 5ced12cfa41b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
44280
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
1 # Copyright 2020 Joerg Sonnenberger <joerg@bec.de>
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
2 #
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
3 # This software may be used and distributed according to the terms of the
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
4 # GNU General Public License version 2 or any later version.
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
5 """export repositories as git fast-import stream"""
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
6
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
7 # The format specification for fast-import streams can be found at
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
8 # https://git-scm.com/docs/git-fast-import#_input_format
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
9
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
10 from __future__ import absolute_import
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
11 import re
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
12
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
13 from mercurial.i18n import _
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
14 from mercurial.node import hex, nullrev
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
15 from mercurial.utils import stringutil
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
16 from mercurial import (
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
17 error,
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
18 pycompat,
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
19 registrar,
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
20 scmutil,
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
21 )
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
22 from .convert import convcmd
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
23
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
24 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
25 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
26 # be specifying the version(s) of Mercurial they are tested with, or
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
27 # leave the attribute unspecified.
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
28 testedwith = b"ships-with-hg-core"
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
29
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
30 cmdtable = {}
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
31 command = registrar.command(cmdtable)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
32
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
33 GIT_PERSON_PROHIBITED = re.compile(b'[<>\n"]')
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
34 GIT_EMAIL_PROHIBITED = re.compile(b"[<> \n]")
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
35
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
36
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
37 def convert_to_git_user(authormap, user, rev):
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
38 mapped_user = authormap.get(user, user)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
39 user_person = stringutil.person(mapped_user)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
40 user_email = stringutil.email(mapped_user)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
41 if GIT_EMAIL_PROHIBITED.match(user_email) or GIT_PERSON_PROHIBITED.match(
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
42 user_person
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
43 ):
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
44 raise error.Abort(
44690
44aff45b556d fastexport: make a diagnostics message more localizable
Joerg Sonnenberger <joerg@bec.de>
parents: 44280
diff changeset
45 _(b"Unable to parse user into person and email for revision %s")
44aff45b556d fastexport: make a diagnostics message more localizable
Joerg Sonnenberger <joerg@bec.de>
parents: 44280
diff changeset
46 % rev
44280
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
47 )
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
48 if user_person:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
49 return b'"' + user_person + b'" <' + user_email + b'>'
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
50 else:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
51 return b"<" + user_email + b">"
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
52
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
53
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
54 def convert_to_git_date(date):
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
55 timestamp, utcoff = date
44821
edffab2cf0ea fastexport: adjust output to be more canonical
Joerg Sonnenberger <joerg@bec.de>
parents: 44811
diff changeset
56 tzsign = b"+" if utcoff <= 0 else b"-"
44280
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
57 if utcoff % 60 != 0:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
58 raise error.Abort(
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
59 _(b"UTC offset in %b is not an integer number of seconds") % (date,)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
60 )
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
61 utcoff = abs(utcoff) // 60
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
62 tzh = utcoff // 60
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
63 tzmin = utcoff % 60
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
64 return b"%d " % int(timestamp) + tzsign + b"%02d%02d" % (tzh, tzmin)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
65
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
66
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
67 def convert_to_git_ref(branch):
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
68 # XXX filter/map depending on git restrictions
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
69 return b"refs/heads/" + branch
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
70
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
71
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
72 def write_data(buf, data, skip_newline):
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
73 buf.append(b"data %d\n" % len(data))
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
74 buf.append(data)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
75 if not skip_newline or data[-1:] != b"\n":
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
76 buf.append(b"\n")
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
77
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
78
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
79 def export_commit(ui, repo, rev, marks, authormap):
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
80 ctx = repo[rev]
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
81 revid = ctx.hex()
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
82 if revid in marks:
44811
5d309906ed0e fastexport: downgrade message about already exported changesets to debug
Joerg Sonnenberger <joerg@bec.de>
parents: 44690
diff changeset
83 ui.debug(b"warning: revision %s already exported, skipped\n" % revid)
44280
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
84 return
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
85 parents = [p for p in ctx.parents() if p.rev() != nullrev]
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
86 for p in parents:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
87 if p.hex() not in marks:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
88 ui.warn(
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
89 _(b"warning: parent %s of %s has not been exported, skipped\n")
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
90 % (p, revid)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
91 )
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
92 return
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
93
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
94 # For all files modified by the commit, check if they have already
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
95 # been exported and otherwise dump the blob with the new mark.
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
96 for fname in ctx.files():
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
97 if fname not in ctx:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
98 continue
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
99 filectx = ctx.filectx(fname)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
100 filerev = hex(filectx.filenode())
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
101 if filerev not in marks:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
102 mark = len(marks) + 1
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
103 marks[filerev] = mark
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
104 data = filectx.data()
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
105 buf = [b"blob\n", b"mark :%d\n" % mark]
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
106 write_data(buf, data, False)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
107 ui.write(*buf, keepprogressbar=True)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
108 del buf
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
109
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
110 # Assign a mark for the current revision for references by
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
111 # latter merge commits.
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
112 mark = len(marks) + 1
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
113 marks[revid] = mark
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
114
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
115 ref = convert_to_git_ref(ctx.branch())
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
116 buf = [
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
117 b"commit %s\n" % ref,
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
118 b"mark :%d\n" % mark,
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
119 b"committer %s %s\n"
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
120 % (
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
121 convert_to_git_user(authormap, ctx.user(), revid),
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
122 convert_to_git_date(ctx.date()),
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
123 ),
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
124 ]
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
125 write_data(buf, ctx.description(), True)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
126 if parents:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
127 buf.append(b"from :%d\n" % marks[parents[0].hex()])
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
128 if len(parents) == 2:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
129 buf.append(b"merge :%d\n" % marks[parents[1].hex()])
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
130 p0ctx = repo[parents[0]]
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
131 files = ctx.manifest().diff(p0ctx.manifest())
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
132 else:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
133 files = ctx.files()
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
134 filebuf = []
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
135 for fname in files:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
136 if fname not in ctx:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
137 filebuf.append((fname, b"D %s\n" % fname))
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
138 else:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
139 filectx = ctx.filectx(fname)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
140 filerev = filectx.filenode()
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
141 fileperm = b"755" if filectx.isexec() else b"644"
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
142 changed = b"M %s :%d %s\n" % (fileperm, marks[hex(filerev)], fname)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
143 filebuf.append((fname, changed))
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
144 filebuf.sort()
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
145 buf.extend(changed for (fname, changed) in filebuf)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
146 del filebuf
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
147 buf.append(b"\n")
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
148 ui.write(*buf, keepprogressbar=True)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
149 del buf
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
150
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
151
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
152 isrev = re.compile(b"^[0-9a-f]{40}$")
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
153
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
154
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
155 @command(
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
156 b"fastexport",
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
157 [
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
158 (b"r", b"rev", [], _(b"revisions to export"), _(b"REV")),
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
159 (b"i", b"import-marks", b"", _(b"old marks file to read"), _(b"FILE")),
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
160 (b"e", b"export-marks", b"", _(b"new marks file to write"), _(b"FILE")),
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
161 (
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
162 b"A",
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
163 b"authormap",
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
164 b"",
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
165 _(b"remap usernames using this file"),
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
166 _(b"FILE"),
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
167 ),
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
168 ],
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
169 _(b"[OPTION]... [REV]..."),
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
170 helpcategory=command.CATEGORY_IMPORT_EXPORT,
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
171 )
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
172 def fastexport(ui, repo, *revs, **opts):
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
173 """export repository as git fast-import stream
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
174
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
175 This command lets you dump a repository as a human-readable text stream.
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
176 It can be piped into corresponding import routines like "git fast-import".
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
177 Incremental dumps can be created by using marks files.
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
178 """
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
179 opts = pycompat.byteskwargs(opts)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
180
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
181 revs += tuple(opts.get(b"rev", []))
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
182 if not revs:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
183 revs = scmutil.revrange(repo, [b":"])
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
184 else:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
185 revs = scmutil.revrange(repo, revs)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
186 if not revs:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
187 raise error.Abort(_(b"no revisions matched"))
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
188 authorfile = opts.get(b"authormap")
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
189 if authorfile:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
190 authormap = convcmd.readauthormap(ui, authorfile)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
191 else:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
192 authormap = {}
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
193
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
194 import_marks = opts.get(b"import_marks")
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
195 marks = {}
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
196 if import_marks:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
197 with open(import_marks, "rb") as import_marks_file:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
198 for line in import_marks_file:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
199 line = line.strip()
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
200 if not isrev.match(line) or line in marks:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
201 raise error.Abort(_(b"Corrupted marks file"))
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
202 marks[line] = len(marks) + 1
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
203
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
204 revs.sort()
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
205 with ui.makeprogress(
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
206 _(b"exporting"), unit=_(b"revisions"), total=len(revs)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
207 ) as progress:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
208 for rev in revs:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
209 export_commit(ui, repo, rev, marks, authormap)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
210 progress.increment()
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
211
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
212 export_marks = opts.get(b"export_marks")
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
213 if export_marks:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
214 with open(export_marks, "wb") as export_marks_file:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
215 output_marks = [None] * len(marks)
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
216 for k, v in marks.items():
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
217 output_marks[v - 1] = k
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
218 for k in output_marks:
93a05cb223da hgext: initial version of fastexport extension
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
219 export_marks_file.write(k + b"\n")