Show More
@@ -1,6 +1,3 b'' | |||||
1 | Integration with the share extension needs improvement. Right now |
|
|||
2 | we've seen some odd bugs. |
|
|||
3 |
|
||||
4 |
|
|
1 | Address commentary in manifest.excludedmanifestrevlog.add - | |
5 | specifically we should improve the collaboration with core so that |
|
2 | specifically we should improve the collaboration with core so that | |
6 | add() never gets called on an excluded directory and we can improve |
|
3 | add() never gets called on an excluded directory and we can improve |
@@ -339,6 +339,8 b' def _widen(ui, repo, remote, commoninc, ' | |||||
339 | ('', 'clear', False, _('whether to replace the existing narrowspec')), |
|
339 | ('', 'clear', False, _('whether to replace the existing narrowspec')), | |
340 | ('', 'force-delete-local-changes', False, |
|
340 | ('', 'force-delete-local-changes', False, | |
341 | _('forces deletion of local changes when narrowing')), |
|
341 | _('forces deletion of local changes when narrowing')), | |
|
342 | ('', 'update-working-copy', False, | |||
|
343 | _('update working copy when the store has changed')), | |||
342 | ] + commands.remoteopts, |
|
344 | ] + commands.remoteopts, | |
343 | _('[OPTIONS]... [REMOTE]'), |
|
345 | _('[OPTIONS]... [REMOTE]'), | |
344 | inferrepo=True) |
|
346 | inferrepo=True) | |
@@ -398,8 +400,9 b' def trackedcmd(ui, repo, remotepath=None' | |||||
398 | addedexcludes = narrowspec.parsepatterns(opts['addexclude']) |
|
400 | addedexcludes = narrowspec.parsepatterns(opts['addexclude']) | |
399 | removedexcludes = narrowspec.parsepatterns(opts['removeexclude']) |
|
401 | removedexcludes = narrowspec.parsepatterns(opts['removeexclude']) | |
400 |
|
402 | |||
|
403 | update_working_copy = opts['update_working_copy'] | |||
401 | only_show = not (addedincludes or removedincludes or addedexcludes or |
|
404 | only_show = not (addedincludes or removedincludes or addedexcludes or | |
402 | removedexcludes or newrules) |
|
405 | removedexcludes or newrules or update_working_copy) | |
403 |
|
406 | |||
404 | oldincludes, oldexcludes = repo.narrowpats |
|
407 | oldincludes, oldexcludes = repo.narrowpats | |
405 |
|
408 | |||
@@ -428,6 +431,12 b' def trackedcmd(ui, repo, remotepath=None' | |||||
428 | fm.end() |
|
431 | fm.end() | |
429 | return 0 |
|
432 | return 0 | |
430 |
|
433 | |||
|
434 | if update_working_copy: | |||
|
435 | with repo.wlock(), repo.lock(), repo.transaction('narrow-wc') as tr: | |||
|
436 | narrowspec.updateworkingcopy(repo, tr) | |||
|
437 | narrowspec.copytoworkingcopy(repo, tr) | |||
|
438 | return 0 | |||
|
439 | ||||
431 | if not widening and not narrowing: |
|
440 | if not widening and not narrowing: | |
432 | ui.status(_("nothing to widen or narrow\n")) |
|
441 | ui.status(_("nothing to widen or narrow\n")) | |
433 | return 0 |
|
442 | return 0 |
@@ -38,6 +38,7 b' from . import (' | |||||
38 | narrowspec, |
|
38 | narrowspec, | |
39 | node, |
|
39 | node, | |
40 | phases, |
|
40 | phases, | |
|
41 | repository as repositorymod, | |||
41 | scmutil, |
|
42 | scmutil, | |
42 | sshpeer, |
|
43 | sshpeer, | |
43 | statichttprepo, |
|
44 | statichttprepo, | |
@@ -331,6 +332,9 b' def postshare(sourcerepo, destrepo, defa' | |||||
331 | template = ('[paths]\n' |
|
332 | template = ('[paths]\n' | |
332 | 'default = %s\n') |
|
333 | 'default = %s\n') | |
333 | destrepo.vfs.write('hgrc', util.tonativeeol(template % default)) |
|
334 | destrepo.vfs.write('hgrc', util.tonativeeol(template % default)) | |
|
335 | if repositorymod.NARROW_REQUIREMENT in sourcerepo.requirements: | |||
|
336 | with destrepo.wlock(): | |||
|
337 | narrowspec.copytoworkingcopy(destrepo, None) | |||
334 |
|
338 | |||
335 | def _postshareupdate(repo, update, checkout=None): |
|
339 | def _postshareupdate(repo, update, checkout=None): | |
336 | """Maybe perform a working directory update after a shared repo is created. |
|
340 | """Maybe perform a working directory update after a shared repo is created. | |
@@ -731,7 +735,7 b' def clone(ui, peeropts, source, dest=Non' | |||||
731 | local = destpeer.local() |
|
735 | local = destpeer.local() | |
732 | if local: |
|
736 | if local: | |
733 | if narrow: |
|
737 | if narrow: | |
734 | with local.lock(): |
|
738 | with local.wlock(), local.lock(): | |
735 | local.setnarrowpats(storeincludepats, storeexcludepats) |
|
739 | local.setnarrowpats(storeincludepats, storeexcludepats) | |
736 |
|
740 | |||
737 | u = util.url(abspath) |
|
741 | u = util.url(abspath) |
@@ -1227,6 +1227,7 b' class localrepository(object):' | |||||
1227 | def _narrowmatch(self): |
|
1227 | def _narrowmatch(self): | |
1228 | if repository.NARROW_REQUIREMENT not in self.requirements: |
|
1228 | if repository.NARROW_REQUIREMENT not in self.requirements: | |
1229 | return matchmod.always(self.root, '') |
|
1229 | return matchmod.always(self.root, '') | |
|
1230 | narrowspec.checkworkingcopynarrowspec(self) | |||
1230 | include, exclude = self.narrowpats |
|
1231 | include, exclude = self.narrowpats | |
1231 | return narrowspec.match(self.root, include=include, exclude=exclude) |
|
1232 | return narrowspec.match(self.root, include=include, exclude=exclude) | |
1232 |
|
1233 | |||
@@ -1251,7 +1252,14 b' class localrepository(object):' | |||||
1251 |
|
1252 | |||
1252 | def setnarrowpats(self, newincludes, newexcludes): |
|
1253 | def setnarrowpats(self, newincludes, newexcludes): | |
1253 | narrowspec.save(self, newincludes, newexcludes) |
|
1254 | narrowspec.save(self, newincludes, newexcludes) | |
|
1255 | narrowspec.copytoworkingcopy(self, self.currenttransaction()) | |||
1254 | self.invalidate(clearfilecache=True) |
|
1256 | self.invalidate(clearfilecache=True) | |
|
1257 | # So the next access won't be considered a conflict | |||
|
1258 | # TODO: It seems like there should be a way of doing this that | |||
|
1259 | # doesn't involve replacing these attributes. | |||
|
1260 | self.narrowpats = newincludes, newexcludes | |||
|
1261 | self._narrowmatch = narrowspec.match(self.root, include=newincludes, | |||
|
1262 | exclude=newexcludes) | |||
1255 |
|
1263 | |||
1256 | def __getitem__(self, changeid): |
|
1264 | def __getitem__(self, changeid): | |
1257 | if changeid is None: |
|
1265 | if changeid is None: |
@@ -13,12 +13,16 b' from .i18n import _' | |||||
13 | from . import ( |
|
13 | from . import ( | |
14 | error, |
|
14 | error, | |
15 | match as matchmod, |
|
15 | match as matchmod, | |
|
16 | merge, | |||
16 | repository, |
|
17 | repository, | |
17 | sparse, |
|
18 | sparse, | |
18 | util, |
|
19 | util, | |
19 | ) |
|
20 | ) | |
20 |
|
21 | |||
|
22 | # The file in .hg/store/ that indicates which paths exit in the store | |||
21 | FILENAME = 'narrowspec' |
|
23 | FILENAME = 'narrowspec' | |
|
24 | # The file in .hg/ that indicates which paths exit in the dirstate | |||
|
25 | DIRSTATE_FILENAME = 'narrowspec.dirstate' | |||
22 |
|
26 | |||
23 | # Pattern prefixes that are allowed in narrow patterns. This list MUST |
|
27 | # Pattern prefixes that are allowed in narrow patterns. This list MUST | |
24 | # only contain patterns that are fast and safe to evaluate. Keep in mind |
|
28 | # only contain patterns that are fast and safe to evaluate. Keep in mind | |
@@ -157,6 +161,18 b' def save(repo, includepats, excludepats)' | |||||
157 | spec = format(includepats, excludepats) |
|
161 | spec = format(includepats, excludepats) | |
158 | repo.svfs.write(FILENAME, spec) |
|
162 | repo.svfs.write(FILENAME, spec) | |
159 |
|
163 | |||
|
164 | def copytoworkingcopy(repo, tr): | |||
|
165 | if tr: | |||
|
166 | def write(file): | |||
|
167 | spec = repo.svfs.read(FILENAME) | |||
|
168 | file.write(spec) | |||
|
169 | file.close() | |||
|
170 | tr.addfilegenerator('narrowspec', (DIRSTATE_FILENAME,), write, | |||
|
171 | location='plain') | |||
|
172 | else: | |||
|
173 | spec = repo.svfs.read(FILENAME) | |||
|
174 | repo.vfs.write(DIRSTATE_FILENAME, spec) | |||
|
175 | ||||
160 | def savebackup(repo, backupname): |
|
176 | def savebackup(repo, backupname): | |
161 | if repository.NARROW_REQUIREMENT not in repo.requirements: |
|
177 | if repository.NARROW_REQUIREMENT not in repo.requirements: | |
162 | return |
|
178 | return | |
@@ -226,3 +242,57 b' def restrictpatterns(req_includes, req_e' | |||||
226 | else: |
|
242 | else: | |
227 | res_includes = set(req_includes) |
|
243 | res_includes = set(req_includes) | |
228 | return res_includes, res_excludes, invalid_includes |
|
244 | return res_includes, res_excludes, invalid_includes | |
|
245 | ||||
|
246 | # These two are extracted for extensions (specifically for Google's CitC file | |||
|
247 | # system) | |||
|
248 | def _deletecleanfiles(repo, files): | |||
|
249 | for f in files: | |||
|
250 | repo.wvfs.unlinkpath(f) | |||
|
251 | ||||
|
252 | def _writeaddedfiles(repo, pctx, files): | |||
|
253 | actions = merge.emptyactions() | |||
|
254 | addgaction = actions['g'].append | |||
|
255 | mf = repo['.'].manifest() | |||
|
256 | for f in files: | |||
|
257 | if not repo.wvfs.exists(f): | |||
|
258 | addgaction((f, (mf.flags(f), False), "narrowspec updated")) | |||
|
259 | merge.applyupdates(repo, actions, wctx=repo[None], | |||
|
260 | mctx=repo['.'], overwrite=False) | |||
|
261 | ||||
|
262 | def checkworkingcopynarrowspec(repo): | |||
|
263 | storespec = repo.svfs.tryread(FILENAME) | |||
|
264 | wcspec = repo.vfs.tryread(DIRSTATE_FILENAME) | |||
|
265 | if wcspec != storespec: | |||
|
266 | raise error.Abort(_("working copy's narrowspec is stale"), | |||
|
267 | hint=_("run 'hg tracked --update-working-copy'")) | |||
|
268 | ||||
|
269 | def updateworkingcopy(repo, tr): | |||
|
270 | oldspec = repo.vfs.tryread(DIRSTATE_FILENAME) | |||
|
271 | newspec = repo.svfs.tryread(FILENAME) | |||
|
272 | ||||
|
273 | oldincludes, oldexcludes = parseconfig(repo.ui, oldspec) | |||
|
274 | newincludes, newexcludes = parseconfig(repo.ui, newspec) | |||
|
275 | oldmatch = match(repo.root, include=oldincludes, exclude=oldexcludes) | |||
|
276 | newmatch = match(repo.root, include=newincludes, exclude=newexcludes) | |||
|
277 | addedmatch = matchmod.differencematcher(newmatch, oldmatch) | |||
|
278 | removedmatch = matchmod.differencematcher(oldmatch, newmatch) | |||
|
279 | ||||
|
280 | ds = repo.dirstate | |||
|
281 | lookup, status = ds.status(removedmatch, subrepos=[], ignored=False, | |||
|
282 | clean=True, unknown=False) | |||
|
283 | _deletecleanfiles(repo, status.clean) | |||
|
284 | trackeddirty = lookup + status.modified + status.added | |||
|
285 | for f in sorted(trackeddirty): | |||
|
286 | repo.ui.status(_('not deleting possibly dirty file %s\n') % f) | |||
|
287 | for f in status.clean + trackeddirty: | |||
|
288 | ds.drop(f) | |||
|
289 | ||||
|
290 | repo.narrowpats = newincludes, newexcludes | |||
|
291 | repo._narrowmatch = newmatch | |||
|
292 | pctx = repo['.'] | |||
|
293 | newfiles = [f for f in pctx.manifest().walk(addedmatch) if f not in ds] | |||
|
294 | for f in newfiles: | |||
|
295 | ds.normallookup(f) | |||
|
296 | _writeaddedfiles(repo, pctx, newfiles) | |||
|
297 | ||||
|
298 | ds.write(tr) |
@@ -6,6 +6,7 b'' | |||||
6 | > path:foo |
|
6 | > path:foo | |
7 | > [exclude] |
|
7 | > [exclude] | |
8 | > EOF |
|
8 | > EOF | |
|
9 | $ cp .hg/store/narrowspec .hg/narrowspec.dirstate | |||
9 | $ echo treemanifest >> .hg/requires |
|
10 | $ echo treemanifest >> .hg/requires | |
10 | $ echo narrowhg-experimental >> .hg/requires |
|
11 | $ echo narrowhg-experimental >> .hg/requires | |
11 | $ mkdir -p foo/bar |
|
12 | $ mkdir -p foo/bar |
@@ -75,13 +75,20 b' Narrow the share and check that the main' | |||||
75 | deleting meta/d5/00manifest.i (tree !) |
|
75 | deleting meta/d5/00manifest.i (tree !) | |
76 | $ hg -R main tracked |
|
76 | $ hg -R main tracked | |
77 | I path:d7 |
|
77 | I path:d7 | |
|
78 | $ hg -R main files | |||
|
79 | abort: working copy's narrowspec is stale | |||
|
80 | (run 'hg tracked --update-working-copy') | |||
|
81 | [255] | |||
|
82 | $ hg -R main tracked --update-working-copy | |||
|
83 | not deleting possibly dirty file d3/f | |||
|
84 | not deleting possibly dirty file d3/g | |||
|
85 | not deleting possibly dirty file d5/f | |||
78 |
|
|
86 | # d1/f, d3/f, d3/g and d5/f should no longer be reported | |
79 | $ hg -R main files |
|
87 | $ hg -R main files | |
80 | main/d7/f |
|
88 | main/d7/f | |
81 |
|
|
89 | # d1/f should no longer be there, d3/f should be since it was dirty, d3/g should be there since | |
82 |
|
|
90 | # it was added, and d5/f should be since we couldn't be sure it was clean | |
83 | $ find main/d* -type f | sort |
|
91 | $ find main/d* -type f | sort | |
84 | main/d1/f |
|
|||
85 | main/d3/f |
|
92 | main/d3/f | |
86 | main/d3/g |
|
93 | main/d3/g | |
87 | main/d5/f |
|
94 | main/d5/f | |
@@ -102,16 +109,20 b' Widen the share and check that the main ' | |||||
102 | I path:d1 |
|
109 | I path:d1 | |
103 | I path:d3 |
|
110 | I path:d3 | |
104 | I path:d7 |
|
111 | I path:d7 | |
|
112 | $ hg -R main files | |||
|
113 | abort: working copy's narrowspec is stale | |||
|
114 | (run 'hg tracked --update-working-copy') | |||
|
115 | [255] | |||
|
116 | $ hg -R main tracked --update-working-copy | |||
105 | # d1/f, d3/f should be back |
|
117 | # d1/f, d3/f should be back | |
106 | $ hg -R main files |
|
118 | $ hg -R main files | |
107 | main/d1/f |
|
119 | main/d1/f | |
108 | main/d3/f |
|
120 | main/d3/f | |
109 | main/d3/g |
|
|||
110 | main/d7/f |
|
121 | main/d7/f | |
111 | # d3/f should be modified (not clobbered by the widening), and d3/g should be untracked |
|
122 | # d3/f should be modified (not clobbered by the widening), and d3/g should be untracked | |
112 | $ hg -R main st --all |
|
123 | $ hg -R main st --all | |
113 | M d3/f |
|
124 | M d3/f | |
114 |
|
|
125 | ? d3/g | |
115 | C d1/f |
|
126 | C d1/f | |
116 | C d7/f |
|
127 | C d7/f | |
117 |
|
128 | |||
@@ -130,3 +141,30 b' We should also be able to unshare withou' | |||||
130 | checking files |
|
141 | checking files | |
131 | checked 11 changesets with 3 changes to 3 files |
|
142 | checked 11 changesets with 3 changes to 3 files | |
132 | $ cd .. |
|
143 | $ cd .. | |
|
144 | ||||
|
145 | Dirstate should be left alone when upgrading from version of hg that didn't support narrow+share | |||
|
146 | ||||
|
147 | $ hg share main share-upgrade | |||
|
148 | updating working directory | |||
|
149 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
150 | $ cd share-upgrade | |||
|
151 | $ echo x >> d1/f | |||
|
152 | $ echo y >> d3/g | |||
|
153 | $ hg add d3/g | |||
|
154 | $ hg rm d7/f | |||
|
155 | $ hg st | |||
|
156 | M d1/f | |||
|
157 | A d3/g | |||
|
158 | R d7/f | |||
|
159 | Make it look like a repo from before narrow+share was supported | |||
|
160 | $ rm .hg/narrowspec.dirstate | |||
|
161 | $ hg st | |||
|
162 | abort: working copy's narrowspec is stale | |||
|
163 | (run 'hg tracked --update-working-copy') | |||
|
164 | [255] | |||
|
165 | $ hg tracked --update-working-copy | |||
|
166 | $ hg st | |||
|
167 | M d1/f | |||
|
168 | A d3/g | |||
|
169 | R d7/f | |||
|
170 | $ cd .. |
@@ -107,6 +107,8 b' Testing the --import-rules flag of `hg t' | |||||
107 | --clear whether to replace the existing narrowspec |
|
107 | --clear whether to replace the existing narrowspec | |
108 | --force-delete-local-changes forces deletion of local changes when |
|
108 | --force-delete-local-changes forces deletion of local changes when | |
109 | narrowing |
|
109 | narrowing | |
|
110 | --update-working-copy update working copy when the store has | |||
|
111 | changed | |||
110 | -e --ssh CMD specify ssh command to use |
|
112 | -e --ssh CMD specify ssh command to use | |
111 | --remotecmd CMD specify hg command to run on the remote side |
|
113 | --remotecmd CMD specify hg command to run on the remote side | |
112 | --insecure do not verify server certificate (ignoring |
|
114 | --insecure do not verify server certificate (ignoring |
General Comments 0
You need to be logged in to leave comments.
Login now