Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/subrepo.py @ 11109:a2bc2f2d77a9
subrepo: normalize path part of URLs so that pulling subrepos from webdir works
For a "all projects at root" repo layout eg:
/main
/sub
Where subrepos are used such that a clone of main has this layout:
./main/
./main/.hgsub
./main/sub/
And the .hgsub content is:
sub = ../sub
This allows a pull from a hgweb where main and sub are exposed
at the root (or same directory level)
The current code doesn't normalize the path component of a pull
url. this results in trying to pull from
http://server.com/hg/main/../sub
Current hgweb implementation doesn't reduce the path component
so this results in a 404 error though everything is setup logically.
This patch adresses this 404 error on the puller side
normalizing the URLs used for pulling sub repos. For this
example, the URL would be reduced to http://server.com/hg/sub
Fix + test
author | Edouard Gomez <ed.gomez@free.fr> |
---|---|
date | Sat, 01 May 2010 23:05:19 +0200 |
parents | 37d1b20168d1 |
children | d2da9e6dd13e |
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 # |
10324
55d134ef8ab7
subrepo: correct copyright
David Soria Parra <dsp@php.net>
parents:
10299
diff
changeset
|
3 # Copyright 2009-2010 Matt Mackall <mpm@selenic.com> |
8812
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 |
10263 | 6 # GNU General Public License version 2 or any later version. |
8812
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
7 |
11109
a2bc2f2d77a9
subrepo: normalize path part of URLs so that pulling subrepos from webdir works
Edouard Gomez <ed.gomez@free.fr>
parents:
11078
diff
changeset
|
8 import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath |
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 |
10177
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
13 nullstate = ('', '', 'empty') |
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: |
10174
65b6dc44cdbf
subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents:
10069
diff
changeset
|
19 p.parse(f, ctx[f].data(), sections, remap, read) |
65b6dc44cdbf
subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents:
10069
diff
changeset
|
20 else: |
65b6dc44cdbf
subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents:
10069
diff
changeset
|
21 raise util.Abort(_("subrepo spec file %s not found") % f) |
65b6dc44cdbf
subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents:
10069
diff
changeset
|
22 |
65b6dc44cdbf
subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents:
10069
diff
changeset
|
23 if '.hgsub' in ctx: |
65b6dc44cdbf
subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents:
10069
diff
changeset
|
24 read('.hgsub') |
8812
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(): |
10177
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
38 kind = 'hg' |
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
39 if src.startswith('['): |
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
40 if ']' not in src: |
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
41 raise util.Abort(_('missing ] in subrepo source')) |
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
42 kind, src = src.split(']', 1) |
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
43 kind = kind[1:] |
10457
4f38d03d4975
subrepo: make sure that the source path is stripped
David Soria Parra <dsp@php.net>
parents:
10378
diff
changeset
|
44 state[path] = (src.strip(), rev.get(path, ''), kind) |
8812
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
45 |
859f841937d0
subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
46 return state |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
47 |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
48 def writestate(repo, state): |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
49 repo.wwrite('.hgsubstate', |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
50 ''.join(['%s %s\n' % (state[s][1], s) |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
51 for s in sorted(state)]), '') |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
52 |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
53 def submerge(repo, wctx, mctx, actx): |
10175
fc32b2fc468e
subrepo: load from a context where the subrepo exists
Augie Fackler <durin42@gmail.com>
parents:
10174
diff
changeset
|
54 # working context, merging context, ancestor context |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
55 if mctx == actx: # backwards? |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
56 actx = wctx.p1() |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
57 s1 = wctx.substate |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
58 s2 = mctx.substate |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
59 sa = actx.substate |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
60 sm = {} |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
61 |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
62 repo.ui.debug("subrepo merge %s %s %s\n" % (wctx, mctx, actx)) |
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
63 |
9779
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
64 def debug(s, msg, r=""): |
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
65 if r: |
10177
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
66 r = "%s:%s:%s" % r |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
67 repo.ui.debug(" subrepo %s: %s %s\n" % (s, msg, r)) |
9779
58a6f3f4d553
subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents:
9752
diff
changeset
|
68 |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
69 for s, l in s1.items(): |
9783
ee00ef6f9be7
submerge: properly deal with overwrites
Matt Mackall <mpm@selenic.com>
parents:
9782
diff
changeset
|
70 if wctx != actx and wctx.sub(s).dirty(): |
9780
1ee085511b89
subrepo: notice dirty subrepo states when merging
Matt Mackall <mpm@selenic.com>
parents:
9779
diff
changeset
|
71 l = (l[0], l[1] + "+") |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
72 a = sa.get(s, nullstate) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
73 if s in s2: |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
74 r = s2[s] |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
75 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
|
76 sm[s] = l |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
77 continue |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
78 elif l == a: # other side changed |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
79 debug(s, "other 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[0] != r[0]: # sources differ |
9048
86b4a9b0ddda
ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents:
8997
diff
changeset
|
83 if repo.ui.promptchoice( |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
84 _(' subrepository sources for %s differ\n' |
8908
105343f9f744
Fix warning: Seen unexpected token "%"
Dongsheng Song <dongsheng.song@gmail.com>
parents:
8815
diff
changeset
|
85 '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
|
86 % (s, l[0], r[0]), |
9048
86b4a9b0ddda
ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents:
8997
diff
changeset
|
87 (_('&Local'), _('&Remote')), 0): |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
88 debug(s, "prompt changed, get", r) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
89 wctx.sub(s).get(r) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
90 sm[s] = r |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
91 elif l[1] == a[1]: # local side is unchanged |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
92 debug(s, "other side changed, get", r) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
93 wctx.sub(s).get(r) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
94 sm[s] = r |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
95 else: |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
96 debug(s, "both sides changed, merge with", r) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
97 wctx.sub(s).merge(r) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
98 sm[s] = l |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
99 elif l == a: # remote removed, local unchanged |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
100 debug(s, "remote removed, remove") |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
101 wctx.sub(s).remove() |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
102 else: |
9048
86b4a9b0ddda
ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents:
8997
diff
changeset
|
103 if repo.ui.promptchoice( |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
104 _(' 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
|
105 'use (c)hanged version or (d)elete?') % s, |
9049
38b5d5e0efab
filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents:
9048
diff
changeset
|
106 (_('&Changed'), _('&Delete')), 0): |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
107 debug(s, "prompt remove") |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
108 wctx.sub(s).remove() |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
109 |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
110 for s, r in s2.items(): |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
111 if s in s1: |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
112 continue |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
113 elif s not in sa: |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
114 debug(s, "remote added, get", r) |
10175
fc32b2fc468e
subrepo: load from a context where the subrepo exists
Augie Fackler <durin42@gmail.com>
parents:
10174
diff
changeset
|
115 mctx.sub(s).get(r) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
116 sm[s] = r |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
117 elif r != sa[s]: |
9048
86b4a9b0ddda
ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents:
8997
diff
changeset
|
118 if repo.ui.promptchoice( |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
119 _(' 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
|
120 'use (c)hanged version or (d)elete?') % s, |
9049
38b5d5e0efab
filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents:
9048
diff
changeset
|
121 (_('&Changed'), _('&Delete')), 0) == 0: |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
122 debug(s, "prompt recreate", r) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
123 wctx.sub(s).get(r) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
124 sm[s] = r |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
125 |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
126 # record merged .hgsubstate |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
127 writestate(repo, sm) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
128 |
8815
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
129 def _abssource(repo, push=False): |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
130 if hasattr(repo, '_subparent'): |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
131 source = repo._subsource |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
132 if source.startswith('/') or '://' in source: |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
133 return source |
10665
664bb0ce95ed
subrepo: forward the push to argument into _abssource
Edouard Gomez <ed.gomez@free.fr>
parents:
10510
diff
changeset
|
134 parent = _abssource(repo._subparent, push) |
9186
f783bb979fb3
subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents:
8997
diff
changeset
|
135 if '://' in parent: |
f783bb979fb3
subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents:
8997
diff
changeset
|
136 if parent[-1] == '/': |
f783bb979fb3
subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents:
8997
diff
changeset
|
137 parent = parent[:-1] |
11109
a2bc2f2d77a9
subrepo: normalize path part of URLs so that pulling subrepos from webdir works
Edouard Gomez <ed.gomez@free.fr>
parents:
11078
diff
changeset
|
138 r = urlparse.urlparse(parent + '/' + source) |
a2bc2f2d77a9
subrepo: normalize path part of URLs so that pulling subrepos from webdir works
Edouard Gomez <ed.gomez@free.fr>
parents:
11078
diff
changeset
|
139 r = urlparse.urlunparse((r[0], r[1], |
a2bc2f2d77a9
subrepo: normalize path part of URLs so that pulling subrepos from webdir works
Edouard Gomez <ed.gomez@free.fr>
parents:
11078
diff
changeset
|
140 posixpath.normpath(r.path), |
a2bc2f2d77a9
subrepo: normalize path part of URLs so that pulling subrepos from webdir works
Edouard Gomez <ed.gomez@free.fr>
parents:
11078
diff
changeset
|
141 r[3], r[4], r[5])) |
a2bc2f2d77a9
subrepo: normalize path part of URLs so that pulling subrepos from webdir works
Edouard Gomez <ed.gomez@free.fr>
parents:
11078
diff
changeset
|
142 return r |
a2bc2f2d77a9
subrepo: normalize path part of URLs so that pulling subrepos from webdir works
Edouard Gomez <ed.gomez@free.fr>
parents:
11078
diff
changeset
|
143 return posixpath.normpath(os.path.join(parent, repo._subsource)) |
8815
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
144 if push and repo.ui.config('paths', 'default-push'): |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
145 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
|
146 return repo.ui.config('paths', 'default', repo.root) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
147 |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
148 def subrepo(ctx, path): |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
149 # subrepo inherently violates our import layering rules |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
150 # 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
|
151 # so we manually delay the circular imports to not break |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
152 # 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
|
153 global hg |
9aebeea7ac00
subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents:
9049
diff
changeset
|
154 import hg as h |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
155 hg = h |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
156 |
8997
70f5d3be5917
subrepo: audit subrepo paths
Matt Mackall <mpm@selenic.com>
parents:
8908
diff
changeset
|
157 util.path_auditor(ctx._repo.root)(path) |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
158 state = ctx.substate.get(path, nullstate) |
10177
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
159 if state[2] not in types: |
10299
e768941f14c1
subrepo: fix errors reported by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10273
diff
changeset
|
160 raise util.Abort(_('unknown subrepo type %s') % state[2]) |
10177
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
161 return types[state[2]](ctx, path, state[:2]) |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
162 |
10027
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
163 # subrepo classes need to implement the following methods: |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
164 # __init__(self, ctx, path, state) |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
165 # dirty(self): returns true if the dirstate of the subrepo |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
166 # does not match current stored state |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
167 # commit(self, text, user, date): commit the current changes |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
168 # to the subrepo with the given log message. Use given |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
169 # user and date if possible. Return the new state of the subrepo. |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
170 # remove(self): remove the subrepo (should verify the dirstate |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
171 # is not dirty first) |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
172 # get(self, state): run whatever commands are needed to put the |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
173 # subrepo into this state |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
174 # merge(self, state): merge currently-saved state with the new state. |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
175 # push(self, force): perform whatever action is analagous to 'hg push' |
30d51a0df46c
subrepo: document necessary methods for a subrepo class
Augie Fackler <durin42@gmail.com>
parents:
9783
diff
changeset
|
176 # This may be a no-op on some systems. |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
177 |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
178 class hgsubrepo(object): |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
179 def __init__(self, ctx, path, state): |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
180 self._path = path |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
181 self._state = state |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
182 r = ctx._repo |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
183 root = r.wjoin(path) |
10666
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
184 create = False |
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
185 if not os.path.exists(os.path.join(root, '.hg')): |
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
186 create = True |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
187 util.makedirs(root) |
10666
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
188 self._repo = hg.repository(r.ui, root, create=create) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
189 self._repo._subparent = r |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
190 self._repo._subsource = state[0] |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
191 |
10666
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
192 if create: |
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
193 fp = self._repo.opener("hgrc", "w", text=True) |
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
194 fp.write('[paths]\n') |
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
195 |
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
196 def addpathconfig(key, value): |
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
197 fp.write('%s = %s\n' % (key, value)) |
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
198 self._repo.ui.setconfig('paths', key, value) |
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
199 |
10697
c90d923fff64
subrepo: fix hgrc paths section during subrepo pulling
Edouard Gomez <ed.gomez@free.fr>
parents:
10666
diff
changeset
|
200 defpath = _abssource(self._repo) |
c90d923fff64
subrepo: fix hgrc paths section during subrepo pulling
Edouard Gomez <ed.gomez@free.fr>
parents:
10666
diff
changeset
|
201 defpushpath = _abssource(self._repo, True) |
10666
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
202 addpathconfig('default', defpath) |
10697
c90d923fff64
subrepo: fix hgrc paths section during subrepo pulling
Edouard Gomez <ed.gomez@free.fr>
parents:
10666
diff
changeset
|
203 if defpath != defpushpath: |
c90d923fff64
subrepo: fix hgrc paths section during subrepo pulling
Edouard Gomez <ed.gomez@free.fr>
parents:
10666
diff
changeset
|
204 addpathconfig('default-push', defpushpath) |
10666
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
205 fp.close() |
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
206 |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
207 def dirty(self): |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
208 r = self._state[1] |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
209 if r == '': |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
210 return True |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
211 w = self._repo[None] |
10666
4c50a90b90fc
subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10665
diff
changeset
|
212 if w.p1() != self._repo[r]: # version checked out change |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
213 return True |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
214 return w.dirty() # working directory changed |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
215 |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
216 def commit(self, text, user, date): |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
217 self._repo.ui.debug("committing subrepo %s\n" % self._path) |
8813
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
218 n = self._repo.commit(text, user, date) |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
219 if not n: |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
220 return self._repo['.'].hex() # different version checked out |
db3c1ab0e632
commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents:
8812
diff
changeset
|
221 return node.hex(n) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
222 |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
223 def remove(self): |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
224 # 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
|
225 # local-only history |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
226 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
|
227 hg.clean(self._repo, node.nullid, False) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
228 |
9507
5987183d6e59
subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents:
9186
diff
changeset
|
229 def _get(self, state): |
10177
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
230 source, revision, kind = state |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
231 try: |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
232 self._repo.lookup(revision) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
233 except error.RepoError: |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
234 self._repo._subsource = source |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
235 srcurl = _abssource(self._repo) |
10671
001ffc2b3d22
subrepo: wrap long line
Martin Geisler <mg@lazybytes.net>
parents:
10670
diff
changeset
|
236 self._repo.ui.status(_('pulling subrepo %s from %s\n') |
001ffc2b3d22
subrepo: wrap long line
Martin Geisler <mg@lazybytes.net>
parents:
10670
diff
changeset
|
237 % (self._path, srcurl)) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
238 other = hg.repository(self._repo.ui, srcurl) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
239 self._repo.pull(other) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
240 |
9507
5987183d6e59
subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents:
9186
diff
changeset
|
241 def get(self, state): |
5987183d6e59
subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents:
9186
diff
changeset
|
242 self._get(state) |
10177
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
243 source, revision, kind = state |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
244 self._repo.ui.debug("getting subrepo %s\n" % self._path) |
8814
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
245 hg.clean(self._repo, revision, False) |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
246 |
ab668c92a036
subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents:
8813
diff
changeset
|
247 def merge(self, state): |
9507
5987183d6e59
subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents:
9186
diff
changeset
|
248 self._get(state) |
9781
eccc8aacd6f9
subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents:
9780
diff
changeset
|
249 cur = self._repo['.'] |
eccc8aacd6f9
subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents:
9780
diff
changeset
|
250 dst = self._repo[state[1]] |
10251
a19d2993385d
subrepo: fix merging of already merged subrepos (issue1986)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10068
diff
changeset
|
251 anc = dst.ancestor(cur) |
a19d2993385d
subrepo: fix merging of already merged subrepos (issue1986)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10068
diff
changeset
|
252 if anc == cur: |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
253 self._repo.ui.debug("updating subrepo %s\n" % self._path) |
9781
eccc8aacd6f9
subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents:
9780
diff
changeset
|
254 hg.update(self._repo, state[1]) |
10251
a19d2993385d
subrepo: fix merging of already merged subrepos (issue1986)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10068
diff
changeset
|
255 elif anc == dst: |
a19d2993385d
subrepo: fix merging of already merged subrepos (issue1986)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10068
diff
changeset
|
256 self._repo.ui.debug("skipping subrepo %s\n" % self._path) |
9781
eccc8aacd6f9
subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents:
9780
diff
changeset
|
257 else: |
9782
c1c40511c276
subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents:
9781
diff
changeset
|
258 self._repo.ui.debug("merging subrepo %s\n" % self._path) |
9781
eccc8aacd6f9
subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents:
9780
diff
changeset
|
259 hg.merge(self._repo, state[1], remind=False) |
8815
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
260 |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
261 def push(self, force): |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
262 # push subrepos depth-first for coherent ordering |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
263 c = self._repo[''] |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
264 subs = c.substate # only repos that are committed |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
265 for s in sorted(subs): |
11067
49e14ec67144
subrepo: propagate and catch push failures
Matt Mackall <mpm@selenic.com>
parents:
10954
diff
changeset
|
266 if not c.sub(s).push(force): |
49e14ec67144
subrepo: propagate and catch push failures
Matt Mackall <mpm@selenic.com>
parents:
10954
diff
changeset
|
267 return False |
8815
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
268 |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
269 self._repo.ui.status(_('pushing subrepo %s\n') % self._path) |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
270 dsturl = _abssource(self._repo, True) |
e87b0fc4750b
subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents:
8814
diff
changeset
|
271 other = hg.repository(self._repo.ui, dsturl) |
11067
49e14ec67144
subrepo: propagate and catch push failures
Matt Mackall <mpm@selenic.com>
parents:
10954
diff
changeset
|
272 return self._repo.push(other, force) |
10177
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
273 |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
274 class svnsubrepo(object): |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
275 def __init__(self, ctx, path, state): |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
276 self._path = path |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
277 self._state = state |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
278 self._ctx = ctx |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
279 self._ui = ctx._repo.ui |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
280 |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
281 def _svncommand(self, commands): |
10954
33119d0252c1
subrepo: fix repo root path handling in svn subrepo
Brett Cannon <brett@python.org>
parents:
10697
diff
changeset
|
282 path = os.path.join(self._ctx._repo.origroot, self._path) |
33119d0252c1
subrepo: fix repo root path handling in svn subrepo
Brett Cannon <brett@python.org>
parents:
10697
diff
changeset
|
283 cmd = ['svn'] + commands + [path] |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
284 cmd = [util.shellquote(arg) for arg in cmd] |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
285 cmd = util.quotecommand(' '.join(cmd)) |
10199
c2e2a5e6c36b
subrepo: force en_US.UTF-8 locale when calling svn
Patrick Mezard <pmezard@gmail.com>
parents:
10197
diff
changeset
|
286 env = dict(os.environ) |
10271
9b38bec5dc29
subrepo: make svn use C locale for portability
Patrick Mezard <pmezard@gmail.com>
parents:
10264
diff
changeset
|
287 # Avoid localized output, preserve current locale for everything else. |
9b38bec5dc29
subrepo: make svn use C locale for portability
Patrick Mezard <pmezard@gmail.com>
parents:
10264
diff
changeset
|
288 env['LC_MESSAGES'] = 'C' |
10199
c2e2a5e6c36b
subrepo: force en_US.UTF-8 locale when calling svn
Patrick Mezard <pmezard@gmail.com>
parents:
10197
diff
changeset
|
289 write, read, err = util.popen3(cmd, env=env, newlines=True) |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
290 retdata = read.read() |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
291 err = err.read().strip() |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
292 if err: |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
293 raise util.Abort(err) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
294 return retdata |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
295 |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
296 def _wcrev(self): |
10272
886858b834da
subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents:
10271
diff
changeset
|
297 output = self._svncommand(['info', '--xml']) |
886858b834da
subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents:
10271
diff
changeset
|
298 doc = xml.dom.minidom.parseString(output) |
886858b834da
subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents:
10271
diff
changeset
|
299 entries = doc.getElementsByTagName('entry') |
886858b834da
subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents:
10271
diff
changeset
|
300 if not entries: |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
301 return 0 |
10272
886858b834da
subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents:
10271
diff
changeset
|
302 return int(entries[0].getAttribute('revision') or 0) |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
303 |
10273
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
304 def _wcchanged(self): |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
305 """Return (changes, extchanges) where changes is True |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
306 if the working directory was changed, and extchanges is |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
307 True if any of these changes concern an external entry. |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
308 """ |
10272
886858b834da
subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents:
10271
diff
changeset
|
309 output = self._svncommand(['status', '--xml']) |
10273
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
310 externals, changes = [], [] |
10272
886858b834da
subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents:
10271
diff
changeset
|
311 doc = xml.dom.minidom.parseString(output) |
10273
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
312 for e in doc.getElementsByTagName('entry'): |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
313 s = e.getElementsByTagName('wc-status') |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
314 if not s: |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
315 continue |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
316 item = s[0].getAttribute('item') |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
317 props = s[0].getAttribute('props') |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
318 path = e.getAttribute('path') |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
319 if item == 'external': |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
320 externals.append(path) |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
321 if (item not in ('', 'normal', 'unversioned', 'external') |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
322 or props not in ('', 'none')): |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
323 changes.append(path) |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
324 for path in changes: |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
325 for ext in externals: |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
326 if path == ext or path.startswith(ext + os.sep): |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
327 return True, True |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
328 return bool(changes), False |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
329 |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
330 def dirty(self): |
10273
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
331 if self._wcrev() == self._state[1] and not self._wcchanged()[0]: |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
332 return False |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
333 return True |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
334 |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
335 def commit(self, text, user, date): |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
336 # user and date are out of our hands since svn is centralized |
10273
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
337 changed, extchanged = self._wcchanged() |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
338 if not changed: |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
339 return self._wcrev() |
10273
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
340 if extchanged: |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
341 # Do not try to commit externals |
e898bc7810ad
subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents:
10272
diff
changeset
|
342 raise util.Abort(_('cannot commit svn externals')) |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
343 commitinfo = self._svncommand(['commit', '-m', text]) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
344 self._ui.status(commitinfo) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
345 newrev = re.search('Committed revision ([\d]+).', commitinfo) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
346 if not newrev: |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
347 raise util.Abort(commitinfo.splitlines()[-1]) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
348 newrev = newrev.groups()[0] |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
349 self._ui.status(self._svncommand(['update', '-r', newrev])) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
350 return newrev |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
351 |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
352 def remove(self): |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
353 if self.dirty(): |
10299
e768941f14c1
subrepo: fix errors reported by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10273
diff
changeset
|
354 self._ui.warn(_('not removing repo %s because ' |
e768941f14c1
subrepo: fix errors reported by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10273
diff
changeset
|
355 'it has changes.\n' % self._path)) |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
356 return |
10510
f77f3383c666
i18n: mark more strings for translation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10457
diff
changeset
|
357 self._ui.note(_('removing subrepo %s\n') % self._path) |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
358 shutil.rmtree(self._ctx.repo.join(self._path)) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
359 |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
360 def get(self, state): |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
361 status = self._svncommand(['checkout', state[0], '--revision', state[1]]) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
362 if not re.search('Checked out revision [\d]+.', status): |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
363 raise util.Abort(status.splitlines()[-1]) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
364 self._ui.status(status) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
365 |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
366 def merge(self, state): |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
367 old = int(self._state[1]) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
368 new = int(state[1]) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
369 if new > old: |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
370 self.get(state) |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
371 |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
372 def push(self, force): |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
373 # nothing for svn |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
374 pass |
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
375 |
10177
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
376 types = { |
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
377 'hg': hgsubrepo, |
10178
cd477be6f2fc
subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents:
10177
diff
changeset
|
378 'svn': svnsubrepo, |
10177
5ca0d220ae21
subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents:
10175
diff
changeset
|
379 } |