##// END OF EJS Templates
convert: add a config option to help doing identity hg->hg conversion...
Valentin Gatien-Baron -
r42839:d98ec36b default
parent child Browse files
Show More
@@ -0,0 +1,40 b''
1 Testing that convert.hg.preserve-hash=true can be used to make hg
2 convert from hg repo to hg repo preserve hashes, even if the
3 computation of the files list in commits change slightly between hg
4 versions.
5
6 $ cat <<'EOF' >> "$HGRCPATH"
7 > [extensions]
8 > convert =
9 > EOF
10 $ cat <<'EOF' > changefileslist.py
11 > from mercurial import (changelog, extensions)
12 > def wrap(orig, clog, manifest, files, *args, **kwargs):
13 > return orig(clog, manifest, ["a"], *args, **kwargs)
14 > def extsetup(ui):
15 > extensions.wrapfunction(changelog.changelog, 'add', wrap)
16 > EOF
17
18 $ hg init repo
19 $ cd repo
20 $ echo a > a; hg commit -qAm a
21 $ echo b > a; hg commit -qAm b
22 $ hg up -qr 0; echo c > c; hg commit -qAm c
23 $ hg merge -qr 1
24 $ hg commit -m_ --config extensions.x=../changefileslist.py
25 $ hg log -r . -T '{node|short} {files|json}\n'
26 c085bbe93d59 ["a"]
27
28 Now that we have a commit with a files list that's not what the
29 current hg version would create, check that convert either fixes it or
30 keeps it depending on config:
31
32 $ hg convert -q . ../convert
33 $ hg --cwd ../convert log -r tip -T '{node|short} {files|json}\n'
34 b7c4d4bbacd3 []
35 $ rm -rf ../convert
36
37 $ hg convert -q . ../convert --config convert.hg.preserve-hash=true
38 $ hg --cwd ../convert log -r tip -T '{node|short} {files|json}\n'
39 c085bbe93d59 ["a"]
40 $ rm -rf ../convert
@@ -439,6 +439,11 b' def convert(ui, src, dest=None, revmapfi'
439 :convert.hg.sourcename: records the given string as a 'convert_source' extra
439 :convert.hg.sourcename: records the given string as a 'convert_source' extra
440 value on each commit made in the target repository. The default is None.
440 value on each commit made in the target repository. The default is None.
441
441
442 :convert.hg.preserve-hash: only works with mercurial sources. Make convert
443 prevent performance improvement to the list of modified files in commits
444 when such an improvement would cause the hash of a commit to change.
445 The default is False.
446
442 All Destinations
447 All Destinations
443 ################
448 ################
444
449
@@ -114,7 +114,7 b" SKIPREV = 'SKIP'"
114 class commit(object):
114 class commit(object):
115 def __init__(self, author, date, desc, parents, branch=None, rev=None,
115 def __init__(self, author, date, desc, parents, branch=None, rev=None,
116 extra=None, sortkey=None, saverev=True, phase=phases.draft,
116 extra=None, sortkey=None, saverev=True, phase=phases.draft,
117 optparents=None):
117 optparents=None, ctx=None):
118 self.author = author or 'unknown'
118 self.author = author or 'unknown'
119 self.date = date or '0 0'
119 self.date = date or '0 0'
120 self.desc = desc
120 self.desc = desc
@@ -126,6 +126,7 b' class commit(object):'
126 self.sortkey = sortkey
126 self.sortkey = sortkey
127 self.saverev = saverev
127 self.saverev = saverev
128 self.phase = phase
128 self.phase = phase
129 self.ctx = ctx # for hg to hg conversions
129
130
130 class converter_source(object):
131 class converter_source(object):
131 """Conversion source interface"""
132 """Conversion source interface"""
@@ -339,7 +339,11 b' class mercurial_sink(common.converter_si'
339 phases.phasenames[commit.phase], 'convert')
339 phases.phasenames[commit.phase], 'convert')
340
340
341 with self.repo.transaction("convert") as tr:
341 with self.repo.transaction("convert") as tr:
342 node = nodemod.hex(self.repo.commitctx(ctx))
342 if self.repo.ui.config('convert', 'hg.preserve-hash'):
343 origctx = commit.ctx
344 else:
345 origctx = None
346 node = nodemod.hex(self.repo.commitctx(ctx, origctx=origctx))
343
347
344 # If the node value has changed, but the phase is lower than
348 # If the node value has changed, but the phase is lower than
345 # draft, set it back to draft since it hasn't been exposed
349 # draft, set it back to draft since it hasn't been exposed
@@ -591,7 +595,8 b' class mercurial_source(common.converter_'
591 extra=ctx.extra(),
595 extra=ctx.extra(),
592 sortkey=ctx.rev(),
596 sortkey=ctx.rev(),
593 saverev=self.saverev,
597 saverev=self.saverev,
594 phase=ctx.phase())
598 phase=ctx.phase(),
599 ctx=ctx)
595
600
596 def numcommits(self):
601 def numcommits(self):
597 return len(self.repo)
602 return len(self.repo)
@@ -400,7 +400,7 b' def reposetup(ui, repo):'
400 if wlock is not None:
400 if wlock is not None:
401 wlock.release()
401 wlock.release()
402
402
403 def commitctx(self, ctx, error=False):
403 def commitctx(self, ctx, error=False, origctx=None):
404 for f in sorted(ctx.added() + ctx.modified()):
404 for f in sorted(ctx.added() + ctx.modified()):
405 if not self._eolmatch(f):
405 if not self._eolmatch(f):
406 continue
406 continue
@@ -416,6 +416,6 b' def reposetup(ui, repo):'
416 if inconsistenteol(data):
416 if inconsistenteol(data):
417 raise errormod.Abort(_("inconsistent newline style "
417 raise errormod.Abort(_("inconsistent newline style "
418 "in %s\n") % f)
418 "in %s\n") % f)
419 return super(eolrepo, self).commitctx(ctx, error)
419 return super(eolrepo, self).commitctx(ctx, error, origctx)
420 repo.__class__ = eolrepo
420 repo.__class__ = eolrepo
421 repo._hgcleardirstate()
421 repo._hgcleardirstate()
@@ -785,8 +785,8 b' def reposetup(ui, repo):'
785 finally:
785 finally:
786 del self.commitctx
786 del self.commitctx
787
787
788 def kwcommitctx(self, ctx, error=False):
788 def kwcommitctx(self, ctx, error=False, origctx=None):
789 n = super(kwrepo, self).commitctx(ctx, error)
789 n = super(kwrepo, self).commitctx(ctx, error, origctx)
790 # no lock needed, only called from repo.commit() which already locks
790 # no lock needed, only called from repo.commit() which already locks
791 if not kwt.postcommit:
791 if not kwt.postcommit:
792 restrict = kwt.restrict
792 restrict = kwt.restrict
@@ -227,9 +227,9 b' def _reposetup(ui, repo):'
227
227
228 class lfsrepo(repo.__class__):
228 class lfsrepo(repo.__class__):
229 @localrepo.unfilteredmethod
229 @localrepo.unfilteredmethod
230 def commitctx(self, ctx, error=False):
230 def commitctx(self, ctx, error=False, origctx=None):
231 repo.svfs.options['lfstrack'] = _trackedmatcher(self)
231 repo.svfs.options['lfstrack'] = _trackedmatcher(self)
232 return super(lfsrepo, self).commitctx(ctx, error)
232 return super(lfsrepo, self).commitctx(ctx, error, origctx=origctx)
233
233
234 repo.__class__ = lfsrepo
234 repo.__class__ = lfsrepo
235
235
@@ -161,7 +161,7 b' def wraprepo(repo):'
161 **kwargs)
161 **kwargs)
162
162
163 @localrepo.unfilteredmethod
163 @localrepo.unfilteredmethod
164 def commitctx(self, ctx, error=False):
164 def commitctx(self, ctx, error=False, origctx=None):
165 """Add a new revision to current repository.
165 """Add a new revision to current repository.
166 Revision information is passed via the context argument.
166 Revision information is passed via the context argument.
167 """
167 """
@@ -179,7 +179,8 b' def wraprepo(repo):'
179 files.append((f, hex(fparent1)))
179 files.append((f, hex(fparent1)))
180 self.fileservice.prefetch(files)
180 self.fileservice.prefetch(files)
181 return super(shallowrepository, self).commitctx(ctx,
181 return super(shallowrepository, self).commitctx(ctx,
182 error=error)
182 error=error,
183 origctx=origctx)
183
184
184 def backgroundprefetch(self, revs, base=None, repack=False, pats=None,
185 def backgroundprefetch(self, revs, base=None, repack=False, pats=None,
185 opts=None):
186 opts=None):
@@ -291,6 +291,9 b" coreconfigitem('convert', 'hg.clonebranc"
291 coreconfigitem('convert', 'hg.ignoreerrors',
291 coreconfigitem('convert', 'hg.ignoreerrors',
292 default=False,
292 default=False,
293 )
293 )
294 coreconfigitem('convert', 'hg.preserve-hash',
295 default=False,
296 )
294 coreconfigitem('convert', 'hg.revs',
297 coreconfigitem('convert', 'hg.revs',
295 default=None,
298 default=None,
296 )
299 )
@@ -2578,7 +2578,7 b' class localrepository(object):'
2578 return ret
2578 return ret
2579
2579
2580 @unfilteredmethod
2580 @unfilteredmethod
2581 def commitctx(self, ctx, error=False):
2581 def commitctx(self, ctx, error=False, origctx=None):
2582 """Add a new revision to current repository.
2582 """Add a new revision to current repository.
2583 Revision information is passed via the context argument.
2583 Revision information is passed via the context argument.
2584
2584
@@ -2586,6 +2586,12 b' class localrepository(object):'
2586 modified/added/removed files. On merge, it may be wider than the
2586 modified/added/removed files. On merge, it may be wider than the
2587 ctx.files() to be committed, since any file nodes derived directly
2587 ctx.files() to be committed, since any file nodes derived directly
2588 from p1 or p2 are excluded from the committed ctx.files().
2588 from p1 or p2 are excluded from the committed ctx.files().
2589
2590 origctx is for convert to work around the problem that bug
2591 fixes to the files list in changesets change hashes. For
2592 convert to be the identity, it can pass an origctx and this
2593 function will use the same files list when it makes sense to
2594 do so.
2589 """
2595 """
2590
2596
2591 p1, p2 = ctx.p1(), ctx.p2()
2597 p1, p2 = ctx.p1(), ctx.p2()
@@ -2701,6 +2707,9 b' class localrepository(object):'
2701 filesadded = filesadded or None
2707 filesadded = filesadded or None
2702 filesremoved = filesremoved or None
2708 filesremoved = filesremoved or None
2703
2709
2710 if origctx and origctx.manifestnode() == mn:
2711 files = origctx.files()
2712
2704 # update changelog
2713 # update changelog
2705 self.ui.note(_("committing changelog\n"))
2714 self.ui.note(_("committing changelog\n"))
2706 self.changelog.delayupdate(tr)
2715 self.changelog.delayupdate(tr)
@@ -1656,7 +1656,7 b' class ilocalrepositorymain(interfaceutil'
1656 editor=False, extra=None):
1656 editor=False, extra=None):
1657 """Add a new revision to the repository."""
1657 """Add a new revision to the repository."""
1658
1658
1659 def commitctx(ctx, error=False):
1659 def commitctx(ctx, error=False, origctx=None):
1660 """Commit a commitctx instance to the repository."""
1660 """Commit a commitctx instance to the repository."""
1661
1661
1662 def destroying():
1662 def destroying():
@@ -917,13 +917,13 b' cases.'
917 > raise error.Abort(b'fail after finalization')
917 > raise error.Abort(b'fail after finalization')
918 > def reposetup(ui, repo):
918 > def reposetup(ui, repo):
919 > class failrepo(repo.__class__):
919 > class failrepo(repo.__class__):
920 > def commitctx(self, ctx, error=False):
920 > def commitctx(self, ctx, error=False, origctx=None):
921 > if self.ui.configbool(b'failafterfinalize', b'fail'):
921 > if self.ui.configbool(b'failafterfinalize', b'fail'):
922 > # 'sorted()' by ASCII code on category names causes
922 > # 'sorted()' by ASCII code on category names causes
923 > # invoking 'fail' after finalization of changelog
923 > # invoking 'fail' after finalization of changelog
924 > # using "'cl-%i' % id(self)" as category name
924 > # using "'cl-%i' % id(self)" as category name
925 > self.currenttransaction().addfinalize(b'zzzzzzzz', fail)
925 > self.currenttransaction().addfinalize(b'zzzzzzzz', fail)
926 > return super(failrepo, self).commitctx(ctx, error)
926 > return super(failrepo, self).commitctx(ctx, error, origctx)
927 > repo.__class__ = failrepo
927 > repo.__class__ = failrepo
928 > EOF
928 > EOF
929
929
@@ -373,6 +373,11 b''
373 records the given string as a 'convert_source' extra value
373 records the given string as a 'convert_source' extra value
374 on each commit made in the target repository. The default is
374 on each commit made in the target repository. The default is
375 None.
375 None.
376 convert.hg.preserve-hash
377 only works with mercurial sources. Make convert prevent
378 performance improvement to the list of modified files in
379 commits when such an improvement would cause the hash of a
380 commit to change. The default is False.
376
381
377 All Destinations
382 All Destinations
378 ################
383 ################
General Comments 0
You need to be logged in to leave comments. Login now