41 def writestate(repo, state): |
42 def writestate(repo, state): |
42 repo.wwrite('.hgsubstate', |
43 repo.wwrite('.hgsubstate', |
43 ''.join(['%s %s\n' % (state[s][1], s) |
44 ''.join(['%s %s\n' % (state[s][1], s) |
44 for s in sorted(state)]), '') |
45 for s in sorted(state)]), '') |
45 |
46 |
|
47 def submerge(repo, wctx, mctx, actx): |
|
48 if mctx == actx: # backwards? |
|
49 actx = wctx.p1() |
|
50 s1 = wctx.substate |
|
51 s2 = mctx.substate |
|
52 sa = actx.substate |
|
53 sm = {} |
|
54 |
|
55 for s, l in s1.items(): |
|
56 a = sa.get(s, nullstate) |
|
57 if s in s2: |
|
58 r = s2[s] |
|
59 if l == r or r == a: # no change or local is newer |
|
60 sm[s] = l |
|
61 continue |
|
62 elif l == a: # other side changed |
|
63 wctx.sub(s).get(r) |
|
64 sm[s] = r |
|
65 elif l[0] != r[0]: # sources differ |
|
66 if repo.ui.prompt( |
|
67 _(' subrepository sources for %s differ\n' |
|
68 'use (l)ocal source (%s) or (r)emote source (%s)?' |
|
69 % (s, l[0], r[0]), |
|
70 (_('&Local'), _('&Remote')), _('l'))) == _('r'): |
|
71 wctx.sub(s).get(r) |
|
72 sm[s] = r |
|
73 elif l[1] == a[1]: # local side is unchanged |
|
74 wctx.sub(s).get(r) |
|
75 sm[s] = r |
|
76 else: |
|
77 wctx.sub(s).merge(r) |
|
78 sm[s] = l |
|
79 elif l == a: # remote removed, local unchanged |
|
80 wctx.sub(s).remove() |
|
81 else: |
|
82 if repo.ui.prompt( |
|
83 _(' local changed subrepository %s which remote removed\n' |
|
84 'use (c)hanged version or (d)elete?' % s, |
|
85 (_('&Changed'), _('&Delete')), _('c'))) == _('d'): |
|
86 wctx.sub(s).remove() |
|
87 |
|
88 for s, r in s2.items(): |
|
89 if s in s1: |
|
90 continue |
|
91 elif s not in sa: |
|
92 wctx.sub(s).get(r) |
|
93 sm[s] = r |
|
94 elif r != sa[s]: |
|
95 if repo.ui.prompt( |
|
96 _(' remote changed subrepository %s which local removed\n' |
|
97 'use (c)hanged version or (d)elete?' % s, |
|
98 (_('&Changed'), _('&Delete')), _('c'))) == _('c'): |
|
99 wctx.sub(s).get(r) |
|
100 sm[s] = r |
|
101 |
|
102 # record merged .hgsubstate |
|
103 writestate(repo, sm) |
|
104 |
|
105 def _abssource(repo): |
|
106 if hasattr(repo, '_subparent'): |
|
107 source = repo._subsource |
|
108 if source.startswith('/') or '://' in source: |
|
109 return source |
|
110 return os.path.join(_abssource(repo._subparent), repo._subsource) |
|
111 return repo.ui.config('paths', 'default', repo.root) |
|
112 |
46 def subrepo(ctx, path): |
113 def subrepo(ctx, path): |
47 # subrepo inherently violates our import layering rules |
114 # subrepo inherently violates our import layering rules |
48 # because it wants to make repo objects from deep inside the stack |
115 # because it wants to make repo objects from deep inside the stack |
49 # so we manually delay the circular imports to not break |
116 # so we manually delay the circular imports to not break |
50 # scripts that don't use our demand-loading |
117 # scripts that don't use our demand-loading |
51 global localrepo |
118 global localrepo, hg |
52 import localrepo as l |
119 import localrepo as l, hg as h |
53 localrepo = l |
120 localrepo = l |
|
121 hg = h |
54 |
122 |
55 state = ctx.substate.get(path, nullstate) |
123 state = ctx.substate.get(path, nullstate) |
56 if state[0].startswith('['): # future expansion |
124 if state[0].startswith('['): # future expansion |
57 raise error.Abort('unknown subrepo source %s' % state[0]) |
125 raise error.Abort('unknown subrepo source %s' % state[0]) |
58 return hgsubrepo(ctx, path, state) |
126 return hgsubrepo(ctx, path, state) |
78 def commit(self, text, user, date): |
152 def commit(self, text, user, date): |
79 n = self._repo.commit(text, user, date) |
153 n = self._repo.commit(text, user, date) |
80 if not n: |
154 if not n: |
81 return self._repo['.'].hex() # different version checked out |
155 return self._repo['.'].hex() # different version checked out |
82 return node.hex(n) |
156 return node.hex(n) |
|
157 |
|
158 def remove(self): |
|
159 # we can't fully delete the repository as it may contain |
|
160 # local-only history |
|
161 self._repo.ui.note(_('removing subrepo %s\n') % self._path) |
|
162 hg.clean(self._repo, node.nullid, False) |
|
163 |
|
164 def get(self, state): |
|
165 source, revision = state |
|
166 try: |
|
167 self._repo.lookup(revision) |
|
168 except error.RepoError: |
|
169 self._repo._subsource = source |
|
170 self._repo.ui.status(_('pulling subrepo %s\n') % self._path) |
|
171 srcurl = _abssource(self._repo) |
|
172 other = hg.repository(self._repo.ui, srcurl) |
|
173 self._repo.pull(other) |
|
174 |
|
175 hg.clean(self._repo, revision, False) |
|
176 |
|
177 def merge(self, state): |
|
178 hg.merge(self._repo, state[1], remind=False) |