Mercurial > hg-git
annotate hggit/hg2git.py @ 894:1959fd51ea12
hg2git: flake8 cleanup
author | Sean Farley <sean@farley.io> |
---|---|
date | Wed, 22 Apr 2015 16:42:48 -0700 |
parents | 81c55f8629ba |
children | 1b8d70c2bbfa |
rev | line source |
---|---|
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
1 # This file contains code dealing specifically with converting Mercurial |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
2 # repositories to Git repositories. Code in this file is meant to be a generic |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
3 # library and should be usable outside the context of hg-git or an hg command. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
4 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
5 import os |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
6 import stat |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
7 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
8 import dulwich.objects as dulobjs |
850
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
9 from mercurial import util as hgutil |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
10 |
850
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
11 import compat |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
12 import util |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 |
671
71fb5dd678bc
hg2git: move parse_subrepos to top level
Siddharth Agarwal <sid0@fb.com>
parents:
649
diff
changeset
|
14 def parse_subrepos(ctx): |
71fb5dd678bc
hg2git: move parse_subrepos to top level
Siddharth Agarwal <sid0@fb.com>
parents:
649
diff
changeset
|
15 sub = util.OrderedDict() |
71fb5dd678bc
hg2git: move parse_subrepos to top level
Siddharth Agarwal <sid0@fb.com>
parents:
649
diff
changeset
|
16 if '.hgsub' in ctx: |
71fb5dd678bc
hg2git: move parse_subrepos to top level
Siddharth Agarwal <sid0@fb.com>
parents:
649
diff
changeset
|
17 sub = util.parse_hgsub(ctx['.hgsub'].data().splitlines()) |
71fb5dd678bc
hg2git: move parse_subrepos to top level
Siddharth Agarwal <sid0@fb.com>
parents:
649
diff
changeset
|
18 substate = util.OrderedDict() |
71fb5dd678bc
hg2git: move parse_subrepos to top level
Siddharth Agarwal <sid0@fb.com>
parents:
649
diff
changeset
|
19 if '.hgsubstate' in ctx: |
71fb5dd678bc
hg2git: move parse_subrepos to top level
Siddharth Agarwal <sid0@fb.com>
parents:
649
diff
changeset
|
20 substate = util.parse_hgsubstate( |
71fb5dd678bc
hg2git: move parse_subrepos to top level
Siddharth Agarwal <sid0@fb.com>
parents:
649
diff
changeset
|
21 ctx['.hgsubstate'].data().splitlines()) |
71fb5dd678bc
hg2git: move parse_subrepos to top level
Siddharth Agarwal <sid0@fb.com>
parents:
649
diff
changeset
|
22 return sub, substate |
71fb5dd678bc
hg2git: move parse_subrepos to top level
Siddharth Agarwal <sid0@fb.com>
parents:
649
diff
changeset
|
23 |
850
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
24 |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
25 def audit_git_path(ui, path): |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
26 r"""Check for path components that case-fold to .git. |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
27 |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
28 >>> class fakeui(object): |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
29 ... def configbool(*args): |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
30 ... return False |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
31 ... def warn(self, s): |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
32 ... print s |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
33 >>> u = fakeui() |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
34 >>> audit_git_path(u, 'foo/git~100/wat') |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
35 warning: path 'foo/git~100/wat' contains a potentially dangerous path component. |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
36 It may not be legal to check out in Git. |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
37 It may also be rejected by some git server configurations. |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
38 <BLANKLINE> |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
39 >>> audit_git_path(u, u'foo/.gi\u200ct'.encode('utf-8')) |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
40 warning: path 'foo/.gi\xe2\x80\x8ct' contains a potentially dangerous path component. |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
41 It may not be legal to check out in Git. |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
42 It may also be rejected by some git server configurations. |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
43 <BLANKLINE> |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
44 >>> audit_git_path(u, 'this/is/safe') |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
45 """ |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
46 dangerous = False |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
47 for c in path.split(os.path.sep): |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
48 if compat.hfsignoreclean(c) == '.git': |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
49 dangerous = True |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
50 break |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
51 elif '~' in c: |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
52 base, tail = c.split('~', 1) |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
53 if tail.isdigit() and base.upper().startswith('GIT'): |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
54 dangerous = True |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
55 break |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
56 if dangerous: |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
57 if ui.configbool('git', 'blockdotgit', True): |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
58 raise hgutil.Abort( |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
59 ('Refusing to export likely-dangerous path %r' % path), |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
60 hint=("If you need to continue, read about CVE-2014-9390 and " |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
61 "then set '[git] blockdotgit = false' in your hgrc.")) |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
62 ui.warn('warning: path %r contains a potentially dangerous path ' |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
63 'component.\n' |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
64 'It may not be legal to check out in Git.\n' |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
65 'It may also be rejected by some git server configurations.\n' |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
66 % path) |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
67 |
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
68 |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
69 class IncrementalChangesetExporter(object): |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
70 """Incrementally export Mercurial changesets to Git trees. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
71 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
72 The purpose of this class is to facilitate Git tree export that is more |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
73 optimal than brute force. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
74 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
75 A "dumb" implementations of Mercurial to Git export would iterate over |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
76 every file present in a Mercurial changeset and would convert each to |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
77 a Git blob and then conditionally add it to a Git repository if it didn't |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
78 yet exist. This is suboptimal because the overhead associated with |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
79 obtaining every file's raw content and converting it to a Git blob is |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
80 not trivial! |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
81 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
82 This class works around the suboptimality of brute force export by |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
83 leveraging the information stored in Mercurial - the knowledge of what |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
84 changed between changesets - to only export Git objects corresponding to |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
85 changes in Mercurial. In the context of converting Mercurial repositories |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
86 to Git repositories, we only export objects Git (possibly) hasn't seen yet. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
87 This prevents a lot of redundant work and is thus faster. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
88 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
89 Callers instantiate an instance of this class against a mercurial.localrepo |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
90 instance. They then associate it with a specific changesets by calling |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
91 update_changeset(). On each call to update_changeset(), the instance |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
92 computes the difference between the current and new changesets and emits |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
93 Git objects that haven't yet been encountered during the lifetime of the |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
94 class instance. In other words, it expresses Mercurial changeset deltas in |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
95 terms of Git objects. Callers then (usually) take this set of Git objects |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
96 and add them to the Git repository. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
97 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
98 This class only emits Git blobs and trees, not commits. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
99 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
100 The tree calculation part of this class is essentially a reimplementation |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
101 of dulwich.index.commit_tree. However, since our implementation reuses |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
102 Tree instances and only recalculates SHA-1 when things change, we are |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
103 more efficient. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
104 """ |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
105 |
709
5c7943ca051f
hg2git: start incremental conversion from a known commit
Siddharth Agarwal <sid0@fb.com>
parents:
707
diff
changeset
|
106 def __init__(self, hg_repo, start_ctx, git_store, git_commit): |
5c7943ca051f
hg2git: start incremental conversion from a known commit
Siddharth Agarwal <sid0@fb.com>
parents:
707
diff
changeset
|
107 """Create an instance against a mercurial.localrepo. |
5c7943ca051f
hg2git: start incremental conversion from a known commit
Siddharth Agarwal <sid0@fb.com>
parents:
707
diff
changeset
|
108 |
894 | 109 start_ctx: the context for a Mercurial commit that has a Git |
110 equivalent, passed in as git_commit. The incremental | |
111 computation will be started from this commit. | |
112 git_store: the Git object store the commit comes from. | |
113 | |
114 start_ctx can be repo[nullid], in which case git_commit should be None. | |
709
5c7943ca051f
hg2git: start incremental conversion from a known commit
Siddharth Agarwal <sid0@fb.com>
parents:
707
diff
changeset
|
115 """ |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
116 self._hg = hg_repo |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
117 |
637
23d7caeed05a
hg2git: store ctx instead of rev
Siddharth Agarwal <sid0@fb.com>
parents:
636
diff
changeset
|
118 # Our current revision's context. |
709
5c7943ca051f
hg2git: start incremental conversion from a known commit
Siddharth Agarwal <sid0@fb.com>
parents:
707
diff
changeset
|
119 self._ctx = start_ctx |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
120 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
121 # Path to dulwich.objects.Tree. |
709
5c7943ca051f
hg2git: start incremental conversion from a known commit
Siddharth Agarwal <sid0@fb.com>
parents:
707
diff
changeset
|
122 self._init_dirs(git_store, git_commit) |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
123 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
124 # Mercurial file nodeid to Git blob SHA-1. Used to prevent redundant |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
125 # blob calculation. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
126 self._blob_cache = {} |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
127 |
707
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
128 def _init_dirs(self, store, commit): |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
129 """Initialize self._dirs for a Git object store and commit.""" |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
130 self._dirs = {} |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
131 if commit is None: |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
132 return |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
133 dirkind = stat.S_IFDIR |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
134 # depth-first order, chosen arbitrarily |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
135 todo = [('', store[commit.tree])] |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
136 while todo: |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
137 path, tree = todo.pop() |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
138 self._dirs[path] = tree |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
139 for entry in tree.iteritems(): |
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
140 if entry.mode == dirkind: |
710
623cb724c3d0
hg2git: in _init_dirs, store keys without leading '/' (issue103)
Siddharth Agarwal <sid0@fb.com>
parents:
709
diff
changeset
|
141 if path == '': |
623cb724c3d0
hg2git: in _init_dirs, store keys without leading '/' (issue103)
Siddharth Agarwal <sid0@fb.com>
parents:
709
diff
changeset
|
142 newpath = entry.path |
623cb724c3d0
hg2git: in _init_dirs, store keys without leading '/' (issue103)
Siddharth Agarwal <sid0@fb.com>
parents:
709
diff
changeset
|
143 else: |
623cb724c3d0
hg2git: in _init_dirs, store keys without leading '/' (issue103)
Siddharth Agarwal <sid0@fb.com>
parents:
709
diff
changeset
|
144 newpath = path + '/' + entry.path |
623cb724c3d0
hg2git: in _init_dirs, store keys without leading '/' (issue103)
Siddharth Agarwal <sid0@fb.com>
parents:
709
diff
changeset
|
145 todo.append((newpath, store[entry.sha])) |
707
d5facc1be5f8
hg2git: implement a method to initialize _dirs from a Git commit
Siddharth Agarwal <sid0@fb.com>
parents:
672
diff
changeset
|
146 |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
147 @property |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
148 def root_tree_sha(self): |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
149 """The SHA-1 of the root Git tree. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
150 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
151 This is needed to construct a Git commit object. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
152 """ |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
153 return self._dirs[''].id |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
154 |
636
0ab89bd32c8e
hg2git: rename ctx to newctx in update_changeset
Siddharth Agarwal <sid0@fb.com>
parents:
598
diff
changeset
|
155 def update_changeset(self, newctx): |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
156 """Set the tree to track a new Mercurial changeset. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
157 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
158 This is a generator of 2-tuples. The first item in each tuple is a |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
159 dulwich object, either a Blob or a Tree. The second item is the |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
160 corresponding Mercurial nodeid for the item, if any. Only blobs will |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
161 have nodeids. Trees do not correspond to a specific nodeid, so it does |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
162 not make sense to emit a nodeid for them. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
163 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
164 When exporting trees from Mercurial, callers typically write the |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
165 returned dulwich object to the Git repo via the store's add_object(). |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
166 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
167 Some emitted objects may already exist in the Git repository. This |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
168 class does not know about the Git repository, so it's up to the caller |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
169 to conditionally add the object, etc. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
170 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
171 Emitted objects are those that have changed since the last call to |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
172 update_changeset. If this is the first call to update_chanageset, all |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
173 objects in the tree are emitted. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
174 """ |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
175 # Our general strategy is to accumulate dulwich.objects.Blob and |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
176 # dulwich.objects.Tree instances for the current Mercurial changeset. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
177 # We do this incremental by iterating over the Mercurial-reported |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
178 # changeset delta. We rely on the behavior of Mercurial to lazy |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
179 # calculate a Tree's SHA-1 when we modify it. This is critical to |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
180 # performance. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
181 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
182 # In theory we should be able to look at changectx.files(). This is |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
183 # *much* faster. However, it may not be accurate, especially with older |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
184 # repositories, which may not record things like deleted files |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
185 # explicitly in the manifest (which is where files() gets its data). |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
186 # The only reliable way to get the full set of changes is by looking at |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
187 # the full manifest. And, the easy way to compare two manifests is |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
188 # localrepo.status(). |
638
f828d82c35dc
hg2git: call status on newctx, not newctx.rev()
Siddharth Agarwal <sid0@fb.com>
parents:
637
diff
changeset
|
189 modified, added, removed = self._hg.status(self._ctx, newctx)[0:3] |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
190 |
598
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
191 # We track which directories/trees have modified in this update and we |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
192 # only export those. |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
193 dirty_trees = set() |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
194 |
672
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
195 subadded, subremoved = [], [] |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
196 |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
197 for s in modified, added, removed: |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
198 if '.hgsub' in s or '.hgsubstate' in s: |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
199 subadded, subremoved = self._handle_subrepos(newctx) |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
200 break |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
201 |
894 | 202 # We first process subrepo and file removals so we can prune dead |
203 # trees. | |
672
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
204 for path in subremoved: |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
205 self._remove_path(path, dirty_trees) |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
206 |
598
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
207 for path in removed: |
672
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
208 if path == '.hgsubstate' or path == '.hgsub': |
649
53423381c540
hg2git: call _handle_subrepos when .hgsubstate is removed
Siddharth Agarwal <sid0@fb.com>
parents:
648
diff
changeset
|
209 continue |
53423381c540
hg2git: call _handle_subrepos when .hgsubstate is removed
Siddharth Agarwal <sid0@fb.com>
parents:
648
diff
changeset
|
210 |
645
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
211 self._remove_path(path, dirty_trees) |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
212 |
672
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
213 for path, sha in subadded: |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
214 d = os.path.dirname(path) |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
215 tree = self._dirs.setdefault(d, dulobjs.Tree()) |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
216 dirty_trees.add(d) |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
217 tree.add(os.path.basename(path), dulobjs.S_IFGITLINK, sha) |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
218 |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
219 # For every file that changed or was added, we need to calculate the |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
220 # corresponding Git blob and its tree entry. We emit the blob |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
221 # immediately and update trees to be aware of its presence. |
598
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
222 for path in set(modified) | set(added): |
850
81c55f8629ba
hg2git: audit path components during export (CVE-2014-9390)
Augie Fackler <raf@durin42.com>
parents:
710
diff
changeset
|
223 audit_git_path(self._hg.ui, path) |
672
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
224 if path == '.hgsubstate' or path == '.hgsub': |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
225 continue |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
226 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
227 d = os.path.dirname(path) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
228 tree = self._dirs.setdefault(d, dulobjs.Tree()) |
598
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
229 dirty_trees.add(d) |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
230 |
636
0ab89bd32c8e
hg2git: rename ctx to newctx in update_changeset
Siddharth Agarwal <sid0@fb.com>
parents:
598
diff
changeset
|
231 fctx = newctx[path] |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
232 |
894 | 233 func = IncrementalChangesetExporter.tree_entry |
234 entry, blob = func(fctx, self._blob_cache) | |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
235 if blob is not None: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
236 yield (blob, fctx.filenode()) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
237 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
238 tree.add(*entry) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
239 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
240 # Now that all the trees represent the current changeset, recalculate |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
241 # the tree IDs and emit them. Note that we wait until now to calculate |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
242 # tree SHA-1s. This is an important difference between us and |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
243 # dulwich.index.commit_tree(), which builds new Tree instances for each |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
244 # series of blobs. |
598
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
245 for obj in self._populate_tree_entries(dirty_trees): |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
246 yield (obj, None) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
247 |
637
23d7caeed05a
hg2git: store ctx instead of rev
Siddharth Agarwal <sid0@fb.com>
parents:
636
diff
changeset
|
248 self._ctx = newctx |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
249 |
645
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
250 def _remove_path(self, path, dirty_trees): |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
251 """Remove a path (file or git link) from the current changeset. |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
252 |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
253 If the tree containing this path is empty, it might be removed.""" |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
254 d = os.path.dirname(path) |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
255 tree = self._dirs.get(d, dulobjs.Tree()) |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
256 |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
257 del tree[os.path.basename(path)] |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
258 dirty_trees.add(d) |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
259 |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
260 # If removing this file made the tree empty, we should delete this |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
261 # tree. This could result in parent trees losing their only child |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
262 # and so on. |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
263 if not len(tree): |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
264 self._remove_tree(d) |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
265 else: |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
266 self._dirs[d] = tree |
104f536be5c7
hg2git: factor out remove path logic into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
638
diff
changeset
|
267 |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
268 def _remove_tree(self, path): |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
269 """Remove a (presumably empty) tree from the current changeset. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
270 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
271 A now-empty tree may be the only child of its parent. So, we traverse |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
272 up the chain to the root tree, deleting any empty trees along the way. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
273 """ |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
274 try: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
275 del self._dirs[path] |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
276 except KeyError: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
277 return |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
278 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
279 # Now we traverse up to the parent and delete any references. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
280 if path == '': |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
281 return |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
282 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
283 basename = os.path.basename(path) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
284 parent = os.path.dirname(path) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
285 while True: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
286 tree = self._dirs.get(parent, None) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
287 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
288 # No parent entry. Nothing to remove or update. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
289 if tree is None: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
290 return |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
291 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
292 try: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
293 del tree[basename] |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
294 except KeyError: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
295 return |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
296 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
297 if len(tree): |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
298 return |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
299 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
300 # The parent tree is empty. Se, we can delete it. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
301 del self._dirs[parent] |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
302 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
303 if parent == '': |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
304 return |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
305 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
306 basename = os.path.basename(parent) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
307 parent = os.path.dirname(parent) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
308 |
598
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
309 def _populate_tree_entries(self, dirty_trees): |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
310 self._dirs.setdefault('', dulobjs.Tree()) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
311 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
312 # Fill in missing directories. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
313 for path in self._dirs.keys(): |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
314 parent = os.path.dirname(path) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
315 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
316 while parent != '': |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
317 parent_tree = self._dirs.get(parent, None) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
318 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
319 if parent_tree is not None: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
320 break |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
321 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
322 self._dirs[parent] = dulobjs.Tree() |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
323 parent = os.path.dirname(parent) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
324 |
598
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
325 for dirty in list(dirty_trees): |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
326 parent = os.path.dirname(dirty) |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
327 |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
328 while parent != '': |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
329 if parent in dirty_trees: |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
330 break |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
331 |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
332 dirty_trees.add(parent) |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
333 parent = os.path.dirname(parent) |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
334 |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
335 # The root tree is always dirty but doesn't always get updated. |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
336 dirty_trees.add('') |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
337 |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
338 # We only need to recalculate and export dirty trees. |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
339 for d in sorted(dirty_trees, key=len, reverse=True): |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
340 # Only happens for deleted directories. |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
341 try: |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
342 tree = self._dirs[d] |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
343 except KeyError: |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
344 continue |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
345 |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
346 yield tree |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
347 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
348 if d == '': |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
349 continue |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
350 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
351 parent_tree = self._dirs[os.path.dirname(d)] |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
352 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
353 # Accessing the tree's ID is what triggers SHA-1 calculation and is |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
354 # the expensive part (at least if the tree has been modified since |
598
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
355 # the last time we retrieved its ID). Also, assigning an entry to a |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
356 # tree (even if it already exists) invalidates the existing tree |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
357 # and incurs SHA-1 recalculation. So, it's in our interest to avoid |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
358 # invalidating trees. Since we only update the entries of dirty |
792955be68dd
Only export modified Git trees
Gregory Szorc <gregory.szorc@gmail.com>
parents:
596
diff
changeset
|
359 # trees, this should hold true. |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
360 parent_tree[os.path.basename(d)] = (stat.S_IFDIR, tree.id) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
361 |
672
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
362 def _handle_subrepos(self, newctx): |
648
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
363 sub, substate = parse_subrepos(self._ctx) |
647
3ceacdd23abe
hg2git: add 'new' prefix to _handle_subrepos variables
Siddharth Agarwal <sid0@fb.com>
parents:
646
diff
changeset
|
364 newsub, newsubstate = parse_subrepos(newctx) |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
365 |
648
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
366 # For each path, the logic is described by the following table. 'no' |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
367 # stands for 'the subrepo doesn't exist', 'git' stands for 'git |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
368 # subrepo', and 'hg' stands for 'hg or other subrepo'. |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
369 # |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
370 # old new | action |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
371 # * git | link (1) |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
372 # git hg | delete (2) |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
373 # git no | delete (3) |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
374 # |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
375 # All other combinations are 'do nothing'. |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
376 # |
894 | 377 # git links without corresponding submodule paths are stored as |
378 # subrepos with a substate but without an entry in .hgsub. | |
648
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
379 |
672
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
380 # 'added' is both modified and added |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
381 added, removed = [], [] |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
382 |
648
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
383 def isgit(sub, path): |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
384 return path not in sub or sub[path].startswith('[git]') |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
385 |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
386 for path, sha in substate.iteritems(): |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
387 if not isgit(sub, path): |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
388 # old = hg -- will be handled in next loop |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
389 continue |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
390 # old = git |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
391 if path not in newsubstate or not isgit(newsub, path): |
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
392 # new = hg or no, case (2) or (3) |
672
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
393 removed.append(path) |
648
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
394 |
647
3ceacdd23abe
hg2git: add 'new' prefix to _handle_subrepos variables
Siddharth Agarwal <sid0@fb.com>
parents:
646
diff
changeset
|
395 for path, sha in newsubstate.iteritems(): |
648
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
396 if not isgit(newsub, path): |
894 | 397 # new = hg or no; the only cases we care about are handled |
398 # above | |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
399 continue |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
400 |
648
bd63cdfbc1de
hg2git: make _handle_subrepos worked in the removed case
Siddharth Agarwal <sid0@fb.com>
parents:
647
diff
changeset
|
401 # case (1) |
672
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
402 added.append((path, sha)) |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
403 |
fbfa6353d96c
hg2git: fix subrepo handling to be deterministic
Siddharth Agarwal <sid0@fb.com>
parents:
671
diff
changeset
|
404 return added, removed |
596
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
405 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
406 @staticmethod |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
407 def tree_entry(fctx, blob_cache): |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
408 """Compute a dulwich TreeEntry from a filectx. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
409 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
410 A side effect is the TreeEntry is stored in the passed cache. |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
411 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
412 Returns a 2-tuple of (dulwich.objects.TreeEntry, dulwich.objects.Blob). |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
413 """ |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
414 blob_id = blob_cache.get(fctx.filenode(), None) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
415 blob = None |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
416 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
417 if blob_id is None: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
418 blob = dulobjs.Blob.from_string(fctx.data()) |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
419 blob_id = blob.id |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
420 blob_cache[fctx.filenode()] = blob_id |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
421 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
422 flags = fctx.flags() |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
423 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
424 if 'l' in flags: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
425 mode = 0120000 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
426 elif 'x' in flags: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
427 mode = 0100755 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
428 else: |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
429 mode = 0100644 |
d6b9c30a3e0f
Export Git objects from incremental Mercurial changes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
430 |
894 | 431 return (dulobjs.TreeEntry(os.path.basename(fctx.path()), mode, |
432 blob_id), blob) |