##// 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 439 :convert.hg.sourcename: records the given string as a 'convert_source' extra
440 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 447 All Destinations
443 448 ################
444 449
@@ -114,7 +114,7 b" SKIPREV = 'SKIP'"
114 114 class commit(object):
115 115 def __init__(self, author, date, desc, parents, branch=None, rev=None,
116 116 extra=None, sortkey=None, saverev=True, phase=phases.draft,
117 optparents=None):
117 optparents=None, ctx=None):
118 118 self.author = author or 'unknown'
119 119 self.date = date or '0 0'
120 120 self.desc = desc
@@ -126,6 +126,7 b' class commit(object):'
126 126 self.sortkey = sortkey
127 127 self.saverev = saverev
128 128 self.phase = phase
129 self.ctx = ctx # for hg to hg conversions
129 130
130 131 class converter_source(object):
131 132 """Conversion source interface"""
@@ -339,7 +339,11 b' class mercurial_sink(common.converter_si'
339 339 phases.phasenames[commit.phase], 'convert')
340 340
341 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 348 # If the node value has changed, but the phase is lower than
345 349 # draft, set it back to draft since it hasn't been exposed
@@ -591,7 +595,8 b' class mercurial_source(common.converter_'
591 595 extra=ctx.extra(),
592 596 sortkey=ctx.rev(),
593 597 saverev=self.saverev,
594 phase=ctx.phase())
598 phase=ctx.phase(),
599 ctx=ctx)
595 600
596 601 def numcommits(self):
597 602 return len(self.repo)
@@ -400,7 +400,7 b' def reposetup(ui, repo):'
400 400 if wlock is not None:
401 401 wlock.release()
402 402
403 def commitctx(self, ctx, error=False):
403 def commitctx(self, ctx, error=False, origctx=None):
404 404 for f in sorted(ctx.added() + ctx.modified()):
405 405 if not self._eolmatch(f):
406 406 continue
@@ -416,6 +416,6 b' def reposetup(ui, repo):'
416 416 if inconsistenteol(data):
417 417 raise errormod.Abort(_("inconsistent newline style "
418 418 "in %s\n") % f)
419 return super(eolrepo, self).commitctx(ctx, error)
419 return super(eolrepo, self).commitctx(ctx, error, origctx)
420 420 repo.__class__ = eolrepo
421 421 repo._hgcleardirstate()
@@ -785,8 +785,8 b' def reposetup(ui, repo):'
785 785 finally:
786 786 del self.commitctx
787 787
788 def kwcommitctx(self, ctx, error=False):
789 n = super(kwrepo, self).commitctx(ctx, error)
788 def kwcommitctx(self, ctx, error=False, origctx=None):
789 n = super(kwrepo, self).commitctx(ctx, error, origctx)
790 790 # no lock needed, only called from repo.commit() which already locks
791 791 if not kwt.postcommit:
792 792 restrict = kwt.restrict
@@ -227,9 +227,9 b' def _reposetup(ui, repo):'
227 227
228 228 class lfsrepo(repo.__class__):
229 229 @localrepo.unfilteredmethod
230 def commitctx(self, ctx, error=False):
230 def commitctx(self, ctx, error=False, origctx=None):
231 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 234 repo.__class__ = lfsrepo
235 235
@@ -161,7 +161,7 b' def wraprepo(repo):'
161 161 **kwargs)
162 162
163 163 @localrepo.unfilteredmethod
164 def commitctx(self, ctx, error=False):
164 def commitctx(self, ctx, error=False, origctx=None):
165 165 """Add a new revision to current repository.
166 166 Revision information is passed via the context argument.
167 167 """
@@ -179,7 +179,8 b' def wraprepo(repo):'
179 179 files.append((f, hex(fparent1)))
180 180 self.fileservice.prefetch(files)
181 181 return super(shallowrepository, self).commitctx(ctx,
182 error=error)
182 error=error,
183 origctx=origctx)
183 184
184 185 def backgroundprefetch(self, revs, base=None, repack=False, pats=None,
185 186 opts=None):
@@ -291,6 +291,9 b" coreconfigitem('convert', 'hg.clonebranc"
291 291 coreconfigitem('convert', 'hg.ignoreerrors',
292 292 default=False,
293 293 )
294 coreconfigitem('convert', 'hg.preserve-hash',
295 default=False,
296 )
294 297 coreconfigitem('convert', 'hg.revs',
295 298 default=None,
296 299 )
@@ -2578,7 +2578,7 b' class localrepository(object):'
2578 2578 return ret
2579 2579
2580 2580 @unfilteredmethod
2581 def commitctx(self, ctx, error=False):
2581 def commitctx(self, ctx, error=False, origctx=None):
2582 2582 """Add a new revision to current repository.
2583 2583 Revision information is passed via the context argument.
2584 2584
@@ -2586,6 +2586,12 b' class localrepository(object):'
2586 2586 modified/added/removed files. On merge, it may be wider than the
2587 2587 ctx.files() to be committed, since any file nodes derived directly
2588 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 2597 p1, p2 = ctx.p1(), ctx.p2()
@@ -2701,6 +2707,9 b' class localrepository(object):'
2701 2707 filesadded = filesadded or None
2702 2708 filesremoved = filesremoved or None
2703 2709
2710 if origctx and origctx.manifestnode() == mn:
2711 files = origctx.files()
2712
2704 2713 # update changelog
2705 2714 self.ui.note(_("committing changelog\n"))
2706 2715 self.changelog.delayupdate(tr)
@@ -1656,7 +1656,7 b' class ilocalrepositorymain(interfaceutil'
1656 1656 editor=False, extra=None):
1657 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 1660 """Commit a commitctx instance to the repository."""
1661 1661
1662 1662 def destroying():
@@ -917,13 +917,13 b' cases.'
917 917 > raise error.Abort(b'fail after finalization')
918 918 > def reposetup(ui, repo):
919 919 > class failrepo(repo.__class__):
920 > def commitctx(self, ctx, error=False):
920 > def commitctx(self, ctx, error=False, origctx=None):
921 921 > if self.ui.configbool(b'failafterfinalize', b'fail'):
922 922 > # 'sorted()' by ASCII code on category names causes
923 923 > # invoking 'fail' after finalization of changelog
924 924 > # using "'cl-%i' % id(self)" as category name
925 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 927 > repo.__class__ = failrepo
928 928 > EOF
929 929
@@ -373,6 +373,11 b''
373 373 records the given string as a 'convert_source' extra value
374 374 on each commit made in the target repository. The default is
375 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 382 All Destinations
378 383 ################
General Comments 0
You need to be logged in to leave comments. Login now