##// END OF EJS Templates
narrow: detect if narrowspec was changed in a different share...
Martin von Zweigbergk -
r41072:ce0bc295 default
parent child Browse files
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 Address commentary in manifest.excludedmanifestrevlog.add -
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 # d1/f, d3/f, d3/g and d5/f should no longer be reported
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 # d1/f should no longer be there, d3/f should be since it was dirty, d3/g should be there since
89 # d1/f should no longer be there, d3/f should be since it was dirty, d3/g should be there since
82 # it was added, and d5/f should be since we couldn't be sure it was clean
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 A d3/g
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