##// END OF EJS Templates
largefiles: fix 'deleted' files sometimes persistently appearing with R status...
Mads Kiilerich -
r30191:328545c7 stable
parent child Browse files
Show More
@@ -1,385 +1,389 b''
1 # Copyright 2009-2010 Gregory P. Ward
1 # Copyright 2009-2010 Gregory P. Ward
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
3 # Copyright 2010-2011 Fog Creek Software
3 # Copyright 2010-2011 Fog Creek Software
4 # Copyright 2010-2011 Unity Technologies
4 # Copyright 2010-2011 Unity Technologies
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 '''setup for largefiles repositories: reposetup'''
9 '''setup for largefiles repositories: reposetup'''
10 from __future__ import absolute_import
10 from __future__ import absolute_import
11
11
12 import copy
12 import copy
13
13
14 from mercurial.i18n import _
14 from mercurial.i18n import _
15
15
16 from mercurial import (
16 from mercurial import (
17 error,
17 error,
18 localrepo,
18 localrepo,
19 match as matchmod,
19 match as matchmod,
20 scmutil,
20 scmutil,
21 )
21 )
22
22
23 from . import (
23 from . import (
24 lfcommands,
24 lfcommands,
25 lfutil,
25 lfutil,
26 )
26 )
27
27
28 def reposetup(ui, repo):
28 def reposetup(ui, repo):
29 # wire repositories should be given new wireproto functions
29 # wire repositories should be given new wireproto functions
30 # by "proto.wirereposetup()" via "hg.wirepeersetupfuncs"
30 # by "proto.wirereposetup()" via "hg.wirepeersetupfuncs"
31 if not repo.local():
31 if not repo.local():
32 return
32 return
33
33
34 class lfilesrepo(repo.__class__):
34 class lfilesrepo(repo.__class__):
35 # the mark to examine whether "repo" object enables largefiles or not
35 # the mark to examine whether "repo" object enables largefiles or not
36 _largefilesenabled = True
36 _largefilesenabled = True
37
37
38 lfstatus = False
38 lfstatus = False
39 def status_nolfiles(self, *args, **kwargs):
39 def status_nolfiles(self, *args, **kwargs):
40 return super(lfilesrepo, self).status(*args, **kwargs)
40 return super(lfilesrepo, self).status(*args, **kwargs)
41
41
42 # When lfstatus is set, return a context that gives the names
42 # When lfstatus is set, return a context that gives the names
43 # of largefiles instead of their corresponding standins and
43 # of largefiles instead of their corresponding standins and
44 # identifies the largefiles as always binary, regardless of
44 # identifies the largefiles as always binary, regardless of
45 # their actual contents.
45 # their actual contents.
46 def __getitem__(self, changeid):
46 def __getitem__(self, changeid):
47 ctx = super(lfilesrepo, self).__getitem__(changeid)
47 ctx = super(lfilesrepo, self).__getitem__(changeid)
48 if self.lfstatus:
48 if self.lfstatus:
49 class lfilesctx(ctx.__class__):
49 class lfilesctx(ctx.__class__):
50 def files(self):
50 def files(self):
51 filenames = super(lfilesctx, self).files()
51 filenames = super(lfilesctx, self).files()
52 return [lfutil.splitstandin(f) or f for f in filenames]
52 return [lfutil.splitstandin(f) or f for f in filenames]
53 def manifest(self):
53 def manifest(self):
54 man1 = super(lfilesctx, self).manifest()
54 man1 = super(lfilesctx, self).manifest()
55 class lfilesmanifest(man1.__class__):
55 class lfilesmanifest(man1.__class__):
56 def __contains__(self, filename):
56 def __contains__(self, filename):
57 orig = super(lfilesmanifest, self).__contains__
57 orig = super(lfilesmanifest, self).__contains__
58 return (orig(filename) or
58 return (orig(filename) or
59 orig(lfutil.standin(filename)))
59 orig(lfutil.standin(filename)))
60 man1.__class__ = lfilesmanifest
60 man1.__class__ = lfilesmanifest
61 return man1
61 return man1
62 def filectx(self, path, fileid=None, filelog=None):
62 def filectx(self, path, fileid=None, filelog=None):
63 orig = super(lfilesctx, self).filectx
63 orig = super(lfilesctx, self).filectx
64 try:
64 try:
65 if filelog is not None:
65 if filelog is not None:
66 result = orig(path, fileid, filelog)
66 result = orig(path, fileid, filelog)
67 else:
67 else:
68 result = orig(path, fileid)
68 result = orig(path, fileid)
69 except error.LookupError:
69 except error.LookupError:
70 # Adding a null character will cause Mercurial to
70 # Adding a null character will cause Mercurial to
71 # identify this as a binary file.
71 # identify this as a binary file.
72 if filelog is not None:
72 if filelog is not None:
73 result = orig(lfutil.standin(path), fileid,
73 result = orig(lfutil.standin(path), fileid,
74 filelog)
74 filelog)
75 else:
75 else:
76 result = orig(lfutil.standin(path), fileid)
76 result = orig(lfutil.standin(path), fileid)
77 olddata = result.data
77 olddata = result.data
78 result.data = lambda: olddata() + '\0'
78 result.data = lambda: olddata() + '\0'
79 return result
79 return result
80 ctx.__class__ = lfilesctx
80 ctx.__class__ = lfilesctx
81 return ctx
81 return ctx
82
82
83 # Figure out the status of big files and insert them into the
83 # Figure out the status of big files and insert them into the
84 # appropriate list in the result. Also removes standin files
84 # appropriate list in the result. Also removes standin files
85 # from the listing. Revert to the original status if
85 # from the listing. Revert to the original status if
86 # self.lfstatus is False.
86 # self.lfstatus is False.
87 # XXX large file status is buggy when used on repo proxy.
87 # XXX large file status is buggy when used on repo proxy.
88 # XXX this needs to be investigated.
88 # XXX this needs to be investigated.
89 @localrepo.unfilteredmethod
89 @localrepo.unfilteredmethod
90 def status(self, node1='.', node2=None, match=None, ignored=False,
90 def status(self, node1='.', node2=None, match=None, ignored=False,
91 clean=False, unknown=False, listsubrepos=False):
91 clean=False, unknown=False, listsubrepos=False):
92 listignored, listclean, listunknown = ignored, clean, unknown
92 listignored, listclean, listunknown = ignored, clean, unknown
93 orig = super(lfilesrepo, self).status
93 orig = super(lfilesrepo, self).status
94 if not self.lfstatus:
94 if not self.lfstatus:
95 return orig(node1, node2, match, listignored, listclean,
95 return orig(node1, node2, match, listignored, listclean,
96 listunknown, listsubrepos)
96 listunknown, listsubrepos)
97
97
98 # some calls in this function rely on the old version of status
98 # some calls in this function rely on the old version of status
99 self.lfstatus = False
99 self.lfstatus = False
100 ctx1 = self[node1]
100 ctx1 = self[node1]
101 ctx2 = self[node2]
101 ctx2 = self[node2]
102 working = ctx2.rev() is None
102 working = ctx2.rev() is None
103 parentworking = working and ctx1 == self['.']
103 parentworking = working and ctx1 == self['.']
104
104
105 if match is None:
105 if match is None:
106 match = matchmod.always(self.root, self.getcwd())
106 match = matchmod.always(self.root, self.getcwd())
107
107
108 wlock = None
108 wlock = None
109 try:
109 try:
110 try:
110 try:
111 # updating the dirstate is optional
111 # updating the dirstate is optional
112 # so we don't wait on the lock
112 # so we don't wait on the lock
113 wlock = self.wlock(False)
113 wlock = self.wlock(False)
114 except error.LockError:
114 except error.LockError:
115 pass
115 pass
116
116
117 # First check if paths or patterns were specified on the
117 # First check if paths or patterns were specified on the
118 # command line. If there were, and they don't match any
118 # command line. If there were, and they don't match any
119 # largefiles, we should just bail here and let super
119 # largefiles, we should just bail here and let super
120 # handle it -- thus gaining a big performance boost.
120 # handle it -- thus gaining a big performance boost.
121 lfdirstate = lfutil.openlfdirstate(ui, self)
121 lfdirstate = lfutil.openlfdirstate(ui, self)
122 if not match.always():
122 if not match.always():
123 for f in lfdirstate:
123 for f in lfdirstate:
124 if match(f):
124 if match(f):
125 break
125 break
126 else:
126 else:
127 return orig(node1, node2, match, listignored, listclean,
127 return orig(node1, node2, match, listignored, listclean,
128 listunknown, listsubrepos)
128 listunknown, listsubrepos)
129
129
130 # Create a copy of match that matches standins instead
130 # Create a copy of match that matches standins instead
131 # of largefiles.
131 # of largefiles.
132 def tostandins(files):
132 def tostandins(files):
133 if not working:
133 if not working:
134 return files
134 return files
135 newfiles = []
135 newfiles = []
136 dirstate = self.dirstate
136 dirstate = self.dirstate
137 for f in files:
137 for f in files:
138 sf = lfutil.standin(f)
138 sf = lfutil.standin(f)
139 if sf in dirstate:
139 if sf in dirstate:
140 newfiles.append(sf)
140 newfiles.append(sf)
141 elif sf in dirstate.dirs():
141 elif sf in dirstate.dirs():
142 # Directory entries could be regular or
142 # Directory entries could be regular or
143 # standin, check both
143 # standin, check both
144 newfiles.extend((f, sf))
144 newfiles.extend((f, sf))
145 else:
145 else:
146 newfiles.append(f)
146 newfiles.append(f)
147 return newfiles
147 return newfiles
148
148
149 m = copy.copy(match)
149 m = copy.copy(match)
150 m._files = tostandins(m._files)
150 m._files = tostandins(m._files)
151
151
152 result = orig(node1, node2, m, ignored, clean, unknown,
152 result = orig(node1, node2, m, ignored, clean, unknown,
153 listsubrepos)
153 listsubrepos)
154 if working:
154 if working:
155
155
156 def sfindirstate(f):
156 def sfindirstate(f):
157 sf = lfutil.standin(f)
157 sf = lfutil.standin(f)
158 dirstate = self.dirstate
158 dirstate = self.dirstate
159 return sf in dirstate or sf in dirstate.dirs()
159 return sf in dirstate or sf in dirstate.dirs()
160
160
161 match._files = [f for f in match._files
161 match._files = [f for f in match._files
162 if sfindirstate(f)]
162 if sfindirstate(f)]
163 # Don't waste time getting the ignored and unknown
163 # Don't waste time getting the ignored and unknown
164 # files from lfdirstate
164 # files from lfdirstate
165 unsure, s = lfdirstate.status(match, [], False, listclean,
165 unsure, s = lfdirstate.status(match, [], False, listclean,
166 False)
166 False)
167 (modified, added, removed, clean) = (s.modified, s.added,
167 (modified, added, removed, deleted, clean) = (
168 s.removed, s.clean)
168 s.modified, s.added, s.removed, s.deleted, s.clean)
169 if parentworking:
169 if parentworking:
170 for lfile in unsure:
170 for lfile in unsure:
171 standin = lfutil.standin(lfile)
171 standin = lfutil.standin(lfile)
172 if standin not in ctx1:
172 if standin not in ctx1:
173 # from second parent
173 # from second parent
174 modified.append(lfile)
174 modified.append(lfile)
175 elif ctx1[standin].data().strip() \
175 elif ctx1[standin].data().strip() \
176 != lfutil.hashfile(self.wjoin(lfile)):
176 != lfutil.hashfile(self.wjoin(lfile)):
177 modified.append(lfile)
177 modified.append(lfile)
178 else:
178 else:
179 if listclean:
179 if listclean:
180 clean.append(lfile)
180 clean.append(lfile)
181 lfdirstate.normal(lfile)
181 lfdirstate.normal(lfile)
182 else:
182 else:
183 tocheck = unsure + modified + added + clean
183 tocheck = unsure + modified + added + clean
184 modified, added, clean = [], [], []
184 modified, added, clean = [], [], []
185 checkexec = self.dirstate._checkexec
185 checkexec = self.dirstate._checkexec
186
186
187 for lfile in tocheck:
187 for lfile in tocheck:
188 standin = lfutil.standin(lfile)
188 standin = lfutil.standin(lfile)
189 if standin in ctx1:
189 if standin in ctx1:
190 abslfile = self.wjoin(lfile)
190 abslfile = self.wjoin(lfile)
191 if ((ctx1[standin].data().strip() !=
191 if ((ctx1[standin].data().strip() !=
192 lfutil.hashfile(abslfile)) or
192 lfutil.hashfile(abslfile)) or
193 (checkexec and
193 (checkexec and
194 ('x' in ctx1.flags(standin)) !=
194 ('x' in ctx1.flags(standin)) !=
195 bool(lfutil.getexecutable(abslfile)))):
195 bool(lfutil.getexecutable(abslfile)))):
196 modified.append(lfile)
196 modified.append(lfile)
197 elif listclean:
197 elif listclean:
198 clean.append(lfile)
198 clean.append(lfile)
199 else:
199 else:
200 added.append(lfile)
200 added.append(lfile)
201
201
202 # at this point, 'removed' contains largefiles
202 # at this point, 'removed' contains largefiles
203 # marked as 'R' in the working context.
203 # marked as 'R' in the working context.
204 # then, largefiles not managed also in the target
204 # then, largefiles not managed also in the target
205 # context should be excluded from 'removed'.
205 # context should be excluded from 'removed'.
206 removed = [lfile for lfile in removed
206 removed = [lfile for lfile in removed
207 if lfutil.standin(lfile) in ctx1]
207 if lfutil.standin(lfile) in ctx1]
208
208
209 # Standins no longer found in lfdirstate has been
209 # Standins no longer found in lfdirstate have been deleted
210 # removed
211 for standin in ctx1.walk(lfutil.getstandinmatcher(self)):
210 for standin in ctx1.walk(lfutil.getstandinmatcher(self)):
212 lfile = lfutil.splitstandin(standin)
211 lfile = lfutil.splitstandin(standin)
213 if not match(lfile):
212 if not match(lfile):
214 continue
213 continue
215 if lfile not in lfdirstate:
214 if lfile not in lfdirstate:
216 removed.append(lfile)
215 deleted.append(lfile)
216 # Sync "largefile has been removed" back to the
217 # standin. Removing a file as a side effect of
218 # running status is gross, but the alternatives (if
219 # any) are worse.
220 self.wvfs.unlink(standin)
217
221
218 # Filter result lists
222 # Filter result lists
219 result = list(result)
223 result = list(result)
220
224
221 # Largefiles are not really removed when they're
225 # Largefiles are not really removed when they're
222 # still in the normal dirstate. Likewise, normal
226 # still in the normal dirstate. Likewise, normal
223 # files are not really removed if they are still in
227 # files are not really removed if they are still in
224 # lfdirstate. This happens in merges where files
228 # lfdirstate. This happens in merges where files
225 # change type.
229 # change type.
226 removed = [f for f in removed
230 removed = [f for f in removed
227 if f not in self.dirstate]
231 if f not in self.dirstate]
228 result[2] = [f for f in result[2]
232 result[2] = [f for f in result[2]
229 if f not in lfdirstate]
233 if f not in lfdirstate]
230
234
231 lfiles = set(lfdirstate._map)
235 lfiles = set(lfdirstate._map)
232 # Unknown files
236 # Unknown files
233 result[4] = set(result[4]).difference(lfiles)
237 result[4] = set(result[4]).difference(lfiles)
234 # Ignored files
238 # Ignored files
235 result[5] = set(result[5]).difference(lfiles)
239 result[5] = set(result[5]).difference(lfiles)
236 # combine normal files and largefiles
240 # combine normal files and largefiles
237 normals = [[fn for fn in filelist
241 normals = [[fn for fn in filelist
238 if not lfutil.isstandin(fn)]
242 if not lfutil.isstandin(fn)]
239 for filelist in result]
243 for filelist in result]
240 lfstatus = (modified, added, removed, s.deleted, [], [],
244 lfstatus = (modified, added, removed, deleted, [], [],
241 clean)
245 clean)
242 result = [sorted(list1 + list2)
246 result = [sorted(list1 + list2)
243 for (list1, list2) in zip(normals, lfstatus)]
247 for (list1, list2) in zip(normals, lfstatus)]
244 else: # not against working directory
248 else: # not against working directory
245 result = [[lfutil.splitstandin(f) or f for f in items]
249 result = [[lfutil.splitstandin(f) or f for f in items]
246 for items in result]
250 for items in result]
247
251
248 if wlock:
252 if wlock:
249 lfdirstate.write()
253 lfdirstate.write()
250
254
251 finally:
255 finally:
252 if wlock:
256 if wlock:
253 wlock.release()
257 wlock.release()
254
258
255 self.lfstatus = True
259 self.lfstatus = True
256 return scmutil.status(*result)
260 return scmutil.status(*result)
257
261
258 def commitctx(self, ctx, *args, **kwargs):
262 def commitctx(self, ctx, *args, **kwargs):
259 node = super(lfilesrepo, self).commitctx(ctx, *args, **kwargs)
263 node = super(lfilesrepo, self).commitctx(ctx, *args, **kwargs)
260 class lfilesctx(ctx.__class__):
264 class lfilesctx(ctx.__class__):
261 def markcommitted(self, node):
265 def markcommitted(self, node):
262 orig = super(lfilesctx, self).markcommitted
266 orig = super(lfilesctx, self).markcommitted
263 return lfutil.markcommitted(orig, self, node)
267 return lfutil.markcommitted(orig, self, node)
264 ctx.__class__ = lfilesctx
268 ctx.__class__ = lfilesctx
265 return node
269 return node
266
270
267 # Before commit, largefile standins have not had their
271 # Before commit, largefile standins have not had their
268 # contents updated to reflect the hash of their largefile.
272 # contents updated to reflect the hash of their largefile.
269 # Do that here.
273 # Do that here.
270 def commit(self, text="", user=None, date=None, match=None,
274 def commit(self, text="", user=None, date=None, match=None,
271 force=False, editor=False, extra={}):
275 force=False, editor=False, extra={}):
272 orig = super(lfilesrepo, self).commit
276 orig = super(lfilesrepo, self).commit
273
277
274 with self.wlock():
278 with self.wlock():
275 lfcommithook = self._lfcommithooks[-1]
279 lfcommithook = self._lfcommithooks[-1]
276 match = lfcommithook(self, match)
280 match = lfcommithook(self, match)
277 result = orig(text=text, user=user, date=date, match=match,
281 result = orig(text=text, user=user, date=date, match=match,
278 force=force, editor=editor, extra=extra)
282 force=force, editor=editor, extra=extra)
279 return result
283 return result
280
284
281 def push(self, remote, force=False, revs=None, newbranch=False):
285 def push(self, remote, force=False, revs=None, newbranch=False):
282 if remote.local():
286 if remote.local():
283 missing = set(self.requirements) - remote.local().supported
287 missing = set(self.requirements) - remote.local().supported
284 if missing:
288 if missing:
285 msg = _("required features are not"
289 msg = _("required features are not"
286 " supported in the destination:"
290 " supported in the destination:"
287 " %s") % (', '.join(sorted(missing)))
291 " %s") % (', '.join(sorted(missing)))
288 raise error.Abort(msg)
292 raise error.Abort(msg)
289 return super(lfilesrepo, self).push(remote, force=force, revs=revs,
293 return super(lfilesrepo, self).push(remote, force=force, revs=revs,
290 newbranch=newbranch)
294 newbranch=newbranch)
291
295
292 # TODO: _subdirlfs should be moved into "lfutil.py", because
296 # TODO: _subdirlfs should be moved into "lfutil.py", because
293 # it is referred only from "lfutil.updatestandinsbymatch"
297 # it is referred only from "lfutil.updatestandinsbymatch"
294 def _subdirlfs(self, files, lfiles):
298 def _subdirlfs(self, files, lfiles):
295 '''
299 '''
296 Adjust matched file list
300 Adjust matched file list
297 If we pass a directory to commit whose only committable files
301 If we pass a directory to commit whose only committable files
298 are largefiles, the core commit code aborts before finding
302 are largefiles, the core commit code aborts before finding
299 the largefiles.
303 the largefiles.
300 So we do the following:
304 So we do the following:
301 For directories that only have largefiles as matches,
305 For directories that only have largefiles as matches,
302 we explicitly add the largefiles to the match list and remove
306 we explicitly add the largefiles to the match list and remove
303 the directory.
307 the directory.
304 In other cases, we leave the match list unmodified.
308 In other cases, we leave the match list unmodified.
305 '''
309 '''
306 actualfiles = []
310 actualfiles = []
307 dirs = []
311 dirs = []
308 regulars = []
312 regulars = []
309
313
310 for f in files:
314 for f in files:
311 if lfutil.isstandin(f + '/'):
315 if lfutil.isstandin(f + '/'):
312 raise error.Abort(
316 raise error.Abort(
313 _('file "%s" is a largefile standin') % f,
317 _('file "%s" is a largefile standin') % f,
314 hint=('commit the largefile itself instead'))
318 hint=('commit the largefile itself instead'))
315 # Scan directories
319 # Scan directories
316 if self.wvfs.isdir(f):
320 if self.wvfs.isdir(f):
317 dirs.append(f)
321 dirs.append(f)
318 else:
322 else:
319 regulars.append(f)
323 regulars.append(f)
320
324
321 for f in dirs:
325 for f in dirs:
322 matcheddir = False
326 matcheddir = False
323 d = self.dirstate.normalize(f) + '/'
327 d = self.dirstate.normalize(f) + '/'
324 # Check for matched normal files
328 # Check for matched normal files
325 for mf in regulars:
329 for mf in regulars:
326 if self.dirstate.normalize(mf).startswith(d):
330 if self.dirstate.normalize(mf).startswith(d):
327 actualfiles.append(f)
331 actualfiles.append(f)
328 matcheddir = True
332 matcheddir = True
329 break
333 break
330 if not matcheddir:
334 if not matcheddir:
331 # If no normal match, manually append
335 # If no normal match, manually append
332 # any matching largefiles
336 # any matching largefiles
333 for lf in lfiles:
337 for lf in lfiles:
334 if self.dirstate.normalize(lf).startswith(d):
338 if self.dirstate.normalize(lf).startswith(d):
335 actualfiles.append(lf)
339 actualfiles.append(lf)
336 if not matcheddir:
340 if not matcheddir:
337 # There may still be normal files in the dir, so
341 # There may still be normal files in the dir, so
338 # add a directory to the list, which
342 # add a directory to the list, which
339 # forces status/dirstate to walk all files and
343 # forces status/dirstate to walk all files and
340 # call the match function on the matcher, even
344 # call the match function on the matcher, even
341 # on case sensitive filesystems.
345 # on case sensitive filesystems.
342 actualfiles.append('.')
346 actualfiles.append('.')
343 matcheddir = True
347 matcheddir = True
344 # Nothing in dir, so readd it
348 # Nothing in dir, so readd it
345 # and let commit reject it
349 # and let commit reject it
346 if not matcheddir:
350 if not matcheddir:
347 actualfiles.append(f)
351 actualfiles.append(f)
348
352
349 # Always add normal files
353 # Always add normal files
350 actualfiles += regulars
354 actualfiles += regulars
351 return actualfiles
355 return actualfiles
352
356
353 repo.__class__ = lfilesrepo
357 repo.__class__ = lfilesrepo
354
358
355 # stack of hooks being executed before committing.
359 # stack of hooks being executed before committing.
356 # only last element ("_lfcommithooks[-1]") is used for each committing.
360 # only last element ("_lfcommithooks[-1]") is used for each committing.
357 repo._lfcommithooks = [lfutil.updatestandinsbymatch]
361 repo._lfcommithooks = [lfutil.updatestandinsbymatch]
358
362
359 # Stack of status writer functions taking "*msg, **opts" arguments
363 # Stack of status writer functions taking "*msg, **opts" arguments
360 # like "ui.status()". Only last element ("_lfstatuswriters[-1]")
364 # like "ui.status()". Only last element ("_lfstatuswriters[-1]")
361 # is used to write status out.
365 # is used to write status out.
362 repo._lfstatuswriters = [ui.status]
366 repo._lfstatuswriters = [ui.status]
363
367
364 def prepushoutgoinghook(pushop):
368 def prepushoutgoinghook(pushop):
365 """Push largefiles for pushop before pushing revisions."""
369 """Push largefiles for pushop before pushing revisions."""
366 lfrevs = pushop.lfrevs
370 lfrevs = pushop.lfrevs
367 if lfrevs is None:
371 if lfrevs is None:
368 lfrevs = pushop.outgoing.missing
372 lfrevs = pushop.outgoing.missing
369 if lfrevs:
373 if lfrevs:
370 toupload = set()
374 toupload = set()
371 addfunc = lambda fn, lfhash: toupload.add(lfhash)
375 addfunc = lambda fn, lfhash: toupload.add(lfhash)
372 lfutil.getlfilestoupload(pushop.repo, lfrevs,
376 lfutil.getlfilestoupload(pushop.repo, lfrevs,
373 addfunc)
377 addfunc)
374 lfcommands.uploadlfiles(ui, pushop.repo, pushop.remote, toupload)
378 lfcommands.uploadlfiles(ui, pushop.repo, pushop.remote, toupload)
375 repo.prepushoutgoinghooks.add("largefiles", prepushoutgoinghook)
379 repo.prepushoutgoinghooks.add("largefiles", prepushoutgoinghook)
376
380
377 def checkrequireslfiles(ui, repo, **kwargs):
381 def checkrequireslfiles(ui, repo, **kwargs):
378 if 'largefiles' not in repo.requirements and any(
382 if 'largefiles' not in repo.requirements and any(
379 lfutil.shortname+'/' in f[0] for f in repo.store.datafiles()):
383 lfutil.shortname+'/' in f[0] for f in repo.store.datafiles()):
380 repo.requirements.add('largefiles')
384 repo.requirements.add('largefiles')
381 repo._writerequirements()
385 repo._writerequirements()
382
386
383 ui.setconfig('hooks', 'changegroup.lfiles', checkrequireslfiles,
387 ui.setconfig('hooks', 'changegroup.lfiles', checkrequireslfiles,
384 'largefiles')
388 'largefiles')
385 ui.setconfig('hooks', 'commit.lfiles', checkrequireslfiles, 'largefiles')
389 ui.setconfig('hooks', 'commit.lfiles', checkrequireslfiles, 'largefiles')
@@ -1,792 +1,784 b''
1 This file focuses mainly on updating largefiles in the working
1 This file focuses mainly on updating largefiles in the working
2 directory (and ".hg/largefiles/dirstate")
2 directory (and ".hg/largefiles/dirstate")
3
3
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [ui]
5 > [ui]
6 > merge = internal:fail
6 > merge = internal:fail
7 > [extensions]
7 > [extensions]
8 > largefiles =
8 > largefiles =
9 > [extdiff]
9 > [extdiff]
10 > # for portability:
10 > # for portability:
11 > pdiff = sh "$RUNTESTDIR/pdiff"
11 > pdiff = sh "$RUNTESTDIR/pdiff"
12 > EOF
12 > EOF
13
13
14 $ hg init repo
14 $ hg init repo
15 $ cd repo
15 $ cd repo
16
16
17 $ echo large1 > large1
17 $ echo large1 > large1
18 $ echo large2 > large2
18 $ echo large2 > large2
19 $ hg add --large large1 large2
19 $ hg add --large large1 large2
20 $ echo normal1 > normal1
20 $ echo normal1 > normal1
21 $ hg add normal1
21 $ hg add normal1
22 $ hg commit -m '#0'
22 $ hg commit -m '#0'
23 $ echo 'large1 in #1' > large1
23 $ echo 'large1 in #1' > large1
24 $ echo 'normal1 in #1' > normal1
24 $ echo 'normal1 in #1' > normal1
25 $ hg commit -m '#1'
25 $ hg commit -m '#1'
26 $ hg pdiff -r '.^' --config extensions.extdiff=
26 $ hg pdiff -r '.^' --config extensions.extdiff=
27 diff -Nru repo.0d9d9b8dc9a3/.hglf/large1 repo/.hglf/large1
27 diff -Nru repo.0d9d9b8dc9a3/.hglf/large1 repo/.hglf/large1
28 --- repo.0d9d9b8dc9a3/.hglf/large1 * (glob)
28 --- repo.0d9d9b8dc9a3/.hglf/large1 * (glob)
29 +++ repo/.hglf/large1 * (glob)
29 +++ repo/.hglf/large1 * (glob)
30 @@ -1* +1* @@ (glob)
30 @@ -1* +1* @@ (glob)
31 -4669e532d5b2c093a78eca010077e708a071bb64
31 -4669e532d5b2c093a78eca010077e708a071bb64
32 +58e24f733a964da346e2407a2bee99d9001184f5
32 +58e24f733a964da346e2407a2bee99d9001184f5
33 diff -Nru repo.0d9d9b8dc9a3/normal1 repo/normal1
33 diff -Nru repo.0d9d9b8dc9a3/normal1 repo/normal1
34 --- repo.0d9d9b8dc9a3/normal1 * (glob)
34 --- repo.0d9d9b8dc9a3/normal1 * (glob)
35 +++ repo/normal1 * (glob)
35 +++ repo/normal1 * (glob)
36 @@ -1* +1* @@ (glob)
36 @@ -1* +1* @@ (glob)
37 -normal1
37 -normal1
38 +normal1 in #1
38 +normal1 in #1
39 [1]
39 [1]
40 $ hg update -q -C 0
40 $ hg update -q -C 0
41 $ echo 'large2 in #2' > large2
41 $ echo 'large2 in #2' > large2
42 $ hg commit -m '#2'
42 $ hg commit -m '#2'
43 created new head
43 created new head
44
44
45 Test that update also updates the lfdirstate of 'unsure' largefiles after
45 Test that update also updates the lfdirstate of 'unsure' largefiles after
46 hashing them:
46 hashing them:
47
47
48 The previous operations will usually have left us with largefiles with a mtime
48 The previous operations will usually have left us with largefiles with a mtime
49 within the same second as the dirstate was written.
49 within the same second as the dirstate was written.
50 The lfdirstate entries will thus have been written with an invalidated/unset
50 The lfdirstate entries will thus have been written with an invalidated/unset
51 mtime to make sure further changes within the same second is detected.
51 mtime to make sure further changes within the same second is detected.
52 We will however occasionally be "lucky" and get a tick between writing
52 We will however occasionally be "lucky" and get a tick between writing
53 largefiles and writing dirstate so we get valid lfdirstate timestamps. The
53 largefiles and writing dirstate so we get valid lfdirstate timestamps. The
54 following verification is thus disabled but can be verified manually.
54 following verification is thus disabled but can be verified manually.
55
55
56 #if false
56 #if false
57 $ hg debugdirstate --large --nodate
57 $ hg debugdirstate --large --nodate
58 n 644 7 unset large1
58 n 644 7 unset large1
59 n 644 13 unset large2
59 n 644 13 unset large2
60 #endif
60 #endif
61
61
62 Wait to make sure we get a tick so the mtime of the largefiles become valid.
62 Wait to make sure we get a tick so the mtime of the largefiles become valid.
63
63
64 $ sleep 1
64 $ sleep 1
65
65
66 A linear merge will update standins before performing the actual merge. It will
66 A linear merge will update standins before performing the actual merge. It will
67 do a lfdirstate status walk and find 'unset'/'unsure' files, hash them, and
67 do a lfdirstate status walk and find 'unset'/'unsure' files, hash them, and
68 update the corresponding standins.
68 update the corresponding standins.
69 Verify that it actually marks the clean files as clean in lfdirstate so
69 Verify that it actually marks the clean files as clean in lfdirstate so
70 we don't have to hash them again next time we update.
70 we don't have to hash them again next time we update.
71
71
72 $ hg up
72 $ hg up
73 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
73 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
74 1 other heads for branch "default"
74 1 other heads for branch "default"
75 $ hg debugdirstate --large --nodate
75 $ hg debugdirstate --large --nodate
76 n 644 7 set large1
76 n 644 7 set large1
77 n 644 13 set large2
77 n 644 13 set large2
78
78
79 Test that lfdirstate keeps track of last modification of largefiles and
79 Test that lfdirstate keeps track of last modification of largefiles and
80 prevents unnecessary hashing of content - also after linear/noop update
80 prevents unnecessary hashing of content - also after linear/noop update
81
81
82 $ sleep 1
82 $ sleep 1
83 $ hg st
83 $ hg st
84 $ hg debugdirstate --large --nodate
84 $ hg debugdirstate --large --nodate
85 n 644 7 set large1
85 n 644 7 set large1
86 n 644 13 set large2
86 n 644 13 set large2
87 $ hg up
87 $ hg up
88 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 1 other heads for branch "default"
89 1 other heads for branch "default"
90 $ hg debugdirstate --large --nodate
90 $ hg debugdirstate --large --nodate
91 n 644 7 set large1
91 n 644 7 set large1
92 n 644 13 set large2
92 n 644 13 set large2
93
93
94 Test that "hg merge" updates largefiles from "other" correctly
94 Test that "hg merge" updates largefiles from "other" correctly
95
95
96 (getting largefiles from "other" normally)
96 (getting largefiles from "other" normally)
97
97
98 $ hg status -A large1
98 $ hg status -A large1
99 C large1
99 C large1
100 $ cat large1
100 $ cat large1
101 large1
101 large1
102 $ cat .hglf/large1
102 $ cat .hglf/large1
103 4669e532d5b2c093a78eca010077e708a071bb64
103 4669e532d5b2c093a78eca010077e708a071bb64
104 $ hg merge --config debug.dirstate.delaywrite=2
104 $ hg merge --config debug.dirstate.delaywrite=2
105 getting changed largefiles
105 getting changed largefiles
106 1 largefiles updated, 0 removed
106 1 largefiles updated, 0 removed
107 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 (branch merge, don't forget to commit)
108 (branch merge, don't forget to commit)
109 $ hg status -A large1
109 $ hg status -A large1
110 M large1
110 M large1
111 $ cat large1
111 $ cat large1
112 large1 in #1
112 large1 in #1
113 $ cat .hglf/large1
113 $ cat .hglf/large1
114 58e24f733a964da346e2407a2bee99d9001184f5
114 58e24f733a964da346e2407a2bee99d9001184f5
115 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
115 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
116 -4669e532d5b2c093a78eca010077e708a071bb64
116 -4669e532d5b2c093a78eca010077e708a071bb64
117 +58e24f733a964da346e2407a2bee99d9001184f5
117 +58e24f733a964da346e2407a2bee99d9001184f5
118
118
119 (getting largefiles from "other" via conflict prompt)
119 (getting largefiles from "other" via conflict prompt)
120
120
121 $ hg update -q -C 2
121 $ hg update -q -C 2
122 $ echo 'large1 in #3' > large1
122 $ echo 'large1 in #3' > large1
123 $ echo 'normal1 in #3' > normal1
123 $ echo 'normal1 in #3' > normal1
124 $ hg commit -m '#3'
124 $ hg commit -m '#3'
125 $ cat .hglf/large1
125 $ cat .hglf/large1
126 e5bb990443d6a92aaf7223813720f7566c9dd05b
126 e5bb990443d6a92aaf7223813720f7566c9dd05b
127 $ hg merge --config debug.dirstate.delaywrite=2 --config ui.interactive=True <<EOF
127 $ hg merge --config debug.dirstate.delaywrite=2 --config ui.interactive=True <<EOF
128 > o
128 > o
129 > EOF
129 > EOF
130 largefile large1 has a merge conflict
130 largefile large1 has a merge conflict
131 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
131 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
132 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
132 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
133 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
133 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
134 merging normal1
134 merging normal1
135 warning: conflicts while merging normal1! (edit, then use 'hg resolve --mark')
135 warning: conflicts while merging normal1! (edit, then use 'hg resolve --mark')
136 getting changed largefiles
136 getting changed largefiles
137 1 largefiles updated, 0 removed
137 1 largefiles updated, 0 removed
138 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
138 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
139 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
139 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
140 [1]
140 [1]
141 $ hg status -A large1
141 $ hg status -A large1
142 M large1
142 M large1
143 $ cat large1
143 $ cat large1
144 large1 in #1
144 large1 in #1
145 $ cat .hglf/large1
145 $ cat .hglf/large1
146 58e24f733a964da346e2407a2bee99d9001184f5
146 58e24f733a964da346e2407a2bee99d9001184f5
147 $ rm normal1.orig
147 $ rm normal1.orig
148
148
149 (merge non-existing largefiles from "other" via conflict prompt -
149 (merge non-existing largefiles from "other" via conflict prompt -
150 make sure the following commit doesn't abort in a confusing way when trying to
150 make sure the following commit doesn't abort in a confusing way when trying to
151 mark the non-existing file as normal in lfdirstate)
151 mark the non-existing file as normal in lfdirstate)
152
152
153 $ mv .hg/largefiles/58e24f733a964da346e2407a2bee99d9001184f5 .
153 $ mv .hg/largefiles/58e24f733a964da346e2407a2bee99d9001184f5 .
154 $ hg update -q -C 3
154 $ hg update -q -C 3
155 $ hg merge --config largefiles.usercache=not --config debug.dirstate.delaywrite=2 --tool :local --config ui.interactive=True <<EOF
155 $ hg merge --config largefiles.usercache=not --config debug.dirstate.delaywrite=2 --tool :local --config ui.interactive=True <<EOF
156 > o
156 > o
157 > EOF
157 > EOF
158 largefile large1 has a merge conflict
158 largefile large1 has a merge conflict
159 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
159 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
160 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
160 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
161 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
161 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
162 getting changed largefiles
162 getting changed largefiles
163 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from file:/*/$TESTTMP/repo (glob)
163 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from file:/*/$TESTTMP/repo (glob)
164 0 largefiles updated, 0 removed
164 0 largefiles updated, 0 removed
165 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
165 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
166 (branch merge, don't forget to commit)
166 (branch merge, don't forget to commit)
167 $ hg commit -m '1-2-3 testing' --config largefiles.usercache=not
167 $ hg commit -m '1-2-3 testing' --config largefiles.usercache=not
168 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from local store
168 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from local store
169 $ hg up -C . --config largefiles.usercache=not
169 $ hg up -C . --config largefiles.usercache=not
170 getting changed largefiles
170 getting changed largefiles
171 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from file:/*/$TESTTMP/repo (glob)
171 large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from file:/*/$TESTTMP/repo (glob)
172 0 largefiles updated, 0 removed
172 0 largefiles updated, 0 removed
173 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
173 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
174 $ hg st large1
174 $ hg st large1
175 ! large1
175 ! large1
176 $ hg rollback -q
176 $ hg rollback -q
177 $ mv 58e24f733a964da346e2407a2bee99d9001184f5 .hg/largefiles/
177 $ mv 58e24f733a964da346e2407a2bee99d9001184f5 .hg/largefiles/
178
178
179 Test that "hg revert -r REV" updates largefiles from "REV" correctly
179 Test that "hg revert -r REV" updates largefiles from "REV" correctly
180
180
181 $ hg update -q -C 3
181 $ hg update -q -C 3
182 $ hg status -A large1
182 $ hg status -A large1
183 C large1
183 C large1
184 $ cat large1
184 $ cat large1
185 large1 in #3
185 large1 in #3
186 $ cat .hglf/large1
186 $ cat .hglf/large1
187 e5bb990443d6a92aaf7223813720f7566c9dd05b
187 e5bb990443d6a92aaf7223813720f7566c9dd05b
188 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
188 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
189 -4669e532d5b2c093a78eca010077e708a071bb64
189 -4669e532d5b2c093a78eca010077e708a071bb64
190 +58e24f733a964da346e2407a2bee99d9001184f5
190 +58e24f733a964da346e2407a2bee99d9001184f5
191 $ hg revert --no-backup -r 1 --config debug.dirstate.delaywrite=2 large1
191 $ hg revert --no-backup -r 1 --config debug.dirstate.delaywrite=2 large1
192 $ hg status -A large1
192 $ hg status -A large1
193 M large1
193 M large1
194 $ cat large1
194 $ cat large1
195 large1 in #1
195 large1 in #1
196 $ cat .hglf/large1
196 $ cat .hglf/large1
197 58e24f733a964da346e2407a2bee99d9001184f5
197 58e24f733a964da346e2407a2bee99d9001184f5
198
198
199 Test that "hg rollback" restores status of largefiles correctly
199 Test that "hg rollback" restores status of largefiles correctly
200
200
201 $ hg update -C -q
201 $ hg update -C -q
202 $ hg remove large1
202 $ hg remove large1
203 $ test -f .hglf/large1
203 $ test -f .hglf/large1
204 [1]
204 [1]
205 $ hg forget large2
205 $ hg forget large2
206 $ test -f .hglf/large2
206 $ test -f .hglf/large2
207 [1]
207 [1]
208 $ echo largeX > largeX
208 $ echo largeX > largeX
209 $ hg add --large largeX
209 $ hg add --large largeX
210 $ cat .hglf/largeX
210 $ cat .hglf/largeX
211
211
212 $ hg commit -m 'will be rollback-ed soon'
212 $ hg commit -m 'will be rollback-ed soon'
213 $ echo largeY > largeY
213 $ echo largeY > largeY
214 $ hg add --large largeY
214 $ hg add --large largeY
215 #if windows
215 #if windows
216 $ hg status -A large1
216 $ hg status -A large1
217 large1: * (glob)
217 large1: * (glob)
218 #else
218 #else
219 $ hg status -A large1
219 $ hg status -A large1
220 large1: No such file or directory
220 large1: No such file or directory
221 #endif
221 #endif
222 $ hg status -A large2
222 $ hg status -A large2
223 ? large2
223 ? large2
224 $ hg status -A largeX
224 $ hg status -A largeX
225 C largeX
225 C largeX
226 $ hg status -A largeY
226 $ hg status -A largeY
227 A largeY
227 A largeY
228 $ hg rollback
228 $ hg rollback
229 repository tip rolled back to revision 3 (undo commit)
229 repository tip rolled back to revision 3 (undo commit)
230 working directory now based on revision 3
230 working directory now based on revision 3
231 $ hg status -A large1
231 $ hg status -A large1
232 R large1
232 R large1
233 $ test -f .hglf/large1
233 $ test -f .hglf/large1
234 [1]
234 [1]
235 $ hg status -A large2
235 $ hg status -A large2
236 R large2
236 R large2
237 $ test -f .hglf/large2
237 $ test -f .hglf/large2
238 [1]
238 [1]
239 $ hg status -A largeX
239 $ hg status -A largeX
240 A largeX
240 A largeX
241 $ cat .hglf/largeX
241 $ cat .hglf/largeX
242
242
243 $ hg status -A largeY
243 $ hg status -A largeY
244 ? largeY
244 ? largeY
245 $ test -f .hglf/largeY
245 $ test -f .hglf/largeY
246 [1]
246 [1]
247 $ rm largeY
247 $ rm largeY
248
248
249 Test that "hg rollback" restores standins correctly
249 Test that "hg rollback" restores standins correctly
250
250
251 $ hg commit -m 'will be rollback-ed soon'
251 $ hg commit -m 'will be rollback-ed soon'
252 $ hg update -q -C 2
252 $ hg update -q -C 2
253 $ cat large1
253 $ cat large1
254 large1
254 large1
255 $ cat .hglf/large1
255 $ cat .hglf/large1
256 4669e532d5b2c093a78eca010077e708a071bb64
256 4669e532d5b2c093a78eca010077e708a071bb64
257 $ cat large2
257 $ cat large2
258 large2 in #2
258 large2 in #2
259 $ cat .hglf/large2
259 $ cat .hglf/large2
260 3cfce6277e7668985707b6887ce56f9f62f6ccd9
260 3cfce6277e7668985707b6887ce56f9f62f6ccd9
261
261
262 $ hg rollback -q -f
262 $ hg rollback -q -f
263 $ cat large1
263 $ cat large1
264 large1
264 large1
265 $ cat .hglf/large1
265 $ cat .hglf/large1
266 4669e532d5b2c093a78eca010077e708a071bb64
266 4669e532d5b2c093a78eca010077e708a071bb64
267 $ cat large2
267 $ cat large2
268 large2 in #2
268 large2 in #2
269 $ cat .hglf/large2
269 $ cat .hglf/large2
270 3cfce6277e7668985707b6887ce56f9f62f6ccd9
270 3cfce6277e7668985707b6887ce56f9f62f6ccd9
271
271
272 (rollback the parent of the working directory, when the parent of it
272 (rollback the parent of the working directory, when the parent of it
273 is not branch-tip)
273 is not branch-tip)
274
274
275 $ hg update -q -C 1
275 $ hg update -q -C 1
276 $ cat .hglf/large1
276 $ cat .hglf/large1
277 58e24f733a964da346e2407a2bee99d9001184f5
277 58e24f733a964da346e2407a2bee99d9001184f5
278 $ cat .hglf/large2
278 $ cat .hglf/large2
279 1deebade43c8c498a3c8daddac0244dc55d1331d
279 1deebade43c8c498a3c8daddac0244dc55d1331d
280
280
281 $ echo normalX > normalX
281 $ echo normalX > normalX
282 $ hg add normalX
282 $ hg add normalX
283 $ hg commit -m 'will be rollback-ed soon'
283 $ hg commit -m 'will be rollback-ed soon'
284 $ hg rollback -q
284 $ hg rollback -q
285
285
286 $ cat .hglf/large1
286 $ cat .hglf/large1
287 58e24f733a964da346e2407a2bee99d9001184f5
287 58e24f733a964da346e2407a2bee99d9001184f5
288 $ cat .hglf/large2
288 $ cat .hglf/large2
289 1deebade43c8c498a3c8daddac0244dc55d1331d
289 1deebade43c8c498a3c8daddac0244dc55d1331d
290 $ rm normalX
290 $ rm normalX
291
291
292 Test that "hg status" shows status of largefiles correctly just after
292 Test that "hg status" shows status of largefiles correctly just after
293 automated commit like rebase/transplant
293 automated commit like rebase/transplant
294
294
295 $ cat >> .hg/hgrc <<EOF
295 $ cat >> .hg/hgrc <<EOF
296 > [extensions]
296 > [extensions]
297 > rebase =
297 > rebase =
298 > strip =
298 > strip =
299 > transplant =
299 > transplant =
300 > EOF
300 > EOF
301 $ hg update -q -C 1
301 $ hg update -q -C 1
302 $ hg remove large1
302 $ hg remove large1
303 $ echo largeX > largeX
303 $ echo largeX > largeX
304 $ hg add --large largeX
304 $ hg add --large largeX
305 $ hg commit -m '#4'
305 $ hg commit -m '#4'
306
306
307 $ hg rebase -s 1 -d 2 --keep
307 $ hg rebase -s 1 -d 2 --keep
308 rebasing 1:72518492caa6 "#1"
308 rebasing 1:72518492caa6 "#1"
309 rebasing 4:07d6153b5c04 "#4" (tip)
309 rebasing 4:07d6153b5c04 "#4" (tip)
310 #if windows
310 #if windows
311 $ hg status -A large1
311 $ hg status -A large1
312 large1: * (glob)
312 large1: * (glob)
313 #else
313 #else
314 $ hg status -A large1
314 $ hg status -A large1
315 large1: No such file or directory
315 large1: No such file or directory
316 #endif
316 #endif
317 $ hg status -A largeX
317 $ hg status -A largeX
318 C largeX
318 C largeX
319 $ hg strip -q 5
319 $ hg strip -q 5
320
320
321 $ hg update -q -C 2
321 $ hg update -q -C 2
322 $ hg transplant -q 1 4
322 $ hg transplant -q 1 4
323 #if windows
323 #if windows
324 $ hg status -A large1
324 $ hg status -A large1
325 large1: * (glob)
325 large1: * (glob)
326 #else
326 #else
327 $ hg status -A large1
327 $ hg status -A large1
328 large1: No such file or directory
328 large1: No such file or directory
329 #endif
329 #endif
330 $ hg status -A largeX
330 $ hg status -A largeX
331 C largeX
331 C largeX
332 $ hg strip -q 5
332 $ hg strip -q 5
333
333
334 $ hg update -q -C 2
334 $ hg update -q -C 2
335 $ hg transplant -q --merge 1 --merge 4
335 $ hg transplant -q --merge 1 --merge 4
336 #if windows
336 #if windows
337 $ hg status -A large1
337 $ hg status -A large1
338 large1: * (glob)
338 large1: * (glob)
339 #else
339 #else
340 $ hg status -A large1
340 $ hg status -A large1
341 large1: No such file or directory
341 large1: No such file or directory
342 #endif
342 #endif
343 $ hg status -A largeX
343 $ hg status -A largeX
344 C largeX
344 C largeX
345 $ hg strip -q 5
345 $ hg strip -q 5
346
346
347 Test that linear merge can detect modification (and conflict) correctly
347 Test that linear merge can detect modification (and conflict) correctly
348
348
349 (linear merge without conflict)
349 (linear merge without conflict)
350
350
351 $ echo 'large2 for linear merge (no conflict)' > large2
351 $ echo 'large2 for linear merge (no conflict)' > large2
352 $ hg update 3 --config debug.dirstate.delaywrite=2
352 $ hg update 3 --config debug.dirstate.delaywrite=2
353 getting changed largefiles
353 getting changed largefiles
354 1 largefiles updated, 0 removed
354 1 largefiles updated, 0 removed
355 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
355 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
356 $ hg status -A large2
356 $ hg status -A large2
357 M large2
357 M large2
358 $ cat large2
358 $ cat large2
359 large2 for linear merge (no conflict)
359 large2 for linear merge (no conflict)
360 $ cat .hglf/large2
360 $ cat .hglf/large2
361 9c4bf8f1b33536d6e5f89447e10620cfe52ea710
361 9c4bf8f1b33536d6e5f89447e10620cfe52ea710
362
362
363 (linear merge with conflict, choosing "other")
363 (linear merge with conflict, choosing "other")
364
364
365 $ hg update -q -C 2
365 $ hg update -q -C 2
366 $ echo 'large1 for linear merge (conflict)' > large1
366 $ echo 'large1 for linear merge (conflict)' > large1
367 $ hg update 3 --config ui.interactive=True <<EOF
367 $ hg update 3 --config ui.interactive=True <<EOF
368 > o
368 > o
369 > EOF
369 > EOF
370 largefile large1 has a merge conflict
370 largefile large1 has a merge conflict
371 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
371 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
372 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
372 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
373 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? o
373 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? o
374 getting changed largefiles
374 getting changed largefiles
375 1 largefiles updated, 0 removed
375 1 largefiles updated, 0 removed
376 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
376 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
377 $ hg status -A large1
377 $ hg status -A large1
378 C large1
378 C large1
379 $ cat large1
379 $ cat large1
380 large1 in #3
380 large1 in #3
381 $ cat .hglf/large1
381 $ cat .hglf/large1
382 e5bb990443d6a92aaf7223813720f7566c9dd05b
382 e5bb990443d6a92aaf7223813720f7566c9dd05b
383
383
384 (linear merge with conflict, choosing "local")
384 (linear merge with conflict, choosing "local")
385
385
386 $ hg update -q -C 2
386 $ hg update -q -C 2
387 $ echo 'large1 for linear merge (conflict)' > large1
387 $ echo 'large1 for linear merge (conflict)' > large1
388 $ hg update 3 --config debug.dirstate.delaywrite=2
388 $ hg update 3 --config debug.dirstate.delaywrite=2
389 largefile large1 has a merge conflict
389 largefile large1 has a merge conflict
390 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
390 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
391 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
391 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
392 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
392 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
393 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
393 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
394 $ hg status -A large1
394 $ hg status -A large1
395 M large1
395 M large1
396 $ cat large1
396 $ cat large1
397 large1 for linear merge (conflict)
397 large1 for linear merge (conflict)
398 $ cat .hglf/large1
398 $ cat .hglf/large1
399 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
399 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
400
400
401 Test a linear merge to a revision containing same-name normal file
401 Test a linear merge to a revision containing same-name normal file
402
402
403 $ hg update -q -C 3
403 $ hg update -q -C 3
404 $ hg remove large2
404 $ hg remove large2
405 $ echo 'large2 as normal file' > large2
405 $ echo 'large2 as normal file' > large2
406 $ hg add large2
406 $ hg add large2
407 $ echo 'large3 as normal file' > large3
407 $ echo 'large3 as normal file' > large3
408 $ hg add large3
408 $ hg add large3
409 $ hg commit -m '#5'
409 $ hg commit -m '#5'
410 $ hg manifest
410 $ hg manifest
411 .hglf/large1
411 .hglf/large1
412 large2
412 large2
413 large3
413 large3
414 normal1
414 normal1
415
415
416 (modified largefile is already switched to normal)
416 (modified largefile is already switched to normal)
417
417
418 $ hg update -q -C 2
418 $ hg update -q -C 2
419 $ echo 'modified large2 for linear merge' > large2
419 $ echo 'modified large2 for linear merge' > large2
420 $ hg update -q 5
420 $ hg update -q 5
421 remote turned local largefile large2 into a normal file
421 remote turned local largefile large2 into a normal file
422 keep (l)argefile or use (n)ormal file? l
422 keep (l)argefile or use (n)ormal file? l
423 $ hg debugdirstate --nodates | grep large2
423 $ hg debugdirstate --nodates | grep large2
424 a 0 -1 unset .hglf/large2
424 a 0 -1 unset .hglf/large2
425 r 0 0 set large2
425 r 0 0 set large2
426 $ hg status -A large2
426 $ hg status -A large2
427 A large2
427 A large2
428 $ cat large2
428 $ cat large2
429 modified large2 for linear merge
429 modified large2 for linear merge
430
430
431 (added largefile is already committed as normal)
431 (added largefile is already committed as normal)
432
432
433 $ hg update -q -C 2
433 $ hg update -q -C 2
434 $ echo 'large3 as large file for linear merge' > large3
434 $ echo 'large3 as large file for linear merge' > large3
435 $ hg add --large large3
435 $ hg add --large large3
436 $ hg update -q 5
436 $ hg update -q 5
437 remote turned local largefile large3 into a normal file
437 remote turned local largefile large3 into a normal file
438 keep (l)argefile or use (n)ormal file? l
438 keep (l)argefile or use (n)ormal file? l
439 $ hg debugdirstate --nodates | grep large3
439 $ hg debugdirstate --nodates | grep large3
440 a 0 -1 unset .hglf/large3
440 a 0 -1 unset .hglf/large3
441 r 0 0 set large3
441 r 0 0 set large3
442 $ hg status -A large3
442 $ hg status -A large3
443 A large3
443 A large3
444 $ cat large3
444 $ cat large3
445 large3 as large file for linear merge
445 large3 as large file for linear merge
446 $ rm -f large3 .hglf/large3
446 $ rm -f large3 .hglf/large3
447
447
448 Test that the internal linear merging works correctly
448 Test that the internal linear merging works correctly
449 (both heads are stripped to keep pairing of revision number and commit log)
449 (both heads are stripped to keep pairing of revision number and commit log)
450
450
451 $ hg update -q -C 2
451 $ hg update -q -C 2
452 $ hg strip 3 4
452 $ hg strip 3 4
453 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9530e27857f7-2e7b195d-backup.hg (glob)
453 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9530e27857f7-2e7b195d-backup.hg (glob)
454 $ mv .hg/strip-backup/9530e27857f7-2e7b195d-backup.hg $TESTTMP
454 $ mv .hg/strip-backup/9530e27857f7-2e7b195d-backup.hg $TESTTMP
455
455
456 (internal linear merging at "hg pull --update")
456 (internal linear merging at "hg pull --update")
457
457
458 $ echo 'large1 for linear merge (conflict)' > large1
458 $ echo 'large1 for linear merge (conflict)' > large1
459 $ echo 'large2 for linear merge (conflict with normal file)' > large2
459 $ echo 'large2 for linear merge (conflict with normal file)' > large2
460 $ hg pull --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
460 $ hg pull --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
461 pulling from $TESTTMP/9530e27857f7-2e7b195d-backup.hg (glob)
461 pulling from $TESTTMP/9530e27857f7-2e7b195d-backup.hg (glob)
462 searching for changes
462 searching for changes
463 adding changesets
463 adding changesets
464 adding manifests
464 adding manifests
465 adding file changes
465 adding file changes
466 added 3 changesets with 5 changes to 5 files
466 added 3 changesets with 5 changes to 5 files
467 remote turned local largefile large2 into a normal file
467 remote turned local largefile large2 into a normal file
468 keep (l)argefile or use (n)ormal file? l
468 keep (l)argefile or use (n)ormal file? l
469 largefile large1 has a merge conflict
469 largefile large1 has a merge conflict
470 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
470 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
471 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
471 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
472 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
472 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
473 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
473 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
474 1 other heads for branch "default"
474 1 other heads for branch "default"
475
475
476 $ hg status -A large1
476 $ hg status -A large1
477 M large1
477 M large1
478 $ cat large1
478 $ cat large1
479 large1 for linear merge (conflict)
479 large1 for linear merge (conflict)
480 $ cat .hglf/large1
480 $ cat .hglf/large1
481 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
481 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
482 $ hg status -A large2
482 $ hg status -A large2
483 A large2
483 A large2
484 $ cat large2
484 $ cat large2
485 large2 for linear merge (conflict with normal file)
485 large2 for linear merge (conflict with normal file)
486 $ cat .hglf/large2
486 $ cat .hglf/large2
487 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
487 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
488
488
489 (internal linear merging at "hg unbundle --update")
489 (internal linear merging at "hg unbundle --update")
490
490
491 $ hg update -q -C 2
491 $ hg update -q -C 2
492 $ hg rollback -q
492 $ hg rollback -q
493
493
494 $ echo 'large1 for linear merge (conflict)' > large1
494 $ echo 'large1 for linear merge (conflict)' > large1
495 $ echo 'large2 for linear merge (conflict with normal file)' > large2
495 $ echo 'large2 for linear merge (conflict with normal file)' > large2
496 $ hg unbundle --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
496 $ hg unbundle --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg
497 adding changesets
497 adding changesets
498 adding manifests
498 adding manifests
499 adding file changes
499 adding file changes
500 added 3 changesets with 5 changes to 5 files
500 added 3 changesets with 5 changes to 5 files
501 remote turned local largefile large2 into a normal file
501 remote turned local largefile large2 into a normal file
502 keep (l)argefile or use (n)ormal file? l
502 keep (l)argefile or use (n)ormal file? l
503 largefile large1 has a merge conflict
503 largefile large1 has a merge conflict
504 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
504 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
505 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
505 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
506 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
506 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
507 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
507 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
508 1 other heads for branch "default"
508 1 other heads for branch "default"
509
509
510 $ hg status -A large1
510 $ hg status -A large1
511 M large1
511 M large1
512 $ cat large1
512 $ cat large1
513 large1 for linear merge (conflict)
513 large1 for linear merge (conflict)
514 $ cat .hglf/large1
514 $ cat .hglf/large1
515 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
515 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
516 $ hg status -A large2
516 $ hg status -A large2
517 A large2
517 A large2
518 $ cat large2
518 $ cat large2
519 large2 for linear merge (conflict with normal file)
519 large2 for linear merge (conflict with normal file)
520 $ cat .hglf/large2
520 $ cat .hglf/large2
521 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
521 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
522
522
523 (internal linear merging in subrepo at "hg update")
523 (internal linear merging in subrepo at "hg update")
524
524
525 $ cd ..
525 $ cd ..
526 $ hg init subparent
526 $ hg init subparent
527 $ cd subparent
527 $ cd subparent
528
528
529 $ hg clone -q -u 2 ../repo sub
529 $ hg clone -q -u 2 ../repo sub
530 $ cat > .hgsub <<EOF
530 $ cat > .hgsub <<EOF
531 > sub = sub
531 > sub = sub
532 > EOF
532 > EOF
533 $ hg add .hgsub
533 $ hg add .hgsub
534 $ hg commit -m '#0@parent'
534 $ hg commit -m '#0@parent'
535 $ cat .hgsubstate
535 $ cat .hgsubstate
536 f74e50bd9e5594b7cf1e6c5cbab86ddd25f3ca2f sub
536 f74e50bd9e5594b7cf1e6c5cbab86ddd25f3ca2f sub
537 $ hg -R sub update -q
537 $ hg -R sub update -q
538 $ hg commit -m '#1@parent'
538 $ hg commit -m '#1@parent'
539 $ cat .hgsubstate
539 $ cat .hgsubstate
540 d65e59e952a9638e2ce863b41a420ca723dd3e8d sub
540 d65e59e952a9638e2ce863b41a420ca723dd3e8d sub
541 $ hg update -q 0
541 $ hg update -q 0
542
542
543 $ echo 'large1 for linear merge (conflict)' > sub/large1
543 $ echo 'large1 for linear merge (conflict)' > sub/large1
544 $ echo 'large2 for linear merge (conflict with normal file)' > sub/large2
544 $ echo 'large2 for linear merge (conflict with normal file)' > sub/large2
545 $ hg update --config ui.interactive=True --config debug.dirstate.delaywrite=2 <<EOF
545 $ hg update --config ui.interactive=True --config debug.dirstate.delaywrite=2 <<EOF
546 > m
546 > m
547 > r
547 > r
548 > l
548 > l
549 > l
549 > l
550 > EOF
550 > EOF
551 subrepository sub diverged (local revision: f74e50bd9e55, remote revision: d65e59e952a9)
551 subrepository sub diverged (local revision: f74e50bd9e55, remote revision: d65e59e952a9)
552 (M)erge, keep (l)ocal or keep (r)emote? m
552 (M)erge, keep (l)ocal or keep (r)emote? m
553 subrepository sources for sub differ (in checked out version)
553 subrepository sources for sub differ (in checked out version)
554 use (l)ocal source (f74e50bd9e55) or (r)emote source (d65e59e952a9)? r
554 use (l)ocal source (f74e50bd9e55) or (r)emote source (d65e59e952a9)? r
555 remote turned local largefile large2 into a normal file
555 remote turned local largefile large2 into a normal file
556 keep (l)argefile or use (n)ormal file? l
556 keep (l)argefile or use (n)ormal file? l
557 largefile large1 has a merge conflict
557 largefile large1 has a merge conflict
558 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
558 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
559 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
559 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
560 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
560 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
561 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
561 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
562 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
562 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
563
563
564 $ hg -R sub status -A sub/large1
564 $ hg -R sub status -A sub/large1
565 M sub/large1
565 M sub/large1
566 $ cat sub/large1
566 $ cat sub/large1
567 large1 for linear merge (conflict)
567 large1 for linear merge (conflict)
568 $ cat sub/.hglf/large1
568 $ cat sub/.hglf/large1
569 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
569 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
570 $ hg -R sub status -A sub/large2
570 $ hg -R sub status -A sub/large2
571 A sub/large2
571 A sub/large2
572 $ cat sub/large2
572 $ cat sub/large2
573 large2 for linear merge (conflict with normal file)
573 large2 for linear merge (conflict with normal file)
574 $ cat sub/.hglf/large2
574 $ cat sub/.hglf/large2
575 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
575 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
576
576
577 $ cd ..
577 $ cd ..
578 $ cd repo
578 $ cd repo
579
579
580 Test that rebase updates largefiles in the working directory even if
580 Test that rebase updates largefiles in the working directory even if
581 it is aborted by conflict.
581 it is aborted by conflict.
582
582
583 $ hg update -q -C 3
583 $ hg update -q -C 3
584 $ cat .hglf/large1
584 $ cat .hglf/large1
585 e5bb990443d6a92aaf7223813720f7566c9dd05b
585 e5bb990443d6a92aaf7223813720f7566c9dd05b
586 $ cat large1
586 $ cat large1
587 large1 in #3
587 large1 in #3
588 $ hg rebase -s 1 -d 3 --keep --config ui.interactive=True <<EOF
588 $ hg rebase -s 1 -d 3 --keep --config ui.interactive=True <<EOF
589 > o
589 > o
590 > EOF
590 > EOF
591 rebasing 1:72518492caa6 "#1"
591 rebasing 1:72518492caa6 "#1"
592 largefile large1 has a merge conflict
592 largefile large1 has a merge conflict
593 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
593 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
594 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
594 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
595 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
595 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
596 merging normal1
596 merging normal1
597 warning: conflicts while merging normal1! (edit, then use 'hg resolve --mark')
597 warning: conflicts while merging normal1! (edit, then use 'hg resolve --mark')
598 unresolved conflicts (see hg resolve, then hg rebase --continue)
598 unresolved conflicts (see hg resolve, then hg rebase --continue)
599 [1]
599 [1]
600 $ cat .hglf/large1
600 $ cat .hglf/large1
601 58e24f733a964da346e2407a2bee99d9001184f5
601 58e24f733a964da346e2407a2bee99d9001184f5
602 $ cat large1
602 $ cat large1
603 large1 in #1
603 large1 in #1
604 $ rm normal1.orig
604 $ rm normal1.orig
605
605
606 Test that rebase updates standins for manually modified largefiles at
606 Test that rebase updates standins for manually modified largefiles at
607 the 1st commit of resuming.
607 the 1st commit of resuming.
608
608
609 $ echo "manually modified before 'hg rebase --continue'" > large1
609 $ echo "manually modified before 'hg rebase --continue'" > large1
610 $ hg resolve -m normal1
610 $ hg resolve -m normal1
611 (no more unresolved files)
611 (no more unresolved files)
612 continue: hg rebase --continue
612 continue: hg rebase --continue
613 $ hg rebase --continue --config ui.interactive=True <<EOF
613 $ hg rebase --continue --config ui.interactive=True <<EOF
614 > c
614 > c
615 > EOF
615 > EOF
616 rebasing 1:72518492caa6 "#1"
616 rebasing 1:72518492caa6 "#1"
617 rebasing 4:07d6153b5c04 "#4"
617 rebasing 4:07d6153b5c04 "#4"
618 local changed .hglf/large1 which remote deleted
618 local changed .hglf/large1 which remote deleted
619 use (c)hanged version, (d)elete, or leave (u)nresolved? c
619 use (c)hanged version, (d)elete, or leave (u)nresolved? c
620
620
621 $ hg diff -c "tip~1" --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
621 $ hg diff -c "tip~1" --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
622 -e5bb990443d6a92aaf7223813720f7566c9dd05b
622 -e5bb990443d6a92aaf7223813720f7566c9dd05b
623 +8a4f783556e7dea21139ca0466eafce954c75c13
623 +8a4f783556e7dea21139ca0466eafce954c75c13
624 $ rm -f large1
624 $ rm -f large1
625 $ hg update -q -C tip
625 $ hg update -q -C tip
626 $ cat large1
626 $ cat large1
627 manually modified before 'hg rebase --continue'
627 manually modified before 'hg rebase --continue'
628
628
629 Test that transplant updates largefiles, of which standins are safely
629 Test that transplant updates largefiles, of which standins are safely
630 changed, even if it is aborted by conflict of other.
630 changed, even if it is aborted by conflict of other.
631
631
632 $ hg update -q -C 5
632 $ hg update -q -C 5
633 $ cat .hglf/large1
633 $ cat .hglf/large1
634 e5bb990443d6a92aaf7223813720f7566c9dd05b
634 e5bb990443d6a92aaf7223813720f7566c9dd05b
635 $ cat large1
635 $ cat large1
636 large1 in #3
636 large1 in #3
637 $ hg diff -c 4 .hglf/largeX | grep '^[+-][0-9a-z]'
637 $ hg diff -c 4 .hglf/largeX | grep '^[+-][0-9a-z]'
638 +fa44618ea25181aff4f48b70428294790cec9f61
638 +fa44618ea25181aff4f48b70428294790cec9f61
639 $ hg transplant 4
639 $ hg transplant 4
640 applying 07d6153b5c04
640 applying 07d6153b5c04
641 patching file .hglf/large1
641 patching file .hglf/large1
642 Hunk #1 FAILED at 0
642 Hunk #1 FAILED at 0
643 1 out of 1 hunks FAILED -- saving rejects to file .hglf/large1.rej
643 1 out of 1 hunks FAILED -- saving rejects to file .hglf/large1.rej
644 patch failed to apply
644 patch failed to apply
645 abort: fix up the working directory and run hg transplant --continue
645 abort: fix up the working directory and run hg transplant --continue
646 [255]
646 [255]
647 $ hg status -A large1
647 $ hg status -A large1
648 C large1
648 C large1
649 $ cat .hglf/large1
649 $ cat .hglf/large1
650 e5bb990443d6a92aaf7223813720f7566c9dd05b
650 e5bb990443d6a92aaf7223813720f7566c9dd05b
651 $ cat large1
651 $ cat large1
652 large1 in #3
652 large1 in #3
653 $ hg status -A largeX
653 $ hg status -A largeX
654 A largeX
654 A largeX
655 $ cat .hglf/largeX
655 $ cat .hglf/largeX
656 fa44618ea25181aff4f48b70428294790cec9f61
656 fa44618ea25181aff4f48b70428294790cec9f61
657 $ cat largeX
657 $ cat largeX
658 largeX
658 largeX
659
659
660 Test that transplant updates standins for manually modified largefiles
660 Test that transplant updates standins for manually modified largefiles
661 at the 1st commit of resuming.
661 at the 1st commit of resuming.
662
662
663 $ echo "manually modified before 'hg transplant --continue'" > large1
663 $ echo "manually modified before 'hg transplant --continue'" > large1
664 $ hg transplant --continue
664 $ hg transplant --continue
665 07d6153b5c04 transplanted as f1bf30eb88cc
665 07d6153b5c04 transplanted as f1bf30eb88cc
666 $ hg diff -c tip .hglf/large1 | grep '^[+-][0-9a-z]'
666 $ hg diff -c tip .hglf/large1 | grep '^[+-][0-9a-z]'
667 -e5bb990443d6a92aaf7223813720f7566c9dd05b
667 -e5bb990443d6a92aaf7223813720f7566c9dd05b
668 +6a4f36d4075fbe0f30ec1d26ca44e63c05903671
668 +6a4f36d4075fbe0f30ec1d26ca44e63c05903671
669 $ rm -f large1
669 $ rm -f large1
670 $ hg update -q -C tip
670 $ hg update -q -C tip
671 $ cat large1
671 $ cat large1
672 manually modified before 'hg transplant --continue'
672 manually modified before 'hg transplant --continue'
673
673
674 Test that "hg status" doesn't show removal of largefiles not managed
674 Test that "hg status" doesn't show removal of largefiles not managed
675 in the target context.
675 in the target context.
676
676
677 $ hg update -q -C 4
677 $ hg update -q -C 4
678 $ hg remove largeX
678 $ hg remove largeX
679 $ hg status -A largeX
679 $ hg status -A largeX
680 R largeX
680 R largeX
681 $ hg status -A --rev '.^1' largeX
681 $ hg status -A --rev '.^1' largeX
682
682
683 #if execbit
683 #if execbit
684
684
685 Test that "hg status" against revisions other than parent notices exec
685 Test that "hg status" against revisions other than parent notices exec
686 bit changes of largefiles.
686 bit changes of largefiles.
687
687
688 $ hg update -q -C 4
688 $ hg update -q -C 4
689
689
690 (the case that large2 doesn't have exec bit in the target context but
690 (the case that large2 doesn't have exec bit in the target context but
691 in the working context)
691 in the working context)
692
692
693 $ chmod +x large2
693 $ chmod +x large2
694 $ hg status -A --rev 0 large2
694 $ hg status -A --rev 0 large2
695 M large2
695 M large2
696 $ hg commit -m 'chmod +x large2'
696 $ hg commit -m 'chmod +x large2'
697
697
698 (the case that large2 has exec bit in the target context but not in
698 (the case that large2 has exec bit in the target context but not in
699 the working context)
699 the working context)
700
700
701 $ echo dummy > dummy
701 $ echo dummy > dummy
702 $ hg add dummy
702 $ hg add dummy
703 $ hg commit -m 'revision for separation'
703 $ hg commit -m 'revision for separation'
704 $ chmod -x large2
704 $ chmod -x large2
705 $ hg status -A --rev '.^1' large2
705 $ hg status -A --rev '.^1' large2
706 M large2
706 M large2
707
707
708 #else
708 #else
709
709
710 Test that "hg status" against revisions other than parent ignores exec
710 Test that "hg status" against revisions other than parent ignores exec
711 bit correctly on the platform being unaware of it.
711 bit correctly on the platform being unaware of it.
712
712
713 $ hg update -q -C 4
713 $ hg update -q -C 4
714
714
715 $ cat > exec-bit.patch <<EOF
715 $ cat > exec-bit.patch <<EOF
716 > # HG changeset patch
716 > # HG changeset patch
717 > # User test
717 > # User test
718 > # Date 0 0
718 > # Date 0 0
719 > # Thu Jan 01 00:00:00 1970 +0000
719 > # Thu Jan 01 00:00:00 1970 +0000
720 > # Node ID be1b433a65b12b27b5519d92213e14f7e1769b90
720 > # Node ID be1b433a65b12b27b5519d92213e14f7e1769b90
721 > # Parent 07d6153b5c04313efb75deec9ba577de7faeb727
721 > # Parent 07d6153b5c04313efb75deec9ba577de7faeb727
722 > chmod +x large2
722 > chmod +x large2
723 >
723 >
724 > diff --git a/.hglf/large2 b/.hglf/large2
724 > diff --git a/.hglf/large2 b/.hglf/large2
725 > old mode 100644
725 > old mode 100644
726 > new mode 100755
726 > new mode 100755
727 > EOF
727 > EOF
728 $ hg import --exact --bypass exec-bit.patch
728 $ hg import --exact --bypass exec-bit.patch
729 applying exec-bit.patch
729 applying exec-bit.patch
730 $ hg status -A --rev tip large2
730 $ hg status -A --rev tip large2
731 C large2
731 C large2
732
732
733 #endif
733 #endif
734
734
735 Test a fatal error interrupting an update. Verify that status report dirty
735 Test a fatal error interrupting an update. Verify that status report dirty
736 files correctly after an interrupted update. Also verify that checking all
736 files correctly after an interrupted update. Also verify that checking all
737 hashes reveals it isn't clean.
737 hashes reveals it isn't clean.
738
738
739 Start with clean dirstates:
739 Start with clean dirstates:
740 $ hg up -qcr "8^"
740 $ hg up -qcr "8^"
741 $ sleep 1
741 $ sleep 1
742 $ hg st
742 $ hg st
743 Update standins without updating largefiles - large1 is modified and largeX is
743 Update standins without updating largefiles - large1 is modified and largeX is
744 added:
744 added:
745 $ cat << EOF > ../crashupdatelfiles.py
745 $ cat << EOF > ../crashupdatelfiles.py
746 > import hgext.largefiles.lfutil
746 > import hgext.largefiles.lfutil
747 > def getlfilestoupdate(oldstandins, newstandins):
747 > def getlfilestoupdate(oldstandins, newstandins):
748 > raise SystemExit(7)
748 > raise SystemExit(7)
749 > hgext.largefiles.lfutil.getlfilestoupdate = getlfilestoupdate
749 > hgext.largefiles.lfutil.getlfilestoupdate = getlfilestoupdate
750 > EOF
750 > EOF
751 $ hg up -Cr "8" --config extensions.crashupdatelfiles=../crashupdatelfiles.py
751 $ hg up -Cr "8" --config extensions.crashupdatelfiles=../crashupdatelfiles.py
752 [7]
752 [7]
753 Check large1 content and status ... and that update will undo modifications:
753 Check large1 content and status ... and that update will undo modifications:
754 BUG: large is R
755 $ cat large1
754 $ cat large1
756 large1 in #3
755 large1 in #3
757 $ hg st
756 $ hg st
758 M large1
757 M large1
759 R largeX
758 ! largeX
760 $ hg up -Cr .
759 $ hg up -Cr .
761 getting changed largefiles
760 getting changed largefiles
762 1 largefiles updated, 0 removed
761 2 largefiles updated, 0 removed
763 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
762 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
764 $ cat large1
763 $ cat large1
765 manually modified before 'hg transplant --continue'
764 manually modified before 'hg transplant --continue'
766 $ hg st
765 $ hg st
767 R largeX
766 Force largefiles rehashing and check that all changes have been caught by
768 Force largefiles rehashing and check again - which makes it realize that largeX
767 status and update:
769 not has been removed but just doesn't exist:
770 $ rm .hg/largefiles/dirstate
768 $ rm .hg/largefiles/dirstate
771 $ hg st
769 $ hg st
772 ! largeX
773 $ hg up -Cr .
774 getting changed largefiles
775 1 largefiles updated, 0 removed
776 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
777 $ hg st
778
770
779 $ cd ..
771 $ cd ..
780
772
781 Test that "hg convert" avoids copying largefiles from the working
773 Test that "hg convert" avoids copying largefiles from the working
782 directory into store, because "hg convert" doesn't update largefiles
774 directory into store, because "hg convert" doesn't update largefiles
783 in the working directory (removing files under ".cache/largefiles"
775 in the working directory (removing files under ".cache/largefiles"
784 forces "hg convert" to copy corresponding largefiles)
776 forces "hg convert" to copy corresponding largefiles)
785
777
786 $ cat >> $HGRCPATH <<EOF
778 $ cat >> $HGRCPATH <<EOF
787 > [extensions]
779 > [extensions]
788 > convert =
780 > convert =
789 > EOF
781 > EOF
790
782
791 $ rm $TESTTMP/.cache/largefiles/6a4f36d4075fbe0f30ec1d26ca44e63c05903671
783 $ rm $TESTTMP/.cache/largefiles/6a4f36d4075fbe0f30ec1d26ca44e63c05903671
792 $ hg convert -q repo repo.converted
784 $ hg convert -q repo repo.converted
General Comments 0
You need to be logged in to leave comments. Login now