Mercurial > hg
annotate mercurial/subrepo.py @ 9781:eccc8aacd6f9
subrepo: do a linear update when appropriate
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sat, 07 Nov 2009 16:31:43 -0600 |
parents | 1ee085511b89 |
children | c1c40511c276 |
rev | line source |
---|---|
8812
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
1 # subrepo.py - sub-repository handling for Mercurial |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
2 # |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com> |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
4 # |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2, incorporated herein by reference. |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
7 |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
8 import errno, os |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
9 from i18n import _ |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
10 import config, util, node, error |
9092
9aebeea7ac00
subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents:
9049
diff
changeset
|
11 hg = None |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
12 |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
13 nullstate = ('', '') |
8812
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
14 |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
15 def state(ctx): |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
16 p = config.config() |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
17 def read(f, sections=None, remap=None): |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
18 if f in ctx: |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
19 try: |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
20 p.parse(f, ctx[f].data(), sections, remap) |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
21 except IOError, err: |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
22 if err.errno != errno.ENOENT: |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
23 raise |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
24 read('.hgsub') |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
25 |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
26 rev = {} |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
27 if '.hgsubstate' in ctx: |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
28 try: |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
29 for l in ctx['.hgsubstate'].data().splitlines(): |
9752
a22cdd5e56b7
subrepo: more robust split for .hgsubstate parsing
Matt Mackall <mpm@selenic.com>
parents:
9508
diff
changeset
|
30 revision, path = l.split(" ", 1) |
8812
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
31 rev[path] = revision |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
32 except IOError, err: |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
33 if err.errno != errno.ENOENT: |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
34 raise |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
35 |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
36 state = {} |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
37 for path, src in p[''].items(): |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
38 state[path] = (src, rev.get(path, '')) |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
39 |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
40 return state |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
41 |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
42 def writestate(repo, state): |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
43 repo.wwrite('.hgsubstate', |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
44 ''.join(['%s %s\n' % (state[s][1], s) |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
45 for s in sorted(state)]), '') |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
46 |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
47 def submerge(repo, wctx, mctx, actx): |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
48 if mctx == actx: # backwards? |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
49 actx = wctx.p1() |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
50 s1 = wctx.substate |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
51 s2 = mctx.substate |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
52 sa = actx.substate |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
53 sm = {} |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
54 |
9779
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
55 def debug(s, msg, r=""): |
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
56 if r: |
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
57 r = "%s:%s" % r |
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
58 repo.ui.debug(_(" subrepo %s: %s %s\n") % (s, msg, r)) |
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
59 |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
60 for s, l in s1.items(): |
9780
1ee085511b89
subrepo: notice dirty subrepo states when merging
Matt Mackall <mpm@selenic.com>
parents:
9779
diff
changeset
|
61 if wctx.sub(s).dirty(): |
1ee085511b89
subrepo: notice dirty subrepo states when merging
Matt Mackall <mpm@selenic.com>
parents:
9779
diff
changeset
|
62 l = (l[0], l[1] + "+") |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
63 a = sa.get(s, nullstate) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
64 if s in s2: |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
65 r = s2[s] |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
66 if l == r or r == a: # no change or local is newer |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
67 sm[s] = l |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
68 continue |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
69 elif l == a: # other side changed |
9779
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
70 debug(s, _("other changed, get"), r) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
71 wctx.sub(s).get(r) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
72 sm[s] = r |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
73 elif l[0] != r[0]: # sources differ |
9048
86b4a9b0ddda
ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents:
8997
diff
changeset
|
74 if repo.ui.promptchoice( |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
75 _(' subrepository sources for %s differ\n' |
8908
105343f9f744
Fix warning: Seen unexpected token "%"
Dongsheng Song <dongsheng.song@gmail.com>
parents:
8815
diff
changeset
|
76 'use (l)ocal source (%s) or (r)emote source (%s)?') |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
77 % (s, l[0], r[0]), |
9048
86b4a9b0ddda
ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents:
8997
diff
changeset
|
78 (_('&Local'), _('&Remote')), 0): |
9779
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
79 debug(s, _("prompt changed, get"), r) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
80 wctx.sub(s).get(r) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
81 sm[s] = r |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
82 elif l[1] == a[1]: # local side is unchanged |
9779
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
83 debug(s, _("other side changed, get"), r) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
84 wctx.sub(s).get(r) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
85 sm[s] = r |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
86 else: |
9779
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
87 debug(s, _("both sides changed, merge with"), r) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
88 wctx.sub(s).merge(r) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
89 sm[s] = l |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
90 elif l == a: # remote removed, local unchanged |
9779
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
91 debug(s, _("remote removed, remove")) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
92 wctx.sub(s).remove() |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
93 else: |
9048
86b4a9b0ddda
ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents:
8997
diff
changeset
|
94 if repo.ui.promptchoice( |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
95 _(' local changed subrepository %s which remote removed\n' |
8908
105343f9f744
Fix warning: Seen unexpected token "%"
Dongsheng Song <dongsheng.song@gmail.com>
parents:
8815
diff
changeset
|
96 'use (c)hanged version or (d)elete?') % s, |
9049
38b5d5e0efab
filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents:
9048
diff
changeset
|
97 (_('&Changed'), _('&Delete')), 0): |
9779
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
98 debug(s, _("prompt remove")) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
99 wctx.sub(s).remove() |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
100 |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
101 for s, r in s2.items(): |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
102 if s in s1: |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
103 continue |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
104 elif s not in sa: |
9779
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
105 debug(s, _("remote added, get"), r) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
106 wctx.sub(s).get(r) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
107 sm[s] = r |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
108 elif r != sa[s]: |
9048
86b4a9b0ddda
ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents:
8997
diff
changeset
|
109 if repo.ui.promptchoice( |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
110 _(' remote changed subrepository %s which local removed\n' |
8908
105343f9f744
Fix warning: Seen unexpected token "%"
Dongsheng Song <dongsheng.song@gmail.com>
parents:
8815
diff
changeset
|
111 'use (c)hanged version or (d)elete?') % s, |
9049
38b5d5e0efab
filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents:
9048
diff
changeset
|
112 (_('&Changed'), _('&Delete')), 0) == 0: |
9779
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
113 debug(s, _("prompt recreate"), r) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
114 wctx.sub(s).get(r) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
115 sm[s] = r |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
116 |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
117 # record merged .hgsubstate |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
118 writestate(repo, sm) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
119 |
8815
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
120 def _abssource(repo, push=False): |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
121 if hasattr(repo, '_subparent'): |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
122 source = repo._subsource |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
123 if source.startswith('/') or '://' in source: |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
124 return source |
9186
f783bb979fb3
subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents:
8997
diff
changeset
|
125 parent = _abssource(repo._subparent) |
f783bb979fb3
subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents:
8997
diff
changeset
|
126 if '://' in parent: |
f783bb979fb3
subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents:
8997
diff
changeset
|
127 if parent[-1] == '/': |
f783bb979fb3
subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents:
8997
diff
changeset
|
128 parent = parent[:-1] |
f783bb979fb3
subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents:
8997
diff
changeset
|
129 return parent + '/' + source |
f783bb979fb3
subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents:
8997
diff
changeset
|
130 return os.path.join(parent, repo._subsource) |
8815
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
131 if push and repo.ui.config('paths', 'default-push'): |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
132 return repo.ui.config('paths', 'default-push', repo.root) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
133 return repo.ui.config('paths', 'default', repo.root) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
134 |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
135 def subrepo(ctx, path): |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
136 # subrepo inherently violates our import layering rules |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
137 # because it wants to make repo objects from deep inside the stack |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
138 # so we manually delay the circular imports to not break |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
139 # scripts that don't use our demand-loading |
9092
9aebeea7ac00
subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents:
9049
diff
changeset
|
140 global hg |
9aebeea7ac00
subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents:
9049
diff
changeset
|
141 import hg as h |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
142 hg = h |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
143 |
8997
70f5d3be5917
subrepo: audit subrepo paths
Matt Mackall <mpm@selenic.com>
parents:
8908
diff
changeset
|
144 util.path_auditor(ctx._repo.root)(path) |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
145 state = ctx.substate.get(path, nullstate) |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
146 if state[0].startswith('['): # future expansion |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
147 raise error.Abort('unknown subrepo source %s' % state[0]) |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
148 return hgsubrepo(ctx, path, state) |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
149 |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
150 class hgsubrepo(object): |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
151 def __init__(self, ctx, path, state): |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
152 self._path = path |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
153 self._state = state |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
154 r = ctx._repo |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
155 root = r.wjoin(path) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
156 if os.path.exists(os.path.join(root, '.hg')): |
9092
9aebeea7ac00
subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents:
9049
diff
changeset
|
157 self._repo = hg.repository(r.ui, root) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
158 else: |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
159 util.makedirs(root) |
9092
9aebeea7ac00
subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents:
9049
diff
changeset
|
160 self._repo = hg.repository(r.ui, root, create=True) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
161 self._repo._subparent = r |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
162 self._repo._subsource = state[0] |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
163 |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
164 def dirty(self): |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
165 r = self._state[1] |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
166 if r == '': |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
167 return True |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
168 w = self._repo[None] |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
169 if w.p1() != self._repo[r]: # version checked out changed |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
170 return True |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
171 return w.dirty() # working directory changed |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
172 |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
173 def commit(self, text, user, date): |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
174 n = self._repo.commit(text, user, date) |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
175 if not n: |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
176 return self._repo['.'].hex() # different version checked out |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
177 return node.hex(n) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
178 |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
179 def remove(self): |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
180 # we can't fully delete the repository as it may contain |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
181 # local-only history |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
182 self._repo.ui.note(_('removing subrepo %s\n') % self._path) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
183 hg.clean(self._repo, node.nullid, False) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
184 |
9507
5987183d6e59
subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents:
9186
diff
changeset
|
185 def _get(self, state): |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
186 source, revision = state |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
187 try: |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
188 self._repo.lookup(revision) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
189 except error.RepoError: |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
190 self._repo._subsource = source |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
191 self._repo.ui.status(_('pulling subrepo %s\n') % self._path) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
192 srcurl = _abssource(self._repo) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
193 other = hg.repository(self._repo.ui, srcurl) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
194 self._repo.pull(other) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
195 |
9507
5987183d6e59
subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents:
9186
diff
changeset
|
196 def get(self, state): |
5987183d6e59
subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents:
9186
diff
changeset
|
197 self._get(state) |
5987183d6e59
subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents:
9186
diff
changeset
|
198 source, revision = state |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
199 hg.clean(self._repo, revision, False) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
200 |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
201 def merge(self, state): |
9507
5987183d6e59
subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents:
9186
diff
changeset
|
202 self._get(state) |
9781
eccc8aacd6f9
subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents:
9780
diff
changeset
|
203 cur = self._repo['.'] |
eccc8aacd6f9
subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents:
9780
diff
changeset
|
204 dst = self._repo[state[1]] |
eccc8aacd6f9
subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents:
9780
diff
changeset
|
205 if dst.ancestor(cur) == cur: |
eccc8aacd6f9
subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents:
9780
diff
changeset
|
206 hg.update(self._repo, state[1]) |
eccc8aacd6f9
subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents:
9780
diff
changeset
|
207 else: |
eccc8aacd6f9
subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents:
9780
diff
changeset
|
208 hg.merge(self._repo, state[1], remind=False) |
8815
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
209 |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
210 def push(self, force): |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
211 # push subrepos depth-first for coherent ordering |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
212 c = self._repo[''] |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
213 subs = c.substate # only repos that are committed |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
214 for s in sorted(subs): |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
215 c.sub(s).push(force) |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
216 |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
217 self._repo.ui.status(_('pushing subrepo %s\n') % self._path) |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
218 dsturl = _abssource(self._repo, True) |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
219 other = hg.repository(self._repo.ui, dsturl) |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
220 self._repo.push(other, force) |