D4287: overlayworkingctx: fix exception in metadata-only inmemory merges (issue5960)
phillco accepted this revision. phillco added a comment. lgtm REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4287 To: spectral, phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2924: rebase: rename conclude[memory]node() to commit[memory]node()
phillco added a comment. What _is_ the difference between "conclude" and "commit"? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2924 To: martinvonz, phillco, #hg-reviewers, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2701: merge: use constants for actions
phillco added subscribers: sid0, quark. phillco added a comment. btw, @quark mentioned there could be a perf hit (@sid0 mentioned this too a long time ago iirc) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2701 To: indygreg, #hg-reviewers, phillco Cc: quark, sid0, phillco, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2701: merge: use constants for actions
phillco added inline comments. INLINE COMMENTS > indygreg wrote in merge.py:909 > Done. > > What's... amusing is that ``dr`` and ``rd`` are not actions in the current > code base. lol REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2701 To: indygreg, #hg-reviewers, phillco Cc: phillco, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2701: merge: use constants for actions
phillco added inline comments. INLINE COMMENTS > merge.py:909 > if actions: > # k, dr, e and rd are no-op > +for m in (ACTION_ADD, ACTION_ADD_MODIFIED, ACTION_FORGET, ACTION_GET, Update this too? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2701 To: indygreg, #hg-reviewers, phillco Cc: phillco, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2701: merge: use constants for actions
phillco accepted this revision. phillco added a comment. Strong +1 REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2701 To: indygreg, #hg-reviewers, phillco Cc: phillco, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1934: convert: use a collections.deque
phillco accepted this revision. phillco added a comment. Nice. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1934 To: indygreg, #hg-reviewers, phillco Cc: phillco, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1782: rebase: don't run IMM if running rebase in a transaction
This revision was automatically updated to reflect the committed changes. Closed by commit rHGc5d220a621e7: rebase: dont run IMM if running rebase in a transaction (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1782?vs=4648=4869 REVISION DETAIL https://phab.mercurial-scm.org/D1782 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -771,8 +771,11 @@ """ inmemory = ui.configbool('rebase', 'experimental.inmemory') -if opts.get('continue') or opts.get('abort'): +if (opts.get('continue') or opts.get('abort') or +repo.currenttransaction() is not None): # in-memory rebase is not compatible with resuming rebases. +# (Or if it is run within a transaction, since the restart logic can +# fail the entire transaction.) inmemory = False if inmemory: To: phillco, #hg-reviewers, quark Cc: quark, mercurial-devel, sid0 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1807: filemerge: only write in-memory backup during premerge
This revision was automatically updated to reflect the committed changes. Closed by commit rHG9a50ffd15b25: filemerge: only write in-memory backup during premerge (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1807?vs=4700=4871 REVISION DETAIL https://phab.mercurial-scm.org/D1807 AFFECTED FILES mercurial/filemerge.py CHANGE DETAILS diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -636,7 +636,8 @@ # merging in-memory, we must redirect the backup to the memory context # so we don't disturb the working directory. relpath = back[len(repo.wvfs.base) + 1:] -wctx[relpath].write(fcd.data(), fcd.flags()) +if premerge: +wctx[relpath].write(fcd.data(), fcd.flags()) return wctx[relpath] else: if premerge: To: phillco, #hg-reviewers, durham Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1806: filemerge: fix backing up an in-memory file to a custom location
This revision was automatically updated to reflect the committed changes. Closed by commit rHGc0439e11af16: filemerge: fix backing up an in-memory file to a custom location (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1806?vs=4699=4870 REVISION DETAIL https://phab.mercurial-scm.org/D1806 AFFECTED FILES mercurial/filemerge.py CHANGE DETAILS diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -618,6 +618,9 @@ (if any), the backup is used to undo certain premerges, confirm whether a merge changed anything, and determine what line endings the new file should have. + +Backups only need to be written once (right before the premerge) since their +content doesn't change afterwards. """ if fcd.isabsent(): return None @@ -628,21 +631,25 @@ back = scmutil.origpath(ui, repo, a) inworkingdir = (back.startswith(repo.wvfs.base) and not back.startswith(repo.vfs.base)) - if isinstance(fcd, context.overlayworkingfilectx) and inworkingdir: # If the backup file is to be in the working directory, and we're # merging in-memory, we must redirect the backup to the memory context # so we don't disturb the working directory. relpath = back[len(repo.wvfs.base) + 1:] wctx[relpath].write(fcd.data(), fcd.flags()) return wctx[relpath] else: -# Otherwise, write to wherever the user specified the backups should go. -# +if premerge: +# Otherwise, write to wherever path the user specified the backups +# should go. We still need to switch based on whether the source is +# in-memory so we can use the fast path of ``util.copy`` if both are +# on disk. +if isinstance(fcd, context.overlayworkingfilectx): +util.writefile(back, fcd.data()) +else: +util.copyfile(a, back) # A arbitraryfilectx is returned, so we can run the same functions on # the backup context regardless of where it lives. -if premerge: -util.copyfile(a, back) return context.arbitraryfilectx(back, repo=repo) def _maketempfiles(repo, fco, fca): To: phillco, #hg-reviewers, durham Cc: durham, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1815: merge: only abort in IMM if files are actually marked as driver-resolved
phillco updated this revision to Diff 4713. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1815?vs=4711=4713 REVISION DETAIL https://phab.mercurial-scm.org/D1815 AFFECTED FILES mercurial/merge.py CHANGE DETAILS diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -1556,11 +1556,9 @@ usemergedriver = not overwrite and mergeactions and ms.mergedriver if usemergedriver: -if wctx.isinmemory(): -raise error.InMemoryMergeConflictsError("in-memory merge does not " -"support mergedriver") ms.commit() proceed = driverpreprocess(repo, ms, wctx, labels=labels) +drivverresolved = [f for f in ms.driverresolved()] # Note which files were marked as driver-resolved but not matched by # experimental.inmemorydisallowedpaths. This will allow us to keep @@ -1573,9 +1571,18 @@ if not pathsconfig: pathsconfig = ".^" regex = util.re.compile(pathsconfig) -unmatched = [f for f in ms.driverresolved() if not regex.match(f)] +unmatched = [f for f in drivverresolved if not regex.match(f)] repo.ui.log('imm_mergedriver', '', -driver_resolved_missed="|".join(sorted(unmatched))) +driver_resolved_missed="|".join(sorted(unmatched)), +in_memory=wctx.isinmemory()) + +# If preprocess() marked any files as driver-resolved and we're merging +# in-memory, abort on the assumption that driver scripts require the +# working directory. +if drivverresolved and wctx.isinmemory(): +errorstr = ("some of your files require mergedriver to run, which " + "in-memory merge does not support") +raise error.InMemoryMergeConflictsError(errorstr) # the driver might leave some files unresolved unresolvedf = set(ms.unresolved()) To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1814: rebase: add experimental.inmemory.nomergedriver to turn off IMM
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This gives us an easy way to ensure IMM is disabled automatically if the user configures a mergedriver script. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1814 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -799,6 +799,19 @@ elif repo.currenttransaction() is not None: whynotimm = "rebase run inside a transaction" +# in-memory rebase can be configured not to run if a mergedriver is +# configured; this should be used only if the driver's preprocess() +# scripts might use the working copy. +# +# (Note: Even without this config, IMM will still abort if any files are +# marked by preprocess() to be driver-resolved; however, sometimes the +# preprocess() function itself can't be trusted.) +# +# TODO(phillco): Replace with decorators on the scripts themselves +elif (ui.config('experimental', 'mergedriver') and + ui.configbool('rebase', 'experimental.inmemory.nomergedriver')): +whynotimm = 'mergedriver enabled' + if whynotimm: ui.log("rebase", "disabling IMM because: %s" % whynotimm, why_not_imm=whynotimm) To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1815: merge: only abort in IMM if files are actually marked as driver-resolved
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Before, we would raise whenever the `usemergedriver` condition was set when merging in-memory, which equated to "any merge with (cd, dc, or m) actions in a repo with a mergedriver script". This was done to be as conservative as possible. However, a better solution is to run the preprocess() script and only raise if any files are marked to actually be driver-resolved. That way we only restart the merge if we absolutely need to. Since some of our preprocess() scripts aren't ready yet, I also added experimental.inmemory.nomergedriver in a previous change so we can deploy this in a build before the preprocess scripts are good to go. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1815 AFFECTED FILES mercurial/merge.py CHANGE DETAILS diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -1556,11 +1556,9 @@ usemergedriver = not overwrite and mergeactions and ms.mergedriver if usemergedriver: -if wctx.isinmemory(): -raise error.InMemoryMergeConflictsError("in-memory merge does not " -"support mergedriver") ms.commit() proceed = driverpreprocess(repo, ms, wctx, labels=labels) +drivverresolved = [f for f in ms.driverresolved()] # Note which files were marked as driver-resolved but not matched by # experimental.inmemorydisallowedpaths. This will allow us to keep @@ -1573,9 +1571,17 @@ if not pathsconfig: pathsconfig = ".^" regex = util.re.compile(pathsconfig) -unmatched = [f for f in ms.driverresolved() if not regex.match(f)] +unmatched = [f for f in drivverresolved if not regex.match(f)] repo.ui.log('imm_mergedriver', '', -driver_resolved_missed="|".join(sorted(unmatched))) +driver_resolved_missed="|".join(sorted(unmatched)), +in_memory=wctx.isinmemory()) + +# If preprocess() marked any files as driver-resolved and we're merging +# in-memory, abort on the assumption that driver scripts require the +# working directory. +if drivverresolved and wctx.isinmemory(): +raise error.InMemoryMergeConflictsError("in-memory merge does not " +"support mergedriver") # the driver might leave some files unresolved unresolvedf = set(ms.unresolved()) To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1807: filemerge: only write in-memory backup during premerge
phillco updated this revision to Diff 4700. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1807?vs=4698=4700 REVISION DETAIL https://phab.mercurial-scm.org/D1807 AFFECTED FILES mercurial/filemerge.py CHANGE DETAILS diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -636,7 +636,8 @@ # merging in-memory, we must redirect the backup to the memory context # so we don't disturb the working directory. relpath = back[len(repo.wvfs.base) + 1:] -wctx[relpath].write(fcd.data(), fcd.flags()) +if premerge: +wctx[relpath].write(fcd.data(), fcd.flags()) return wctx[relpath] else: if premerge: To: phillco, #hg-reviewers, durham Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1806: filemerge: fix backing up an in-memory file to a custom location
phillco updated this revision to Diff 4699. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1806?vs=4697=4699 REVISION DETAIL https://phab.mercurial-scm.org/D1806 AFFECTED FILES mercurial/filemerge.py CHANGE DETAILS diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -618,6 +618,9 @@ (if any), the backup is used to undo certain premerges, confirm whether a merge changed anything, and determine what line endings the new file should have. + +Backups only need to be written once (right before the premerge) since their +content doesn't change afterwards. """ if fcd.isabsent(): return None @@ -628,21 +631,25 @@ back = scmutil.origpath(ui, repo, a) inworkingdir = (back.startswith(repo.wvfs.base) and not back.startswith(repo.vfs.base)) - if isinstance(fcd, context.overlayworkingfilectx) and inworkingdir: # If the backup file is to be in the working directory, and we're # merging in-memory, we must redirect the backup to the memory context # so we don't disturb the working directory. relpath = back[len(repo.wvfs.base) + 1:] wctx[relpath].write(fcd.data(), fcd.flags()) return wctx[relpath] else: -# Otherwise, write to wherever the user specified the backups should go. -# +if premerge: +# Otherwise, write to wherever path the user specified the backups +# should go. We still need to switch based on whether the source is +# in-memory so we can use the fast path of ``util.copy`` if both are +# on disk. +if isinstance(fcd, context.overlayworkingfilectx): +util.writefile(back, fcd.data()) +else: +util.copyfile(a, back) # A arbitraryfilectx is returned, so we can run the same functions on # the backup context regardless of where it lives. -if premerge: -util.copyfile(a, back) return context.arbitraryfilectx(back, repo=repo) def _maketempfiles(repo, fco, fca): To: phillco, #hg-reviewers, durham Cc: durham, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1806: filemerge: fix backing up an in-memory file to a custom location
phillco updated this revision to Diff 4697. phillco edited the summary of this revision. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1806?vs=4688=4697 REVISION DETAIL https://phab.mercurial-scm.org/D1806 AFFECTED FILES mercurial/filemerge.py CHANGE DETAILS diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -618,7 +618,10 @@ (if any), the backup is used to undo certain premerges, confirm whether a merge changed anything, and determine what line endings the new file should have. -""" + +Backups only need to be written once (right before the premerge) since their +content doesn't change afterwards. +s""" if fcd.isabsent(): return None # TODO: Break this import cycle somehow. (filectx -> ctx -> fileset -> @@ -628,21 +631,25 @@ back = scmutil.origpath(ui, repo, a) inworkingdir = (back.startswith(repo.wvfs.base) and not back.startswith(repo.vfs.base)) - if isinstance(fcd, context.overlayworkingfilectx) and inworkingdir: # If the backup file is to be in the working directory, and we're # merging in-memory, we must redirect the backup to the memory context # so we don't disturb the working directory. relpath = back[len(repo.wvfs.base) + 1:] wctx[relpath].write(fcd.data(), fcd.flags()) return wctx[relpath] else: -# Otherwise, write to wherever the user specified the backups should go. -# +if premerge: +# Otherwise, write to wherever path the user specified the backups +# should go. We still need to switch based on whether the source is +# in-memory so we can use the fast path of ``util.copy`` if both are +# on disk. +if isinstance(fcd, context.overlayworkingfilectx): +util.writefile(back, fcd.data()) +else: +util.copyfile(a, back) # A arbitraryfilectx is returned, so we can run the same functions on # the backup context regardless of where it lives. -if premerge: -util.copyfile(a, back) return context.arbitraryfilectx(back, repo=repo) def _maketempfiles(repo, fco, fca): To: phillco, #hg-reviewers, durham Cc: durham, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1807: filemerge: only write in-memory backup during premerge
phillco updated this revision to Diff 4698. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1807?vs=4689=4698 REVISION DETAIL https://phab.mercurial-scm.org/D1807 AFFECTED FILES mercurial/filemerge.py CHANGE DETAILS diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -636,7 +636,8 @@ # merging in-memory, we must redirect the backup to the memory context # so we don't disturb the working directory. relpath = back[len(repo.wvfs.base) + 1:] -wctx[relpath].write(fcd.data(), fcd.flags()) +if premerge: +wctx[relpath].write(fcd.data(), fcd.flags()) return wctx[relpath] else: if premerge: To: phillco, #hg-reviewers, durham Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1806: filemerge: fix backing up an in-memory file to a custom location
phillco added a comment. > Should we even be calling _makebackup in the case of an inmemory merge? Like, maybe the makebackup should be conditional based on if the source file context is actually a workingctx? The merge process itself uses the backup, it's not just for the user. INLINE COMMENTS > durham wrote in filemerge.py:623 > I know you're just documenting the parameter that already existed, but might > be nice to explain why this is (if you happen to know why right now). I think I can REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1806 To: phillco, #hg-reviewers, durham Cc: durham, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1806: filemerge: fix backing up an in-memory file to a custom location
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY If the user specifies a ui.origbackuppath, we used to always copy the file there, but if the source file is in memory we must write it instead of copying. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1806 AFFECTED FILES mercurial/filemerge.py CHANGE DETAILS diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -618,6 +618,9 @@ (if any), the backup is used to undo certain premerges, confirm whether a merge changed anything, and determine what line endings the new file should have. + +Backups are only need to be written for the premerge, and not again during +the main merge. """ if fcd.isabsent(): return None @@ -628,21 +631,25 @@ back = scmutil.origpath(ui, repo, a) inworkingdir = (back.startswith(repo.wvfs.base) and not back.startswith(repo.vfs.base)) - if isinstance(fcd, context.overlayworkingfilectx) and inworkingdir: # If the backup file is to be in the working directory, and we're # merging in-memory, we must redirect the backup to the memory context # so we don't disturb the working directory. relpath = back[len(repo.wvfs.base) + 1:] wctx[relpath].write(fcd.data(), fcd.flags()) return wctx[relpath] else: -# Otherwise, write to wherever the user specified the backups should go. -# +if premerge: +# Otherwise, write to wherever path the user specified the backups +# should go. We still need to switch based on whether the source is +# in-memory so we can use the fast path of ``util.copy`` if both are +# on disk. +if isinstance(fcd, context.overlayworkingfilectx): +util.writefile(back, fcd.data()) +else: +util.copyfile(a, back) # A arbitraryfilectx is returned, so we can run the same functions on # the backup context regardless of where it lives. -if premerge: -util.copyfile(a, back) return context.arbitraryfilectx(back, repo=repo) def _maketempfiles(repo, fco, fca): To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1807: filemerge: only write in-memory backup during premerge
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This wasn't broken, but should mirror the non-in memory case to save an extra write. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1807 AFFECTED FILES mercurial/filemerge.py CHANGE DETAILS diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -636,7 +636,8 @@ # merging in-memory, we must redirect the backup to the memory context # so we don't disturb the working directory. relpath = back[len(repo.wvfs.base) + 1:] -wctx[relpath].write(fcd.data(), fcd.flags()) +if premerge: +wctx[relpath].write(fcd.data(), fcd.flags()) return wctx[relpath] else: if premerge: To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1782: rebase: don't run IMM if running rebase in a transaction
phillco updated this revision to Diff 4648. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1782?vs=4647=4648 REVISION DETAIL https://phab.mercurial-scm.org/D1782 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -779,8 +779,11 @@ """ inmemory = ui.configbool('rebase', 'experimental.inmemory') -if opts.get('continue') or opts.get('abort'): +if (opts.get('continue') or opts.get('abort') or +repo.currenttransaction() is not None): # in-memory rebase is not compatible with resuming rebases. +# (Or if it is run within a transaction, since the restart logic can +# fail the entire transaction.) inmemory = False if inmemory: To: phillco, #hg-reviewers, quark Cc: quark, mercurial-devel, sid0 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1782: rebase: don't run IMM if running rebase in a transaction
phillco updated this revision to Diff 4647. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1782?vs=4645=4647 REVISION DETAIL https://phab.mercurial-scm.org/D1782 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -779,8 +779,11 @@ """ inmemory = ui.configbool('rebase', 'experimental.inmemory') -if opts.get('continue') or opts.get('abort'): +if (opts.get('continue') or opts.get('abort') or +repo.currenttransaction() is not None): # in-memory rebase is not compatible with resuming rebases. +# (Or if it is run within a transaction, since the restart logic can +# fail the entire transaction.) inmemory = False if inmemory: To: phillco, #hg-reviewers, quark Cc: quark, mercurial-devel, sid0 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1781: merge: raise before running mergedriver if using IMM
This revision was automatically updated to reflect the committed changes. Closed by commit rHG87918218da70: merge: raise before running mergedriver if using IMM (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1781?vs=4643=4646 REVISION DETAIL https://phab.mercurial-scm.org/D1781 AFFECTED FILES mercurial/merge.py CHANGE DETAILS diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -1556,6 +1556,9 @@ usemergedriver = not overwrite and mergeactions and ms.mergedriver if usemergedriver: +if wctx.isinmemory(): +raise error.InMemoryMergeConflictsError("in-memory merge does not " +"support mergedriver") ms.commit() proceed = driverpreprocess(repo, ms, wctx, labels=labels) # the driver might leave some files unresolved To: phillco, #hg-reviewers, quark, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1782: rebase: don't run IMM if running rebase in a transaction
phillco updated this revision to Diff 4645. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1782?vs=4644=4645 REVISION DETAIL https://phab.mercurial-scm.org/D1782 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -779,8 +779,11 @@ """ inmemory = ui.configbool('rebase', 'experimental.inmemory') -if opts.get('continue') or opts.get('abort'): +if (opts.get('continue') or opts.get('abort') or +repo.currenttransaction() is not None): # in-memory rebase is not compatible with resuming rebases. +# (Or if it is run within a transaction, since the restart logic can +# fail the entire transaction.) inmemory = False if inmemory: To: phillco, #hg-reviewers, quark Cc: quark, mercurial-devel, sid0 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1782: rebase: don't run IMM if running rebase in a transaction
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Some callers to rebase.rebase(), like `_moverelative` in `fbamend/movement.py`, wrap the entire rebase call in a transaction. This raises havoc when IMM tries to retry the rebase when it hits merge conflicts, because the abort will fail the whole transaction, not the subset. It also fails at the end, losing any conflict resolution, as @sid0 noticed. The right long-term fix that @quark and I have discussed is to change the restarting logic such that it doesn't abort at all, but simply switches between IMM and non-IMM fluidly for each commit, which has other nice properties. In the meantime this will do for now. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1782 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -779,8 +779,11 @@ """ inmemory = ui.configbool('rebase', 'experimental.inmemory') -if opts.get('continue') or opts.get('abort'): +if (opts.get('continue') or opts.get('abort') or +repo.currenttransaction() is None): # in-memory rebase is not compatible with resuming rebases. +# (Or if it is run within a transaction, since the restart logic can +# fail the entire transaction.) inmemory = False if inmemory: To: phillco, #hg-reviewers Cc: quark, mercurial-devel, sid0 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1781: merge: raise before running mergedriver if using IMM
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1781 AFFECTED FILES mercurial/merge.py CHANGE DETAILS diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -1556,6 +1556,9 @@ usemergedriver = not overwrite and mergeactions and ms.mergedriver if usemergedriver: +if wctx.isinmemory(): +raise error.InMemoryMergeConflictsError("in-memory merge does not " +"support mergedriver") ms.commit() proceed = driverpreprocess(repo, ms, wctx, labels=labels) # the driver might leave some files unresolved To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1748: rebase: switch ui.log calls to common style
This revision was automatically updated to reflect the committed changes. Closed by commit rHGbf556bd2f589: rebase: switch ui.log calls to common style (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1748?vs=4586=4598 REVISION DETAIL https://phab.mercurial-scm.org/D1748 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -390,9 +390,7 @@ else: self.wctx = self.repo[None] self.repo.ui.debug("rebasing on disk\n") -self.repo.ui.log("rebase", "", { -'rebase_imm_used': self.wctx.isinmemory() -}) +self.repo.ui.log("rebase", "", rebase_imm_used=self.wctx.isinmemory()) def _performrebase(self, tr): self._assignworkingcopy() @@ -966,7 +964,7 @@ # stacks that include the WCP. However, I'm not yet sure where the cutoff # is. rebasingwcp = repo['.'].rev() in rebaseset -ui.log("rebase", "", {'rebase_rebasing_wcp': rebasingwcp}) +ui.log("rebase", "", rebase_rebasing_wcp=rebasingwcp) if rbsrt.inmemory and rebasingwcp: rbsrt.inmemory = False # Check these since we did not before. To: phillco, #hg-reviewers, quark, yuja Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1751: histedit: add ui.log for action count
This revision was automatically updated to reflect the committed changes. Closed by commit rHG784a85c87c22: histedit: add ui.log for action count (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1751?vs=4590=4601 REVISION DETAIL https://phab.mercurial-scm.org/D1751 AFFECTED FILES hgext/histedit.py CHANGE DETAILS diff --git a/hgext/histedit.py b/hgext/histedit.py --- a/hgext/histedit.py +++ b/hgext/histedit.py @@ -1310,6 +1310,9 @@ state.topmost = topmost state.replacements = [] +ui.log("histedit", "%d actions to histedit", len(actions), + histedit_num_actions=len(actions)) + # Create a backup so we can always abort completely. backupfile = None if not obsolete.isenabled(repo, obsolete.createmarkersopt): To: phillco, durin42, #hg-reviewers, quark, yuja Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1751: histedit: add ui.log for action count
phillco updated this revision to Diff 4590. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1751?vs=4589=4590 REVISION DETAIL https://phab.mercurial-scm.org/D1751 AFFECTED FILES hgext/histedit.py CHANGE DETAILS diff --git a/hgext/histedit.py b/hgext/histedit.py --- a/hgext/histedit.py +++ b/hgext/histedit.py @@ -1310,6 +1310,9 @@ state.topmost = topmost state.replacements = [] +ui.log("histedit", "%d actions to histedit", len(actions), + histedit_num_actions=len(actions)) + # Create a backup so we can always abort completely. backupfile = None if not obsolete.isenabled(repo, obsolete.createmarkersopt): To: phillco, durin42, #hg-reviewers, quark Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1751: histedit: add ui.log for action count
phillco created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1751 AFFECTED FILES hgext/histedit.py CHANGE DETAILS diff --git a/hgext/histedit.py b/hgext/histedit.py --- a/hgext/histedit.py +++ b/hgext/histedit.py @@ -1310,6 +1310,9 @@ state.topmost = topmost state.replacements = [] +ui.log("histedit", "%d actions to histedit", len(actions), +histedit_num_actions=len(actions)) + # Create a backup so we can always abort completely. backupfile = None if not obsolete.isenabled(repo, obsolete.createmarkersopt): To: phillco, durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1748: rebase: switch ui.log calls to common style
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The old style raised errors in some cases. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1748 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -390,9 +390,7 @@ else: self.wctx = self.repo[None] self.repo.ui.debug("rebasing on disk\n") -self.repo.ui.log("rebase", "", { -'rebase_imm_used': self.wctx.isinmemory() -}) +self.repo.ui.log("rebase", "", rebase_imm_used=self.wctx.isinmemory()) def _performrebase(self, tr): self._assignworkingcopy() @@ -960,7 +958,7 @@ # stacks that include the WCP. However, I'm not yet sure where the cutoff # is. rebasingwcp = repo['.'].rev() in rebaseset -ui.log("rebase", "", {'rebase_rebasing_wcp': rebasingwcp}) +ui.log("rebase", "", rebase_rebasing_wcp=rebasingwcp) if rbsrt.inmemory and rebasingwcp: rbsrt.inmemory = False # Check these since we did not before. To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1745: rebase: don't take out a dirstate guard for in-memory rebase
This revision was automatically updated to reflect the committed changes. Closed by commit rHG01b084914a60: rebase: dont take out a dirstate guard for in-memory rebase (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1745?vs=4579=4580 REVISION DETAIL https://phab.mercurial-scm.org/D1745 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -567,8 +567,6 @@ revtoreuse = max(self.state) dsguard = None -if ui.configbool('rebase', 'singletransaction'): -dsguard = dirstateguard.dirstateguard(repo, 'rebase') if self.inmemory: newnode = concludememorynode(repo, revtoreuse, p1, self.external, @@ -578,6 +576,8 @@ keepbranches=self.keepbranchesf, date=self.date, wctx=self.wctx) else: +if ui.configbool('rebase', 'singletransaction'): +dsguard = dirstateguard.dirstateguard(repo, 'rebase') with util.acceptintervention(dsguard): newnode = concludenode(repo, revtoreuse, p1, self.external, commitmsg=commitmsg, @@ -851,8 +851,14 @@ singletr = ui.configbool('rebase', 'singletransaction') if singletr: tr = repo.transaction('rebase') + +# If `rebase.singletransaction` is enabled, wrap the entire operation in +# one transaction here. Otherwise, transactions are obtained when +# committing each node, which is slower but allows partial success. with util.acceptintervention(tr): -if singletr: +# Same logic for the dirstate guard, except we don't create one when +# rebasing in-memory (it's not needed). +if singletr and not inmemory: dsguard = dirstateguard.dirstateguard(repo, 'rebase') with util.acceptintervention(dsguard): rbsrt._performrebase(tr) @@ -1032,8 +1038,8 @@ def concludememorynode(repo, rev, p1, p2, wctx=None, commitmsg=None, editor=None, extrafn=None, keepbranches=False, date=None): -'''Commit the wd changes with parents p1 and p2. Reuse commit info from rev -but also store useful information in extra. +'''Commit the memory changes with parents p1 and p2. Reuse commit info from +rev but also store useful information in extra. Return node of committed revision.''' ctx = repo[rev] if commitmsg is None: To: phillco, #hg-reviewers, krbullock Cc: krbullock, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1739: filemerge: only raise InMemoryMergeConflictsError when running _xmerge
This revision was automatically updated to reflect the committed changes. Closed by commit rHGef7e667a4f7b: filemerge: only raise InMemoryMergeConflictsError when running _xmerge (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1739?vs=4567=4572 REVISION DETAIL https://phab.mercurial-scm.org/D1739 AFFECTED FILES mercurial/filemerge.py CHANGE DETAILS diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -490,6 +490,18 @@ return _idump(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=labels) +def _xmergeimm(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): +# In-memory merge simply raises an exception on all external merge tools, +# for now. +# +# It would be possible to run most tools with temporary files, but this +# raises the question of what to do if the user only partially resolves the +# file -- we can't leave a merge state. (Copy to somewhere in the .hg/ +# directory and tell the user how to get it is my best idea, but it's +# clunky.) +raise error.InMemoryMergeConflictsError('in-memory merge does not support ' +'external merge tools') + def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): tool, toolpath, binary, symlink = toolconf if fcd.isabsent() or fco.isabsent(): @@ -688,16 +700,14 @@ onfailure = func.onfailure precheck = func.precheck else: -func = _xmerge +if wctx.isinmemory(): +func = _xmergeimm +else: +func = _xmerge mergetype = fullmerge onfailure = _("merging %s failed!\n") precheck = None -if wctx.isinmemory(): -raise error.InMemoryMergeConflictsError('in-memory merge does not ' -'support external merge ' -'tools') - toolconf = tool, toolpath, binary, symlink if mergetype == nomerge: To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1739: filemerge: only raise InMemoryMergeConflictsError when running _xmerge
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The old code here was overly broad and would raise in cases when we didn't end up calling `xmerge` and resolved using an internal tool (such as when `premerge=True`). Instead, let's swap out _xmerge if IMM is enabled and have the new tool raise when called, which is the behavior we want. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1739 AFFECTED FILES mercurial/filemerge.py CHANGE DETAILS diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py --- a/mercurial/filemerge.py +++ b/mercurial/filemerge.py @@ -490,6 +490,18 @@ return _idump(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=labels) +def _xmergeimm(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): +# In-memory merge simply raises an exception on all external merge tools, +# for now. +# +# It would be possible to run most tools with temporary files, but this +# raises the question of what to do if the user only partially resolves the +# file -- we can't leave a merge state. (Copy to somewhere in the .hg/ +# directory and tell the user how to get it is my best idea, but it's +# clunky.) +raise error.InMemoryMergeConflictsError('in-memory merge does not support ' +'external merge tools') + def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): tool, toolpath, binary, symlink = toolconf if fcd.isabsent() or fco.isabsent(): @@ -688,16 +700,14 @@ onfailure = func.onfailure precheck = func.precheck else: -func = _xmerge +if wctx.isinmemory(): +func = _xmergeimm +else: +func = _xmerge mergetype = fullmerge onfailure = _("merging %s failed!\n") precheck = None -if wctx.isinmemory(): -raise error.InMemoryMergeConflictsError('in-memory merge does not ' -'support external merge ' -'tools') - toolconf = tool, toolpath, binary, symlink if mergetype == nomerge: To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1681: rebase: add ui.log calls for whether IMM used, whether rebasing WCP
This revision was automatically updated to reflect the committed changes. Closed by commit rHG464b3e5e3eec: rebase: add ui.log calls for whether IMM used, whether rebasing WCP (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1681?vs=4426=4490 REVISION DETAIL https://phab.mercurial-scm.org/D1681 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -390,6 +390,9 @@ else: self.wctx = self.repo[None] self.repo.ui.debug("rebasing on disk\n") +self.repo.ui.log("rebase", "", { +'rebase_imm_used': self.wctx.isinmemory() +}) def _performrebase(self, tr): self._assignworkingcopy() @@ -957,6 +960,7 @@ # stacks that include the WCP. However, I'm not yet sure where the cutoff # is. rebasingwcp = repo['.'].rev() in rebaseset +ui.log("rebase", "", {'rebase_rebasing_wcp': rebasingwcp}) if rbsrt.inmemory and rebasingwcp: rbsrt.inmemory = False # Check these since we did not before. To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1679: rebase: fix for hgsubversion
phillco added a comment. @yuja is that just because of the `_manifest` property cache, or are there others as well? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1679 To: phillco, #hg-reviewers, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1679: rebase: fix for hgsubversion
This revision was automatically updated to reflect the committed changes. Closed by commit rHG83014fa95435: rebase: fix for hgsubversion (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1679?vs=4415=4428 REVISION DETAIL https://phab.mercurial-scm.org/D1679 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -1102,13 +1102,14 @@ if wctx.isinmemory(): wctx.setbase(repo[p1]) else: -# This is necessary to invalidate workingctx's caches. -wctx = repo[None] if repo['.'].rev() != p1: repo.ui.debug(" update to %d:%s\n" % (p1, repo[p1])) mergemod.update(repo, p1, False, True) else: repo.ui.debug(" already in destination\n") +# This is, alas, necessary to invalidate workingctx's manifest cache, +# as well as other data we litter on it in other places. +wctx = repo[None] repo.dirstate.write(repo.currenttransaction()) repo.ui.debug(" merge against %d:%s\n" % (rev, repo[rev])) if base is not None: To: phillco, #hg-reviewers, yuja Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1681: rebase: add ui.log calls for whether IMM used, whether rebasing WCP
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1681 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -390,6 +390,9 @@ else: self.wctx = self.repo[None] self.repo.ui.debug("rebasing on disk\n") +self.repo.ui.log("rebase", "", { +'rebase_imm_used': self.wctx.isinmemory() +}) def _performrebase(self, tr): self._assignworkingcopy() @@ -957,6 +960,7 @@ # stacks that include the WCP. However, I'm not yet sure where the cutoff # is. rebasingwcp = repo['.'].rev() in rebaseset +ui.log("rebase", "", {'rebase_rebasing_wcp': rebasingwcp}) if rbsrt.inmemory and rebasingwcp: rbsrt.inmemory = False # Check these since we did not before. To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1679: rebase: fix for hgsubversion
phillco added a comment. A better way might just be to use `None` for `self.wtcx` when rebasing on disk, which will cause fresh wctxs to be used every time and feel less icky. We could use `sel.inmemory` instead of `self.wctx.isinmemory()`. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1679 To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1679: rebase: fix for hgsubversion
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY https://phab.mercurial-scm.org/rHG5c25fe7fb1e63a31ed082dfcb93673fa79cf081f broke something in the hgsubversion test path, causing it raise an abort (Abort: nothing to merge) during a perfectly good rebase. I tracked it down to this change. It's probably not hgsubversion related. I suspect that using the same `wctx` from before the initial update causes problems with the wctx's cached manifest property. I noticed we also sometimes stick random gunk on the wctx object in other places (like in `copies.py`) so it's probably best to reset it for now. The line I added before was actually useless since we don't pass wctx to the initial `merge.update`, so it defaults to `repo[None]`. So I just removed it. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1679 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -1102,13 +1102,14 @@ if wctx.isinmemory(): wctx.setbase(repo[p1]) else: -# This is necessary to invalidate workingctx's caches. -wctx = repo[None] if repo['.'].rev() != p1: repo.ui.debug(" update to %d:%s\n" % (p1, repo[p1])) mergemod.update(repo, p1, False, True) else: repo.ui.debug(" already in destination\n") +# This is, alas, necessary to invalidate workingctx's manifest cache, +# as well as other data we litter on it in other places. +wctx = repo[None] repo.dirstate.write(repo.currenttransaction()) repo.ui.debug(" merge against %d:%s\n" % (rev, repo[rev])) if base is not None: To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1666: rebase: replace --inmemory flag with rebase.experimental.inmemory config
This revision was automatically updated to reflect the committed changes. Closed by commit rHGdd11df900f7f: rebase: replace --inmemory flag with rebase.experimental.inmemory config (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1666?vs=4377=4379 REVISION DETAIL https://phab.mercurial-scm.org/D1666 AFFECTED FILES hgext/rebase.py mercurial/configitems.py tests/test-rebase-inmemory.t CHANGE DETAILS diff --git a/tests/test-rebase-inmemory.t b/tests/test-rebase-inmemory.t --- a/tests/test-rebase-inmemory.t +++ b/tests/test-rebase-inmemory.t @@ -4,6 +4,8 @@ > amend= > rebase= > debugdrawdag=$TESTDIR/drawdag.py + > [rebase] + > experimental.inmemory=1 > [diff] > git=1 > [alias] @@ -35,7 +37,7 @@ c (no-eol) $ hg cat -r 2 b b (no-eol) - $ hg rebase --inmemory --debug -r b -d c | grep rebasing + $ hg rebase --debug -r b -d c | grep rebasing rebasing in-memory rebasing 2:db0e82a16a62 "b" (b) $ hg tglog @@ -94,7 +96,7 @@ b (no-eol) $ hg cat -r 3 e somefile (no-eol) - $ hg rebase --inmemory --debug -s b -d a | grep rebasing + $ hg rebase --debug -s b -d a | grep rebasing rebasing in-memory rebasing 2:db0e82a16a62 "b" (b) $ hg tglog @@ -110,7 +112,7 @@ c (no-eol) $ hg cat -r 3 b b (no-eol) - $ hg rebase --inmemory --debug -s 1 -d 3 | grep rebasing + $ hg rebase --debug -s 1 -d 3 | grep rebasing rebasing in-memory rebasing 1:02952614a83d "d" (d) rebasing 2:f56b71190a8f "c" @@ -142,7 +144,7 @@ we requested in-memory. $ hg up -C 3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg rebase -r 3 -d 0 --inmemory --debug | grep rebasing + $ hg rebase -r 3 -d 0 --debug | grep rebasing rebasing on disk rebasing 3:753feb6fd12a "c" (tip) $ hg tglog diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -1269,3 +1269,6 @@ coreconfigitem('rebase', 'singletransaction', default=False, ) +coreconfigitem('rebase', 'experimental.inmemory', +default=False, +) diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -136,7 +136,7 @@ class rebaseruntime(object): """This class is a container for rebase runtime state""" -def __init__(self, repo, ui, opts=None): +def __init__(self, repo, ui, inmemory=False, opts=None): if opts is None: opts = {} @@ -179,7 +179,7 @@ self.keepopen = opts.get('keepopen', False) self.obsoletenotrebased = {} self.obsoletewithoutsuccessorindestination = set() -self.inmemory = opts.get('inmemory', False) +self.inmemory = inmemory @property def repo(self): @@ -645,7 +645,6 @@ ('i', 'interactive', False, _('(DEPRECATED)')), ('t', 'tool', '', _('specify merge tool')), ('c', 'continue', False, _('continue an interrupted rebase')), -('', 'inmemory', False, _('run rebase in-memory (EXPERIMENTAL)')), ('a', 'abort', False, _('abort an interrupted rebase'))] + cmdutil.formatteropts, _('[-s REV | -b REV] [-d REV] [OPTION]')) @@ -757,35 +756,40 @@ [rebase] singletransaction = True +By default, rebase writes to the working copy, but you can configure it to +run in-memory for for better performance, and to allow it to run if the +working copy is dirty:: + + [rebase] + experimental.inmemory = True + Return Values: Returns 0 on success, 1 if nothing to rebase or there are unresolved conflicts. """ +inmemory = ui.configbool('rebase', 'experimental.inmemory') if opts.get('continue') or opts.get('abort'): # in-memory rebase is not compatible with resuming rebases. -opts['inmemory'] = False +inmemory = False -if opts.get('inmemory', False): +if inmemory: try: # in-memory merge doesn't support conflicts, so if we hit any, abort # and re-run as an on-disk merge. -return _origrebase(ui, repo, **opts) +return _origrebase(ui, repo, inmemory=inmemory, **opts) except error.InMemoryMergeConflictsError: ui.warn(_('hit merge conflicts; re-running rebase without in-memory' ' merge\n')) _origrebase(ui, repo, **{'abort': True}) -opts['inmemory'] = False -return _origrebase(ui, repo, **opts) +return _origrebase(ui, repo, inmemory=False, **opts) else: return _origrebase(ui, repo, **opts) -def _origrebase(ui, repo, **opts): +def _origrebase(ui, repo, inmemory=False, **opts): opts = pycompat.byteskwargs(opts) -if 'inmemory' not in opts: -opts['inmemory'] = False -rbsrt = rebaseruntime(repo, ui, opts) +rbsrt = rebaseruntime(repo, ui, inmemory, opts) with repo.wlock(), repo.lock():
D1666: rebase: replace --inmemory flag with rebase.experimental.inmemory config
phillco updated this revision to Diff 4377. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1666?vs=4376=4377 REVISION DETAIL https://phab.mercurial-scm.org/D1666 AFFECTED FILES hgext/rebase.py mercurial/configitems.py tests/test-rebase-inmemory.t CHANGE DETAILS diff --git a/tests/test-rebase-inmemory.t b/tests/test-rebase-inmemory.t --- a/tests/test-rebase-inmemory.t +++ b/tests/test-rebase-inmemory.t @@ -4,6 +4,8 @@ > amend= > rebase= > debugdrawdag=$TESTDIR/drawdag.py + > [rebase] + > experimental.inmemory=1 > [diff] > git=1 > [alias] @@ -35,7 +37,7 @@ c (no-eol) $ hg cat -r 2 b b (no-eol) - $ hg rebase --inmemory --debug -r b -d c | grep rebasing + $ hg rebase --debug -r b -d c | grep rebasing rebasing in-memory rebasing 2:db0e82a16a62 "b" (b) $ hg tglog @@ -94,7 +96,7 @@ b (no-eol) $ hg cat -r 3 e somefile (no-eol) - $ hg rebase --inmemory --debug -s b -d a | grep rebasing + $ hg rebase --debug -s b -d a | grep rebasing rebasing in-memory rebasing 2:db0e82a16a62 "b" (b) $ hg tglog @@ -110,7 +112,7 @@ c (no-eol) $ hg cat -r 3 b b (no-eol) - $ hg rebase --inmemory --debug -s 1 -d 3 | grep rebasing + $ hg rebase --debug -s 1 -d 3 | grep rebasing rebasing in-memory rebasing 1:02952614a83d "d" (d) rebasing 2:f56b71190a8f "c" @@ -142,7 +144,7 @@ we requested in-memory. $ hg up -C 3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg rebase -r 3 -d 0 --inmemory --debug | grep rebasing + $ hg rebase -r 3 -d 0 --debug | grep rebasing rebasing on disk rebasing 3:753feb6fd12a "c" (tip) $ hg tglog diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -1269,3 +1269,6 @@ coreconfigitem('rebase', 'singletransaction', default=False, ) +coreconfigitem('rebase', 'experimental.inmemory', +default=False, +) diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -136,7 +136,7 @@ class rebaseruntime(object): """This class is a container for rebase runtime state""" -def __init__(self, repo, ui, opts=None): +def __init__(self, repo, ui, inmemory=False, opts=None): if opts is None: opts = {} @@ -179,7 +179,7 @@ self.keepopen = opts.get('keepopen', False) self.obsoletenotrebased = {} self.obsoletewithoutsuccessorindestination = set() -self.inmemory = opts.get('inmemory', False) +self.inmemory = inmemory @property def repo(self): @@ -645,7 +645,6 @@ ('i', 'interactive', False, _('(DEPRECATED)')), ('t', 'tool', '', _('specify merge tool')), ('c', 'continue', False, _('continue an interrupted rebase')), -('', 'inmemory', False, _('run rebase in-memory (EXPERIMENTAL)')), ('a', 'abort', False, _('abort an interrupted rebase'))] + cmdutil.formatteropts, _('[-s REV | -b REV] [-d REV] [OPTION]')) @@ -757,35 +756,40 @@ [rebase] singletransaction = True +By default, rebase writes to the working copy, but you can configure it to +run in-memory for for better performance, and to allow it to run if the +working copy is dirty:: + + [rebase] + experimental.inmemory = True + Return Values: Returns 0 on success, 1 if nothing to rebase or there are unresolved conflicts. """ +inmemory = ui.configbool('rebase', 'experimental.inmemory') if opts.get('continue') or opts.get('abort'): # in-memory rebase is not compatible with resuming rebases. -opts['inmemory'] = False +inmemory = False -if opts.get('inmemory', False): +if inmemory: try: # in-memory merge doesn't support conflicts, so if we hit any, abort # and re-run as an on-disk merge. -return _origrebase(ui, repo, **opts) +return _origrebase(ui, repo, inmemory=inmemory, **opts) except error.InMemoryMergeConflictsError: ui.warn(_('hit merge conflicts; re-running rebase without in-memory' ' merge\n')) _origrebase(ui, repo, **{'abort': True}) -opts['inmemory'] = False -return _origrebase(ui, repo, **opts) +return _origrebase(ui, repo, inmemory=False, **opts) else: return _origrebase(ui, repo, **opts) -def _origrebase(ui, repo, **opts): +def _origrebase(ui, repo, inmemory=False, **opts): opts = pycompat.byteskwargs(opts) -if 'inmemory' not in opts: -opts['inmemory'] = False -rbsrt = rebaseruntime(repo, ui, opts) +rbsrt = rebaseruntime(repo, ui, inmemory, opts) with repo.wlock(), repo.lock(): # Validate input and define rebasing points @@ -832,10 +836,8 @@ if retcode is not None: return retcode else: -destmap =
D1666: rebase: replace --inmemory flag with rebase.experimental.inmemory config
phillco updated this revision to Diff 4376. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1666?vs=4375=4376 REVISION DETAIL https://phab.mercurial-scm.org/D1666 AFFECTED FILES hgext/rebase.py mercurial/configitems.py tests/test-rebase-inmemory.t CHANGE DETAILS diff --git a/tests/test-rebase-inmemory.t b/tests/test-rebase-inmemory.t --- a/tests/test-rebase-inmemory.t +++ b/tests/test-rebase-inmemory.t @@ -4,6 +4,8 @@ > amend= > rebase= > debugdrawdag=$TESTDIR/drawdag.py + > [rebase] + > experimental.inmemory=1 > [diff] > git=1 > [alias] @@ -35,7 +37,7 @@ c (no-eol) $ hg cat -r 2 b b (no-eol) - $ hg rebase --inmemory --debug -r b -d c | grep rebasing + $ hg rebase --debug -r b -d c | grep rebasing rebasing in-memory rebasing 2:db0e82a16a62 "b" (b) $ hg tglog @@ -94,7 +96,7 @@ b (no-eol) $ hg cat -r 3 e somefile (no-eol) - $ hg rebase --inmemory --debug -s b -d a | grep rebasing + $ hg rebase --debug -s b -d a | grep rebasing rebasing in-memory rebasing 2:db0e82a16a62 "b" (b) $ hg tglog @@ -110,7 +112,7 @@ c (no-eol) $ hg cat -r 3 b b (no-eol) - $ hg rebase --inmemory --debug -s 1 -d 3 | grep rebasing + $ hg rebase --debug -s 1 -d 3 | grep rebasing rebasing in-memory rebasing 1:02952614a83d "d" (d) rebasing 2:f56b71190a8f "c" @@ -142,7 +144,7 @@ we requested in-memory. $ hg up -C 3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg rebase -r 3 -d 0 --inmemory --debug | grep rebasing + $ hg rebase -r 3 -d 0 --debug | grep rebasing rebasing on disk rebasing 3:753feb6fd12a "c" (tip) $ hg tglog diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -1269,3 +1269,6 @@ coreconfigitem('rebase', 'singletransaction', default=False, ) +coreconfigitem('rebase', 'experimental.inmemory', +default=False, +) diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -136,7 +136,7 @@ class rebaseruntime(object): """This class is a container for rebase runtime state""" -def __init__(self, repo, ui, opts=None): +def __init__(self, repo, ui, inmemory=False, opts=None): if opts is None: opts = {} @@ -179,7 +179,7 @@ self.keepopen = opts.get('keepopen', False) self.obsoletenotrebased = {} self.obsoletewithoutsuccessorindestination = set() -self.inmemory = opts.get('inmemory', False) +self.inmemory = inmemory @property def repo(self): @@ -645,7 +645,6 @@ ('i', 'interactive', False, _('(DEPRECATED)')), ('t', 'tool', '', _('specify merge tool')), ('c', 'continue', False, _('continue an interrupted rebase')), -('', 'inmemory', False, _('run rebase in-memory (EXPERIMENTAL)')), ('a', 'abort', False, _('abort an interrupted rebase'))] + cmdutil.formatteropts, _('[-s REV | -b REV] [-d REV] [OPTION]')) @@ -763,29 +762,27 @@ unresolved conflicts. """ +inmemory = ui.configbool('rebase', 'experimental.inmemory') if opts.get('continue') or opts.get('abort'): # in-memory rebase is not compatible with resuming rebases. -opts['inmemory'] = False +inmemory = False -if opts.get('inmemory', False): +if inmemory: try: # in-memory merge doesn't support conflicts, so if we hit any, abort # and re-run as an on-disk merge. -return _origrebase(ui, repo, **opts) +return _origrebase(ui, repo, inmemory=inmemory, **opts) except error.InMemoryMergeConflictsError: ui.warn(_('hit merge conflicts; re-running rebase without in-memory' ' merge\n')) _origrebase(ui, repo, **{'abort': True}) -opts['inmemory'] = False -return _origrebase(ui, repo, **opts) +return _origrebase(ui, repo, inmemory=False, **opts) else: return _origrebase(ui, repo, **opts) -def _origrebase(ui, repo, **opts): +def _origrebase(ui, repo, inmemory=False, **opts): opts = pycompat.byteskwargs(opts) -if 'inmemory' not in opts: -opts['inmemory'] = False -rbsrt = rebaseruntime(repo, ui, opts) +rbsrt = rebaseruntime(repo, ui, inmemory, opts) with repo.wlock(), repo.lock(): # Validate input and define rebasing points @@ -832,10 +829,8 @@ if retcode is not None: return retcode else: -destmap = _definedestmap(ui, repo, destf, srcf, basef, revf, - destspace=destspace, - opts=opts) -rbsrt.inmemory = opts['inmemory'] +destmap = _definedestmap(ui, repo, rbsrt, destf, srcf, basef, revf, + destspace=destspace) retcode =
D1666: rebase: replace --inmemory flag with rebase.experimental.inmemory config
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1666 AFFECTED FILES hgext/rebase.py mercurial/configitems.py tests/test-rebase-inmemory.t CHANGE DETAILS diff --git a/tests/test-rebase-inmemory.t b/tests/test-rebase-inmemory.t --- a/tests/test-rebase-inmemory.t +++ b/tests/test-rebase-inmemory.t @@ -4,6 +4,8 @@ > amend= > rebase= > debugdrawdag=$TESTDIR/drawdag.py + > [rebase] + > experimental.inmemory=1 > [diff] > git=1 > [alias] @@ -35,7 +37,7 @@ c (no-eol) $ hg cat -r 2 b b (no-eol) - $ hg rebase --inmemory --debug -r b -d c | grep rebasing + $ hg rebase --debug -r b -d c | grep rebasing rebasing in-memory rebasing 2:db0e82a16a62 "b" (b) $ hg tglog @@ -94,7 +96,7 @@ b (no-eol) $ hg cat -r 3 e somefile (no-eol) - $ hg rebase --inmemory --debug -s b -d a | grep rebasing + $ hg rebase --debug -s b -d a | grep rebasing rebasing in-memory rebasing 2:db0e82a16a62 "b" (b) $ hg tglog @@ -110,7 +112,7 @@ c (no-eol) $ hg cat -r 3 b b (no-eol) - $ hg rebase --inmemory --debug -s 1 -d 3 | grep rebasing + $ hg rebase --debug -s 1 -d 3 | grep rebasing rebasing in-memory rebasing 1:02952614a83d "d" (d) rebasing 2:f56b71190a8f "c" @@ -142,7 +144,7 @@ we requested in-memory. $ hg up -C 3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg rebase -r 3 -d 0 --inmemory --debug | grep rebasing + $ hg rebase -r 3 -d 0 --debug | grep rebasing rebasing on disk rebasing 3:753feb6fd12a "c" (tip) $ hg tglog diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -1269,3 +1269,6 @@ coreconfigitem('rebase', 'singletransaction', default=False, ) +coreconfigitem('rebase', 'experimental.inmemory', +default=False, +) diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -136,7 +136,7 @@ class rebaseruntime(object): """This class is a container for rebase runtime state""" -def __init__(self, repo, ui, opts=None): +def __init__(self, repo, ui, inmemory=False, opts=None): if opts is None: opts = {} @@ -179,7 +179,7 @@ self.keepopen = opts.get('keepopen', False) self.obsoletenotrebased = {} self.obsoletewithoutsuccessorindestination = set() -self.inmemory = opts.get('inmemory', False) +self.inmemory = inmemory @property def repo(self): @@ -645,7 +645,6 @@ ('i', 'interactive', False, _('(DEPRECATED)')), ('t', 'tool', '', _('specify merge tool')), ('c', 'continue', False, _('continue an interrupted rebase')), -('', 'inmemory', False, _('run rebase in-memory (EXPERIMENTAL)')), ('a', 'abort', False, _('abort an interrupted rebase'))] + cmdutil.formatteropts, _('[-s REV | -b REV] [-d REV] [OPTION]')) @@ -763,29 +762,27 @@ unresolved conflicts. """ +inmemory = ui.configbool('rebase', 'experimental.inmemory') if opts.get('continue') or opts.get('abort'): # in-memory rebase is not compatible with resuming rebases. -opts['inmemory'] = False +inmemory = False -if opts.get('inmemory', False): +if inmemory: try: # in-memory merge doesn't support conflicts, so if we hit any, abort # and re-run as an on-disk merge. -return _origrebase(ui, repo, **opts) +return _origrebase(ui, repo, inmemory=inmemory, **opts) except error.InMemoryMergeConflictsError: ui.warn(_('hit merge conflicts; re-running rebase without in-memory' ' merge\n')) _origrebase(ui, repo, **{'abort': True}) -opts['inmemory'] = False -return _origrebase(ui, repo, **opts) +return _origrebase(ui, repo, inmemory=False, **opts) else: return _origrebase(ui, repo, **opts) -def _origrebase(ui, repo, **opts): +def _origrebase(ui, repo, inmemory=False, **opts): opts = pycompat.byteskwargs(opts) -if 'inmemory' not in opts: -opts['inmemory'] = False -rbsrt = rebaseruntime(repo, ui, opts) +rbsrt = rebaseruntime(repo, ui, inmemory, opts) with repo.wlock(), repo.lock(): # Validate input and define rebasing points @@ -832,10 +829,8 @@ if retcode is not None: return retcode else: -destmap = _definedestmap(ui, repo, destf, srcf, basef, revf, - destspace=destspace, - opts=opts) -rbsrt.inmemory = opts['inmemory'] +destmap = _definedestmap(ui, repo, rbsrt, destf, srcf, basef, revf, + destspace=destspace) retcode =
D1232: rebase: add the --inmemory option flag; assign a wctx object for the rebase
phillco added a comment. Given that most users will be using the config knob (and eventually, nothing at all), I can just send a followup to rename to `experimental.inmmemory`. Nobody is using it yet. INLINE COMMENTS > dlax wrote in rebase.py:738 > This is useless because "inmemory" will be in `opts` and because you wrote > `opts.get('inmemory', False)` in `rebaseruntime.__init__()` above. Thanks. I'll send a followup. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1232 To: phillco, #hg-reviewers, dlax, durin42 Cc: smf, durin42, dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1652: tests: add a simple test for in-memory rebase
This revision was automatically updated to reflect the committed changes. Closed by commit rHGb9bdee046cc2: tests: add a simple test for in-memory rebase (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1652?vs=4348=4351 REVISION DETAIL https://phab.mercurial-scm.org/D1652 AFFECTED FILES hgext/rebase.py tests/test-rebase-conflicts.t tests/test-rebase-inmemory.t CHANGE DETAILS diff --git a/tests/test-rebase-inmemory.t b/tests/test-rebase-inmemory.t new file mode 100644 --- /dev/null +++ b/tests/test-rebase-inmemory.t @@ -0,0 +1,157 @@ +#require symlink execbit + $ cat << EOF >> $HGRCPATH + > [extensions] + > amend= + > rebase= + > debugdrawdag=$TESTDIR/drawdag.py + > [diff] + > git=1 + > [alias] + > tglog = log -G --template "{rev}: {node|short} '{desc}'\n" + > EOF + +Rebase a simple DAG: + $ hg init repo1 + $ cd repo1 + $ hg debugdrawdag <<'EOS' + > c b + > |/ + > d + > | + > a + > EOS + $ hg up -C a + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg tglog + o 3: 814f6bd05178 'c' + | + | o 2: db0e82a16a62 'b' + |/ + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 c + c (no-eol) + $ hg cat -r 2 b + b (no-eol) + $ hg rebase --inmemory --debug -r b -d c | grep rebasing + rebasing in-memory + rebasing 2:db0e82a16a62 "b" (b) + $ hg tglog + o 3: ca58782ad1e4 'b' + | + o 2: 814f6bd05178 'c' + | + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 b + b (no-eol) + $ hg cat -r 2 c + c (no-eol) + +Case 2: + $ hg init repo2 + $ cd repo2 + $ hg debugdrawdag <<'EOS' + > c b + > |/ + > d + > | + > a + > EOS + +Add a symlink and executable file: + $ hg up -C c + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ ln -s somefile e + $ echo f > f + $ chmod +x f + $ hg add e f + $ hg amend -q + $ hg up -Cq a + +Write files to the working copy, and ensure they're still there after the rebase + $ echo "abc" > a + $ ln -s def b + $ echo "ghi" > c + $ echo "jkl" > d + $ echo "mno" > e + $ hg tglog + o 3: f56b71190a8f 'c' + | + | o 2: db0e82a16a62 'b' + |/ + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 c + c (no-eol) + $ hg cat -r 2 b + b (no-eol) + $ hg cat -r 3 e + somefile (no-eol) + $ hg rebase --inmemory --debug -s b -d a | grep rebasing + rebasing in-memory + rebasing 2:db0e82a16a62 "b" (b) + $ hg tglog + o 3: fc055c3b4d33 'b' + | + | o 2: f56b71190a8f 'c' + | | + | o 1: 02952614a83d 'd' + |/ + @ 0: b173517d0057 'a' + + $ hg cat -r 2 c + c (no-eol) + $ hg cat -r 3 b + b (no-eol) + $ hg rebase --inmemory --debug -s 1 -d 3 | grep rebasing + rebasing in-memory + rebasing 1:02952614a83d "d" (d) + rebasing 2:f56b71190a8f "c" + $ hg tglog + o 3: 753feb6fd12a 'c' + | + o 2: 09c044d2cb43 'd' + | + o 1: fc055c3b4d33 'b' + | + @ 0: b173517d0057 'a' + +Ensure working copy files are still there: + $ cat a + abc + $ readlink.py b + b -> def + $ cat e + mno + +Ensure symlink and executable files were rebased properly: + $ hg up -Cq 3 + $ readlink.py e + e -> somefile + $ ls -l f | cut -c -10 + -rwxr-xr-x + +Rebase the working copy parent, which should default to an on-disk merge even if +we requested in-memory. + $ hg up -C 3 + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg rebase -r 3 -d 0 --inmemory --debug | grep rebasing + rebasing on disk + rebasing 3:753feb6fd12a "c" (tip) + $ hg tglog + @ 3: 844a7de3e617 'c' + | + | o 2: 09c044d2cb43 'd' + | | + | o 1: fc055c3b4d33 'b' + |/ + o 0: b173517d0057 'a' + + diff --git a/tests/test-rebase-conflicts.t b/tests/test-rebase-conflicts.t --- a/tests/test-rebase-conflicts.t +++ b/tests/test-rebase-conflicts.t @@ -235,6 +235,7 @@ $ hg rebase -s9 -d2 --debug # use debug to really check merge base used rebase onto 4bc80088dc6b starting from e31216eec445 + rebasing on disk rebase status stored rebasing 9:e31216eec445 "more changes to f1" future parents are 2 and -1 diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -386,8 +386,10 @@ if self.inmemory: from mercurial.context import overlayworkingctx self.wctx = overlayworkingctx(self.repo) +self.repo.ui.debug("rebasing in-memory\n") else: self.wctx = self.repo[None] +self.repo.ui.debug("rebasing on disk\n") def _performrebase(self, tr): self._assignworkingcopy() To: phillco, #hg-reviewers, durin42 Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1650: tests: add commit hashes to log commands in rebase tests
This revision was automatically updated to reflect the committed changes. Closed by commit rHG469b06b4c3ca: tests: add commit hashes to log commands in rebase tests (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1650?vs=4343=4352 REVISION DETAIL https://phab.mercurial-scm.org/D1650 AFFECTED FILES tests/test-mq-header-date.t tests/test-mq-header-from.t tests/test-mq-pull-from-bundle.t tests/test-rebase-base-flag.t tests/test-rebase-bookmarks.t tests/test-rebase-collapse.t tests/test-rebase-dest.t tests/test-rebase-detach.t tests/test-rebase-interruptions.t tests/test-rebase-issue-noparam-single-rev.t tests/test-rebase-mq-skip.t tests/test-rebase-mq.t tests/test-rebase-named-branches.t tests/test-rebase-newancestor.t tests/test-rebase-parameters.t tests/test-rebase-partial.t tests/test-rebase-pull.t tests/test-rebase-rename.t tests/test-rebase-scenario-global.t To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1652: tests: add a simple test for in-memory rebase
phillco updated this revision to Diff 4348. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1652?vs=4347=4348 REVISION DETAIL https://phab.mercurial-scm.org/D1652 AFFECTED FILES hgext/rebase.py tests/test-rebase-conflicts.t tests/test-rebase-inmemory.t CHANGE DETAILS diff --git a/tests/test-rebase-inmemory.t b/tests/test-rebase-inmemory.t new file mode 100644 --- /dev/null +++ b/tests/test-rebase-inmemory.t @@ -0,0 +1,157 @@ +#require symlink execbit + $ cat << EOF >> $HGRCPATH + > [extensions] + > amend= + > rebase= + > debugdrawdag=$TESTDIR/drawdag.py + > [diff] + > git=1 + > [alias] + > tglog = log -G --template "{rev}: {node|short} '{desc}'\n" + > EOF + +Rebase a simple DAG: + $ hg init repo1 + $ cd repo1 + $ hg debugdrawdag <<'EOS' + > c b + > |/ + > d + > | + > a + > EOS + $ hg up -C a + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg tglog + o 3: 814f6bd05178 'c' + | + | o 2: db0e82a16a62 'b' + |/ + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 c + c (no-eol) + $ hg cat -r 2 b + b (no-eol) + $ hg rebase --inmemory --debug -r b -d c | grep rebasing + rebasing in-memory + rebasing 2:db0e82a16a62 "b" (b) + $ hg tglog + o 3: ca58782ad1e4 'b' + | + o 2: 814f6bd05178 'c' + | + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 b + b (no-eol) + $ hg cat -r 2 c + c (no-eol) + +Case 2: + $ hg init repo2 + $ cd repo2 + $ hg debugdrawdag <<'EOS' + > c b + > |/ + > d + > | + > a + > EOS + +Add a symlink and executable file: + $ hg up -C c + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ ln -s somefile e + $ echo f > f + $ chmod +x f + $ hg add e f + $ hg amend -q + $ hg up -Cq a + +Write files to the working copy, and ensure they're still there after the rebase + $ echo "abc" > a + $ ln -s def b + $ echo "ghi" > c + $ echo "jkl" > d + $ echo "mno" > e + $ hg tglog + o 3: f56b71190a8f 'c' + | + | o 2: db0e82a16a62 'b' + |/ + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 c + c (no-eol) + $ hg cat -r 2 b + b (no-eol) + $ hg cat -r 3 e + somefile (no-eol) + $ hg rebase --inmemory --debug -s b -d a | grep rebasing + rebasing in-memory + rebasing 2:db0e82a16a62 "b" (b) + $ hg tglog + o 3: fc055c3b4d33 'b' + | + | o 2: f56b71190a8f 'c' + | | + | o 1: 02952614a83d 'd' + |/ + @ 0: b173517d0057 'a' + + $ hg cat -r 2 c + c (no-eol) + $ hg cat -r 3 b + b (no-eol) + $ hg rebase --inmemory --debug -s 1 -d 3 | grep rebasing + rebasing in-memory + rebasing 1:02952614a83d "d" (d) + rebasing 2:f56b71190a8f "c" + $ hg tglog + o 3: 753feb6fd12a 'c' + | + o 2: 09c044d2cb43 'd' + | + o 1: fc055c3b4d33 'b' + | + @ 0: b173517d0057 'a' + +Ensure working copy files are still there: + $ cat a + abc + $ readlink.py b + b -> def + $ cat e + mno + +Ensure symlink and executable files were rebased properly: + $ hg up -Cq 3 + $ readlink.py e + e -> somefile + $ ls -l f | cut -c -10 + -rwxr-xr-x + +Rebase the working copy parent, which should default to an on-disk merge even if +we requested in-memory. + $ hg up -C 3 + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg rebase -r 3 -d 0 --inmemory --debug | grep rebasing + rebasing on disk + rebasing 3:753feb6fd12a "c" (tip) + $ hg tglog + @ 3: 844a7de3e617 'c' + | + | o 2: 09c044d2cb43 'd' + | | + | o 1: fc055c3b4d33 'b' + |/ + o 0: b173517d0057 'a' + + diff --git a/tests/test-rebase-conflicts.t b/tests/test-rebase-conflicts.t --- a/tests/test-rebase-conflicts.t +++ b/tests/test-rebase-conflicts.t @@ -235,6 +235,7 @@ $ hg rebase -s9 -d2 --debug # use debug to really check merge base used rebase onto 4bc80088dc6b starting from e31216eec445 + rebasing on disk rebase status stored rebasing 9:e31216eec445 "more changes to f1" future parents are 2 and -1 diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -386,8 +386,10 @@ if self.inmemory: from mercurial.context import overlayworkingctx self.wctx = overlayworkingctx(self.repo) +self.repo.ui.debug("rebasing in-memory\n") else: self.wctx = self.repo[None] +self.repo.ui.debug("rebasing on disk\n") def _performrebase(self, tr): self._assignworkingcopy() To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1617: rebase: extract _assignworkingcopy
phillco added inline comments. INLINE COMMENTS > krbullock wrote in rebase.py:393 > Rather than having this method spookily set self.wctx, why not make > `_assignworkingcopy` _return_ the wctx (and rename it accordingly)? Good point, I'll send a followup. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1617 To: phillco, #hg-reviewers, dlax Cc: krbullock, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1652: tests: add a simple test for in-memory rebase
phillco updated this revision to Diff 4347. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1652?vs=4346=4347 REVISION DETAIL https://phab.mercurial-scm.org/D1652 AFFECTED FILES hgext/rebase.py tests/test-rebase-inmemory.t CHANGE DETAILS diff --git a/tests/test-rebase-inmemory.t b/tests/test-rebase-inmemory.t new file mode 100644 --- /dev/null +++ b/tests/test-rebase-inmemory.t @@ -0,0 +1,157 @@ +#require symlink execbit + $ cat << EOF >> $HGRCPATH + > [extensions] + > amend= + > rebase= + > debugdrawdag=$TESTDIR/drawdag.py + > [diff] + > git=1 + > [alias] + > tglog = log -G --template "{rev}: {node|short} '{desc}'\n" + > EOF + +Rebase a simple DAG: + $ hg init repo1 + $ cd repo1 + $ hg debugdrawdag <<'EOS' + > c b + > |/ + > d + > | + > a + > EOS + $ hg up -C a + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg tglog + o 3: 814f6bd05178 'c' + | + | o 2: db0e82a16a62 'b' + |/ + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 c + c (no-eol) + $ hg cat -r 2 b + b (no-eol) + $ hg rebase --inmemory --debug -r b -d c | grep rebasing + rebasing in-memory + rebasing 2:db0e82a16a62 "b" (b) + $ hg tglog + o 3: ca58782ad1e4 'b' + | + o 2: 814f6bd05178 'c' + | + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 b + b (no-eol) + $ hg cat -r 2 c + c (no-eol) + +Case 2: + $ hg init repo2 + $ cd repo2 + $ hg debugdrawdag <<'EOS' + > c b + > |/ + > d + > | + > a + > EOS + +Add a symlink and executable file: + $ hg up -C c + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ ln -s somefile e + $ echo f > f + $ chmod +x f + $ hg add e f + $ hg amend -q + $ hg up -Cq a + +Write files to the working copy, and ensure they're still there after the rebase + $ echo "abc" > a + $ ln -s def b + $ echo "ghi" > c + $ echo "jkl" > d + $ echo "mno" > e + $ hg tglog + o 3: f56b71190a8f 'c' + | + | o 2: db0e82a16a62 'b' + |/ + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 c + c (no-eol) + $ hg cat -r 2 b + b (no-eol) + $ hg cat -r 3 e + somefile (no-eol) + $ hg rebase --inmemory --debug -s b -d a | grep rebasing + rebasing in-memory + rebasing 2:db0e82a16a62 "b" (b) + $ hg tglog + o 3: fc055c3b4d33 'b' + | + | o 2: f56b71190a8f 'c' + | | + | o 1: 02952614a83d 'd' + |/ + @ 0: b173517d0057 'a' + + $ hg cat -r 2 c + c (no-eol) + $ hg cat -r 3 b + b (no-eol) + $ hg rebase --inmemory --debug -s 1 -d 3 | grep rebasing + rebasing in-memory + rebasing 1:02952614a83d "d" (d) + rebasing 2:f56b71190a8f "c" + $ hg tglog + o 3: 753feb6fd12a 'c' + | + o 2: 09c044d2cb43 'd' + | + o 1: fc055c3b4d33 'b' + | + @ 0: b173517d0057 'a' + +Ensure working copy files are still there: + $ cat a + abc + $ readlink.py b + b -> def + $ cat e + mno + +Ensure symlink and executable files were rebased properly: + $ hg up -Cq 3 + $ readlink.py e + e -> somefile + $ ls -l f | cut -f1 -d ' ' + -rwxr-xr-x + +Rebase the working copy parent, which should default to an on-disk merge even if +we requested in-memory. + $ hg up -C 3 + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg rebase -r 3 -d 0 --inmemory --debug | grep rebasing + rebasing on disk + rebasing 3:753feb6fd12a "c" (tip) + $ hg tglog + @ 3: 844a7de3e617 'c' + | + | o 2: 09c044d2cb43 'd' + | | + | o 1: fc055c3b4d33 'b' + |/ + o 0: b173517d0057 'a' + + diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -386,8 +386,10 @@ if self.inmemory: from mercurial.context import overlayworkingctx self.wctx = overlayworkingctx(self.repo) +self.repo.ui.debug("rebasing in-memory\n") else: self.wctx = self.repo[None] +self.repo.ui.debug("rebasing on disk\n") def _performrebase(self, tr): self._assignworkingcopy() To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1652: tests: add a simple test for in-memory rebase
phillco updated this revision to Diff 4346. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1652?vs=4345=4346 REVISION DETAIL https://phab.mercurial-scm.org/D1652 AFFECTED FILES hgext/rebase.py tests/test-rebase-inmemory.t CHANGE DETAILS diff --git a/tests/test-rebase-inmemory.t b/tests/test-rebase-inmemory.t new file mode 100644 --- /dev/null +++ b/tests/test-rebase-inmemory.t @@ -0,0 +1,156 @@ + $ cat << EOF >> $HGRCPATH + > [extensions] + > amend= + > rebase= + > debugdrawdag=$TESTDIR/drawdag.py + > [diff] + > git=1 + > [alias] + > tglog = log -G --template "{rev}: {node|short} '{desc}'\n" + > EOF + +Rebase a simple DAG: + $ hg init repo1 + $ cd repo1 + $ hg debugdrawdag <<'EOS' + > c b + > |/ + > d + > | + > a + > EOS + $ hg up -C a + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg tglog + o 3: 814f6bd05178 'c' + | + | o 2: db0e82a16a62 'b' + |/ + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 c + c (no-eol) + $ hg cat -r 2 b + b (no-eol) + $ hg rebase --inmemory --debug -r b -d c | grep rebasing + rebasing in-memory + rebasing 2:db0e82a16a62 "b" (b) + $ hg tglog + o 3: ca58782ad1e4 'b' + | + o 2: 814f6bd05178 'c' + | + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 b + b (no-eol) + $ hg cat -r 2 c + c (no-eol) + +Case 2: + $ hg init repo2 + $ cd repo2 + $ hg debugdrawdag <<'EOS' + > c b + > |/ + > d + > | + > a + > EOS + +Add a symlink and executable file: + $ hg up -C c + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ ln -s somefile e + $ echo f > f + $ chmod +x f + $ hg add e f + $ hg amend -q + $ hg up -Cq a + +Write files to the working copy, and ensure they're still there after the rebase + $ echo "abc" > a + $ ln -s def b + $ echo "ghi" > c + $ echo "jkl" > d + $ echo "mno" > e + $ hg tglog + o 3: f56b71190a8f 'c' + | + | o 2: db0e82a16a62 'b' + |/ + o 1: 02952614a83d 'd' + | + @ 0: b173517d0057 'a' + + $ hg cat -r 3 c + c (no-eol) + $ hg cat -r 2 b + b (no-eol) + $ hg cat -r 3 e + somefile (no-eol) + $ hg rebase --inmemory --debug -s b -d a | grep rebasing + rebasing in-memory + rebasing 2:db0e82a16a62 "b" (b) + $ hg tglog + o 3: fc055c3b4d33 'b' + | + | o 2: f56b71190a8f 'c' + | | + | o 1: 02952614a83d 'd' + |/ + @ 0: b173517d0057 'a' + + $ hg cat -r 2 c + c (no-eol) + $ hg cat -r 3 b + b (no-eol) + $ hg rebase --inmemory --debug -s 1 -d 3 | grep rebasing + rebasing in-memory + rebasing 1:02952614a83d "d" (d) + rebasing 2:f56b71190a8f "c" + $ hg tglog + o 3: 753feb6fd12a 'c' + | + o 2: 09c044d2cb43 'd' + | + o 1: fc055c3b4d33 'b' + | + @ 0: b173517d0057 'a' + +Ensure working copy files are still there: + $ cat a + abc + $ readlink b + def + $ cat e + mno + +Ensure symlink and executable files were rebased properly: + $ hg up -Cq 3 + $ readlink e + somefile + $ ls -l f | cut -f1 -d ' ' + -rwxr-xr-x + +Rebase the working copy parent, which should default to an on-disk merge even if +we requested in-memory. + $ hg up -C 3 + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg rebase -r 3 -d 0 --inmemory --debug | grep rebasing + rebasing on disk + rebasing 3:753feb6fd12a "c" (tip) + $ hg tglog + @ 3: 844a7de3e617 'c' + | + | o 2: 09c044d2cb43 'd' + | | + | o 1: fc055c3b4d33 'b' + |/ + o 0: b173517d0057 'a' + + diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -386,8 +386,10 @@ if self.inmemory: from mercurial.context import overlayworkingctx self.wctx = overlayworkingctx(self.repo) +self.repo.ui.debug("rebasing in-memory\n") else: self.wctx = self.repo[None] +self.repo.ui.debug("rebasing on disk\n") def _performrebase(self, tr): self._assignworkingcopy() To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1652: tests: add a simple test for in-memory rebase
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This is just a very simple start, but verifies some of the basic cases of an in-memory rebase. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1652 AFFECTED FILES tests/test-imm.t tests/test-rebase-inmemory.t CHANGE DETAILS diff --git a/tests/test-imm.t b/tests/test-rebase-inmemory.t rename from tests/test-imm.t rename to tests/test-rebase-inmemory.t --- a/tests/test-imm.t +++ b/tests/test-rebase-inmemory.t @@ -1,13 +1,15 @@ -Setup $ cat << EOF >> $HGRCPATH > [extensions] + > amend= > rebase= > debugdrawdag=$TESTDIR/drawdag.py > [diff] > git=1 + > [alias] + > tglog = log -G --template "{rev}: {node|short} '{desc}'\n" > EOF -It works well for disparate parents. +Rebase a simple DAG: $ hg init repo1 $ cd repo1 $ hg debugdrawdag <<'EOS' @@ -19,89 +21,37 @@ > EOS $ hg up -C a 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg log -G -T '{node|short}: {rev} ({desc})' - o 814f6bd05178: 3 (c) + $ hg tglog + o 3: 814f6bd05178 'c' | - | o db0e82a16a62: 2 (b) + | o 2: db0e82a16a62 'b' |/ - o 02952614a83d: 1 (d) + o 1: 02952614a83d 'd' | - @ b173517d0057: 0 (a) + @ 0: b173517d0057 'a' - - $ hg export 3 - # HG changeset patch - # User test - # Date 0 0 - # Thu Jan 01 00:00:00 1970 + - # Node ID 814f6bd051784616494e0d357c1cf342c4412d9b - # Parent 02952614a83d315dda1e5f11662dca1c0cdb4de8 - c - - diff --git a/c b/c - new file mode 100644 - --- /dev/null - +++ b/c - @@ -0,0 +1,1 @@ - +c - \ No newline at end of file - $ hg cat -r 3 c c (no-eol) $ hg cat -r 2 b b (no-eol) - $ hg rebase --inmemory --debug -r b -d c | grep rebasing rebasing in-memory rebasing 2:db0e82a16a62 "b" (b) - $ hg log -G -T '{node|short}: {rev} ({desc})' - o ca58782ad1e4: 3 (b) + $ hg tglog + o 3: ca58782ad1e4 'b' | - o 814f6bd05178: 2 (c) + o 2: 814f6bd05178 'c' | - o 02952614a83d: 1 (d) + o 1: 02952614a83d 'd' | - @ b173517d0057: 0 (a) + @ 0: b173517d0057 'a' $ hg cat -r 3 b b (no-eol) - $ hg cat -r 1 c - c: no such file in rev 02952614a83d - [1] - $ hg log -r 3 -T json - [ - { -"rev": 3, -"node": "ca58782ad1e4f59977cdedfd7bca25fe048aaed8", -"branch": "default", -"phase": "draft", -"user": "test", -"date": [0, 0], -"desc": "b", -"bookmarks": [], -"tags": ["tip"], -"parents": ["814f6bd051784616494e0d357c1cf342c4412d9b"] - } - ] - $ hg export 3 - # HG changeset patch - # User test - # Date 0 0 - # Thu Jan 01 00:00:00 1970 + - # Node ID ca58782ad1e4f59977cdedfd7bca25fe048aaed8 - # Parent 814f6bd051784616494e0d357c1cf342c4412d9b - b - - diff --git a/b b/b - new file mode 100644 - --- /dev/null - +++ b/b - @@ -0,0 +1,1 @@ - +b - \ No newline at end of file + $ hg cat -r 2 c + c (no-eol) - -Not so well for: +Case 2: $ hg init repo2 $ cd repo2 $ hg debugdrawdag <<'EOS' @@ -111,138 +61,96 @@ > | > a > EOS - $ hg up -C a - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg log -G -T '{node|short}: {rev} ({desc})' - o 814f6bd05178: 3 (c) + +Add a symlink and executable file: + $ hg up -C c + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ ln -s somefile e + $ echo f > f + $ chmod +x f + $ hg add e f + $ hg amend -q + $ hg up -Cq a + +Write files to the working copy, and ensure they're still there after the rebase + $ echo "abc" > a + $ ln -s def b + $ echo "ghi" > c + $ echo "jkl" > d + $ echo "mno" > e + $ hg tglog + o 3: f56b71190a8f 'c' | - | o db0e82a16a62: 2 (b) + | o 2: db0e82a16a62 'b' |/ - o 02952614a83d: 1 (d) + o 1: 02952614a83d 'd' | - @ b173517d0057: 0 (a) + @ 0: b173517d0057 'a' - - $ hg cat -r 3 c c (no-eol) $ hg cat -r 2 b b (no-eol) - $ hg rebase --inmemory --debug -r b -d a | grep rebasing + $ hg cat -r 3 e + somefile (no-eol) + $ hg rebase --inmemory --debug -s b -d a | grep rebasing rebasing in-memory rebasing 2:db0e82a16a62 "b" (b) - $ hg log -G -T '{node|short}: {rev} ({desc})' - o fc055c3b4d33: 3 (b) + $ hg tglog + o 3: fc055c3b4d33 'b' | - | o 814f6bd05178: 2 (c) + | o 2: f56b71190a8f 'c' | | - | o 02952614a83d: 1 (d) + | o 1: 02952614a83d 'd' |/ - @ b173517d0057: 0 (a) + @ 0: b173517d0057 'a' - - - $ echo "aaa" > a - $ echo "aaa" > b - $ echo "aaa" > c - $ echo "aaa" > d - $ echo "aaa" > e + $ hg cat -r 2 c + c (no-eol) + $ hg cat -r 3 b + b (no-eol) $ hg rebase --inmemory --debug -s 1 -d 3 | grep rebasing rebasing in-memory rebasing 1:02952614a83d "d" (d) - rebasing 2:814f6bd05178 "c" (c) - $ hg log -G -T '{node|short}: {rev} ({desc})' - o 231d1cda1460: 3 (c) + rebasing 2:f56b71190a8f "c" + $ hg tglog + o 3:
D1650: tests: add commit hashes to log commands in rebase tests
phillco added a comment. (To make this easier to review, I sent https://phab.mercurial-scm.org/D1651 as an abandoned diff that just makes the changes to the `log -G` calls. You could take that one, then run the whole test suite and accept the changes, if it'd be easier to review.) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1650 To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1651: tests: change log templates to include hashes
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1651 AFFECTED FILES tests/test-mq-header-date.t tests/test-mq-header-from.t tests/test-mq-pull-from-bundle.t tests/test-rebase-base-flag.t tests/test-rebase-bookmarks.t tests/test-rebase-collapse.t tests/test-rebase-dest.t tests/test-rebase-detach.t tests/test-rebase-interruptions.t tests/test-rebase-issue-noparam-single-rev.t tests/test-rebase-mq-skip.t tests/test-rebase-mq.t tests/test-rebase-named-branches.t tests/test-rebase-newancestor.t tests/test-rebase-parameters.t tests/test-rebase-partial.t tests/test-rebase-pull.t tests/test-rebase-rename.t tests/test-rebase-scenario-global.t CHANGE DETAILS diff --git a/tests/test-rebase-scenario-global.t b/tests/test-rebase-scenario-global.t --- a/tests/test-rebase-scenario-global.t +++ b/tests/test-rebase-scenario-global.t @@ -7,7 +7,7 @@ > publish=False > > [alias] - > tglog = log -G --template "{rev}: '{desc}' {branches}\n" + > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n" > EOF diff --git a/tests/test-rebase-rename.t b/tests/test-rebase-rename.t --- a/tests/test-rebase-rename.t +++ b/tests/test-rebase-rename.t @@ -3,7 +3,7 @@ > rebase= > > [alias] - > tlog = log --template "{rev}: '{desc}' {branches}\n" + > tlog = log --template "{rev}: {node|short} '{desc}' {branches}\n" > tglog = tlog --graph > EOF diff --git a/tests/test-rebase-pull.t b/tests/test-rebase-pull.t --- a/tests/test-rebase-pull.t +++ b/tests/test-rebase-pull.t @@ -4,7 +4,7 @@ > histedit= > > [alias] - > tglog = log -G --template "{rev}: '{desc}' {branches}\n" + > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n" > EOF diff --git a/tests/test-rebase-partial.t b/tests/test-rebase-partial.t --- a/tests/test-rebase-partial.t +++ b/tests/test-rebase-partial.t @@ -11,7 +11,7 @@ > evolution.allowunstable=True > > [alias] - > tglog = log -G --template "{rev}: {desc}" + > tglog = log -G --template "{rev}: {node|short} {desc}" > EOF $ rebasewithdag() { diff --git a/tests/test-rebase-parameters.t b/tests/test-rebase-parameters.t --- a/tests/test-rebase-parameters.t +++ b/tests/test-rebase-parameters.t @@ -6,7 +6,7 @@ > publish=False > > [alias] - > tglog = log -G --template "{rev}: '{desc}' {branches}\n" + > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n" > EOF diff --git a/tests/test-rebase-newancestor.t b/tests/test-rebase-newancestor.t --- a/tests/test-rebase-newancestor.t +++ b/tests/test-rebase-newancestor.t @@ -5,7 +5,7 @@ > rebase= > drawdag=$TESTDIR/drawdag.py > [alias] - > tglog = log -G --template "{rev}: '{desc}' {branches}\n" + > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n" > EOF $ hg init repo diff --git a/tests/test-rebase-named-branches.t b/tests/test-rebase-named-branches.t --- a/tests/test-rebase-named-branches.t +++ b/tests/test-rebase-named-branches.t @@ -6,7 +6,7 @@ > publish=False > > [alias] - > tglog = log -G --template "{rev}: '{desc}' {branches}\n" + > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n" > EOF $ hg init a diff --git a/tests/test-rebase-mq.t b/tests/test-rebase-mq.t --- a/tests/test-rebase-mq.t +++ b/tests/test-rebase-mq.t @@ -7,7 +7,7 @@ > plain=true > > [alias] - > tglog = log -G --template "{rev}: '{desc}' tags: {tags}\n" + > tglog = log -G --template "{rev}: {node|short} '{desc}' tags: {tags}\n" > EOF diff --git a/tests/test-rebase-mq-skip.t b/tests/test-rebase-mq-skip.t --- a/tests/test-rebase-mq-skip.t +++ b/tests/test-rebase-mq-skip.t @@ -12,7 +12,7 @@ > publish=False > > [alias] - > tglog = log -G --template "{rev}: '{desc}' tags: {tags}\n" + > tglog = log -G --template "{rev}: {node|short} '{desc}' tags: {tags}\n" > EOF diff --git a/tests/test-rebase-issue-noparam-single-rev.t b/tests/test-rebase-issue-noparam-single-rev.t --- a/tests/test-rebase-issue-noparam-single-rev.t +++ b/tests/test-rebase-issue-noparam-single-rev.t @@ -6,7 +6,7 @@ > publish=False > > [alias] - > tglog = log -G --template "{rev}: '{desc}' {branches}\n" + > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n" > EOF diff --git a/tests/test-rebase-interruptions.t b/tests/test-rebase-interruptions.t --- a/tests/test-rebase-interruptions.t +++ b/tests/test-rebase-interruptions.t @@ -6,8 +6,8 @@ > publish=False > > [alias] - > tglog = log -G --template "{rev}: '{desc}' {branches}\n" - > tglogp = log -G --template "{rev}:{phase} '{desc}' {branches}\n" + > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n" + > tglogp = log -G --template "{rev}: {node|short} {phase} '{desc}' {branches}\n" > EOF diff
D1650: tests: add commit hashes to log commands in rebase tests
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Commit hashes are a useful way to ensure the content of commits made in the tests are not changing, even if we don't query every aspect of every commit. (And some properties, like extras, are rarely printed at all.) Many of the rebase log -G calls didn't show hashes; by adding hashes to places that weren't showing them we can help protect those tests from unwanted changes. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1650 AFFECTED FILES tests/test-mq-header-date.t tests/test-mq-header-from.t tests/test-mq-pull-from-bundle.t tests/test-rebase-base-flag.t tests/test-rebase-bookmarks.t tests/test-rebase-collapse.t tests/test-rebase-dest.t tests/test-rebase-detach.t tests/test-rebase-interruptions.t tests/test-rebase-issue-noparam-single-rev.t tests/test-rebase-mq-skip.t tests/test-rebase-mq.t tests/test-rebase-named-branches.t tests/test-rebase-newancestor.t tests/test-rebase-parameters.t tests/test-rebase-partial.t tests/test-rebase-pull.t tests/test-rebase-rename.t tests/test-rebase-scenario-global.t To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1617: rebase: extract _assignworkingcopy
This revision was automatically updated to reflect the committed changes. Closed by commit rHG8dba17546016: rebase: extract _assignworkingcopy (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1617?vs=4277=4286 REVISION DETAIL https://phab.mercurial-scm.org/D1617 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -382,14 +382,16 @@ self.prepared = True -def _performrebase(self, tr): -repo, ui = self.repo, self.ui -# Assign a working copy object. +def _assignworkingcopy(self): if self.inmemory: from mercurial.context import overlayworkingctx self.wctx = overlayworkingctx(self.repo) else: self.wctx = self.repo[None] + +def _performrebase(self, tr): +self._assignworkingcopy() +repo, ui = self.repo, self.ui if self.keepbranchesf: # insert _savebranch at the start of extrafns so if # there's a user-provided extrafn it can clobber branch if To: phillco, #hg-reviewers, dlax Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1616: rebase: disable `inmemory` if the rebaseset contains the working copy
This revision was automatically updated to reflect the committed changes. Closed by commit rHG03bec089e105: rebase: disable `inmemory` if the rebaseset contains the working copy (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1616?vs=4276=4285 REVISION DETAIL https://phab.mercurial-scm.org/D1616 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -830,7 +830,8 @@ else: destmap = _definedestmap(ui, repo, destf, srcf, basef, revf, destspace=destspace, - inmemory=opts['inmemory']) + opts=opts) +rbsrt.inmemory = opts['inmemory'] retcode = rbsrt._preparenewrebase(destmap) if retcode is not None: return retcode @@ -850,7 +851,7 @@ rbsrt._finishrebase() def _definedestmap(ui, repo, destf=None, srcf=None, basef=None, revf=None, - destspace=None, inmemory=False): + destspace=None, opts=None): """use revisions argument to define destmap {srcrev: destrev}""" if revf is None: revf = [] @@ -864,7 +865,7 @@ if revf and srcf: raise error.Abort(_('cannot specify both a revision and a source')) -if not inmemory: +if not opts['inmemory']: cmdutil.checkunfinished(repo) cmdutil.bailifchanged(repo) @@ -939,6 +940,22 @@ ui.status(_('nothing to rebase from %s to %s\n') % ('+'.join(str(repo[r]) for r in base), dest)) return None +# If rebasing the working copy parent, force in-memory merge to be off. +# +# This is because the extra work of checking out the newly rebased commit +# outweights the benefits of rebasing in-memory, and executing an extra +# update command adds a bit of overhead, so better to just do it on disk. In +# all other cases leave it on. +# +# Note that there are cases where this isn't true -- e.g., rebasing large +# stacks that include the WCP. However, I'm not yet sure where the cutoff +# is. +rebasingwcp = repo['.'].rev() in rebaseset +if opts['inmemory'] and rebasingwcp: +opts['inmemory'] = False +# Check these since we did not before. +cmdutil.checkunfinished(repo) +cmdutil.bailifchanged(repo) if not destf: dest = repo[_destrebase(repo, rebaseset, destspace=destspace)] To: phillco, #hg-reviewers, dlax Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1617: rebase: extract _assignworkingcopy
phillco updated this revision to Diff 4277. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1617?vs=4248=4277 REVISION DETAIL https://phab.mercurial-scm.org/D1617 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -382,14 +382,16 @@ self.prepared = True -def _performrebase(self, tr): -repo, ui = self.repo, self.ui -# Assign a working copy object. +def _assignworkingcopy(self): if self.inmemory: from mercurial.context import overlayworkingctx self.wctx = overlayworkingctx(self.repo) else: self.wctx = self.repo[None] + +def _performrebase(self, tr): +self._assignworkingcopy() +repo, ui = self.repo, self.ui if self.keepbranchesf: # insert _savebranch at the start of extrafns so if # there's a user-provided extrafn it can clobber branch if To: phillco, #hg-reviewers, dlax Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1616: rebase: disable `inmemory` if the rebaseset contains the working copy
phillco updated this revision to Diff 4276. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1616?vs=4247=4276 REVISION DETAIL https://phab.mercurial-scm.org/D1616 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -830,7 +830,8 @@ else: destmap = _definedestmap(ui, repo, destf, srcf, basef, revf, destspace=destspace, - inmemory=opts['inmemory']) + opts=opts) +rbsrt.inmemory = opts['inmemory'] retcode = rbsrt._preparenewrebase(destmap) if retcode is not None: return retcode @@ -850,7 +851,7 @@ rbsrt._finishrebase() def _definedestmap(ui, repo, destf=None, srcf=None, basef=None, revf=None, - destspace=None, inmemory=False): + destspace=None, opts=None): """use revisions argument to define destmap {srcrev: destrev}""" if revf is None: revf = [] @@ -864,7 +865,7 @@ if revf and srcf: raise error.Abort(_('cannot specify both a revision and a source')) -if not inmemory: +if not opts['inmemory']: cmdutil.checkunfinished(repo) cmdutil.bailifchanged(repo) @@ -939,6 +940,22 @@ ui.status(_('nothing to rebase from %s to %s\n') % ('+'.join(str(repo[r]) for r in base), dest)) return None +# If rebasing the working copy parent, force in-memory merge to be off. +# +# This is because the extra work of checking out the newly rebased commit +# outweights the benefits of rebasing in-memory, and executing an extra +# update command adds a bit of overhead, so better to just do it on disk. In +# all other cases leave it on. +# +# Note that there are cases where this isn't true -- e.g., rebasing large +# stacks that include the WCP. However, I'm not yet sure where the cutoff +# is. +rebasingwcp = repo['.'].rev() in rebaseset +if opts['inmemory'] and rebasingwcp: +opts['inmemory'] = False +# Check these since we did not before. +cmdutil.checkunfinished(repo) +cmdutil.bailifchanged(repo) if not destf: dest = repo[_destrebase(repo, rebaseset, destspace=destspace)] To: phillco, #hg-reviewers, dlax Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1244: overlayworkingctx: invalidate the manifest cache when changing parents
This revision was automatically updated to reflect the committed changes. Closed by commit rHG777cb4497d8d: overlayworkingctx: invalidate the manifest cache when changing parents (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1244?vs=4258=4273 REVISION DETAIL https://phab.mercurial-scm.org/D1244 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1999,6 +1999,10 @@ def setbase(self, wrappedctx): self._wrappedctx = wrappedctx self._parents = [wrappedctx] +# Drop old manifest cache as it is now out of date. +# This is necessary when, e.g., rebasing several nodes with one +# ``overlayworkingctx`` (e.g. with --collapse). +util.clearcachedproperty(self, '_manifest') def data(self, path): if self.isdirty(path): To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1243: overlayworkingctx: add `_compact()`
This revision was automatically updated to reflect the committed changes. Closed by commit rHGdc9da4f4f363: overlayworkingctx: add `_compact()` (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1243?vs=4249=4272 REVISION DETAIL https://phab.mercurial-scm.org/D1243 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2225,6 +2225,29 @@ def clean(self): self._cache = {} +def _compact(self): +"""Removes keys from the cache that are actually clean, by comparing +them with the underlying context. + +This can occur during the merge process, e.g. by passing --tool :local +to resolve a conflict. +""" +keys = [] +for path in self._cache.keys(): +cache = self._cache[path] +try: +underlying = self._wrappedctx[path] +if (underlying.data() == cache['data'] and +underlying.flags() == cache['flags']): +keys.append(path) +except error.ManifestLookupError: +# Path not in the underlying manifest (created). +continue + +for path in keys: +del self._cache[path] +return keys + def _markdirty(self, path, exists, data=None, date=None, flags=''): self._cache[path] = { 'exists': exists, To: phillco, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1238: overlayworkingctx: add _manifest, files(), added(), removed(), modified()
This revision was automatically updated to reflect the committed changes. Closed by commit rHG2e1c32a9c97b: overlayworkingctx: add _manifest, files(), added(), removed(), modified() (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1238?vs=4230=4267 REVISION DETAIL https://phab.mercurial-scm.org/D1238 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2014,6 +2014,43 @@ else: return self._wrappedctx[path].data() +@propertycache +def _manifest(self): +parents = self.parents() +man = parents[0].manifest().copy() + +flag = self._flagfunc +for path in self.added(): +man[path] = addednodeid +man.setflag(path, flag(path)) +for path in self.modified(): +man[path] = modifiednodeid +man.setflag(path, flag(path)) +for path in self.removed(): +del man[path] +return man + +@propertycache +def _flagfunc(self): +def f(path): +return self._cache[path]['flags'] +return f + +def files(self): +return sorted(self.added() + self.modified() + self.removed()) + +def modified(self): +return [f for f in self._cache.keys() if self._cache[f]['exists'] and +self._existsinparent(f)] + +def added(self): +return [f for f in self._cache.keys() if self._cache[f]['exists'] and +not self._existsinparent(f)] + +def removed(self): +return [f for f in self._cache.keys() if +not self._cache[f]['exists'] and self._existsinparent(f)] + def isinmemory(self): return True To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1242: overlayworkingctx: add ``tomemctx()`` and ``commit()``
This revision was automatically updated to reflect the committed changes. Closed by commit rHG71edd38c4bb4: overlayworkingctx: add ``tomemctx()`` (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1242?vs=4234=4271 REVISION DETAIL https://phab.mercurial-scm.org/D1242 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2177,6 +2177,42 @@ self._path) return self._wrappedctx[path].size() +def tomemctx(self, text, branch=None, extra=None, date=None, parents=None, + user=None, editor=None): +"""Converts this ``overlayworkingctx`` into a ``memctx`` ready to be +committed. + +``text`` is the commit message. +``parents`` (optional) are rev numbers. +""" +# Default parents to the wrapped contexts' if not passed. +if parents is None: +parents = self._wrappedctx.parents() +if len(parents) == 1: +parents = (parents[0], None) + +# ``parents`` is passed as rev numbers; convert to ``commitctxs``. +if parents[1] is None: +parents = (self._repo[parents[0]], None) +else: +parents = (self._repo[parents[0]], self._repo[parents[1]]) + +files = self._cache.keys() +def getfile(repo, memctx, path): +if self._cache[path]['exists']: +return memfilectx(repo, path, + self._cache[path]['data'], + 'l' in self._cache[path]['flags'], + 'x' in self._cache[path]['flags'], + self._cache[path]['copied'], + memctx) +else: +# Returning None, but including the path in `files`, is +# necessary for memctx to register a deletion. +return None +return memctx(self._repo, parents, text, files, getfile, date=date, + extra=extra, user=user, branch=branch, editor=editor) + def isdirty(self, path): return path in self._cache To: phillco, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1241: overlayworkingctx: add _auditconflicts to write()
This revision was automatically updated to reflect the committed changes. Closed by commit rHG72fbdd373de8: overlayworkingctx: add _auditconflicts to write() (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1241?vs=4233=4270 REVISION DETAIL https://phab.mercurial-scm.org/D1241 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2092,9 +2092,50 @@ except error.ManifestLookupError: return False +def _auditconflicts(self, path): +"""Replicates conflict checks done by wvfs.write(). + +Since we never write to the filesystem and never call `applyupdates` in +IMM, we'll never check that a path is actually writable -- e.g., because +it adds `a/foo`, but `a` is actually a file in the other commit. +""" +def fail(path, component): +# p1() is the base and we're receiving "writes" for p2()'s +# files. +if 'l' in self.p1()[component].flags(): +raise error.Abort("error: %s conflicts with symlink %s " + "in %s." % (path, component, + self.p1().rev())) +else: +raise error.Abort("error: '%s' conflicts with file '%s' in " + "%s." % (path, component, + self.p1().rev())) + +# Test that each new directory to be created to write this path from p2 +# is not a file in p1. +components = path.split('/') +for i in xrange(len(components)): +component = "/".join(components[0:i]) +if component in self.p1(): +fail(path, component) + +# Test the other direction -- that this path from p2 isn't a directory +# in p1 (test that p1 doesn't any paths matching `path/*`). +match = matchmod.match('/', '', [path + '/'], default=b'relpath') +matches = self.p1().manifest().matches(match) +if len(matches) > 0: +if len(matches) == 1 and matches.keys()[0] == path: +return +raise error.Abort("error: file '%s' cannot be written because " + " '%s/' is a folder in %s (containing %d " + "entries: %s)" + % (path, path, self.p1(), len(matches), + ', '.join(matches.keys( + def write(self, path, data, flags=''): if data is None: raise error.ProgrammingError("data must be non-None") +self._auditconflicts(path) self._markdirty(path, exists=True, data=data, date=util.makedate(), flags=flags) To: phillco, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1239: overlayworkingctx: add a no-op ``clearunknown()``
This revision was automatically updated to reflect the committed changes. Closed by commit rHGbaf58e621363: overlayworkingctx: add a no-op ``clearunknown()`` (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1239?vs=4231=4268 REVISION DETAIL https://phab.mercurial-scm.org/D1239 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2217,6 +2217,9 @@ def remove(self, ignoremissing=False): return self._parent.remove(self._path) +def clearunknown(self): +pass + class workingcommitctx(workingctx): """A workingcommitctx object makes access to data related to the revision being committed convenient. To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1240: overlayworkingctx: inherit from committablectx instead of workingctx
This revision was automatically updated to reflect the committed changes. Closed by commit rHG8e1386b342f7: overlayworkingctx: inherit from committablectx instead of workingctx (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1240?vs=4232=4269 REVISION DETAIL https://phab.mercurial-scm.org/D1240 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1976,9 +1976,9 @@ def setflags(self, l, x): self._repo.wvfs.setflags(self._path, l, x) -class overlayworkingctx(workingctx): -"""Wraps another mutable context with a write-back cache that can be flushed -at a later time. +class overlayworkingctx(committablectx): +"""Wraps another mutable context with a write-back cache that can be +converted into a commit context. self._cache[path] maps to a dict with keys: { 'exists': bool? @@ -2161,7 +2161,7 @@ return overlayworkingfilectx(self._repo, path, parent=self, filelog=filelog) -class overlayworkingfilectx(workingfilectx): +class overlayworkingfilectx(committablefilectx): """Wrap a ``workingfilectx`` but intercepts all writes into an in-memory cache, which can be flushed through later by calling ``flush()``.""" To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1248: rebase: add concludememorynode(), and call it when rebasing in-memory
This revision was automatically updated to reflect the committed changes. Closed by commit rHG228916ca12b5: rebase: add concludememorynode(), and call it when rebasing in-memory (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1248?vs=4245=4265 REVISION DETAIL https://phab.mercurial-scm.org/D1248 AFFECTED FILES hgext/rebase.py mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2102,6 +2102,12 @@ def isdirty(self, path): return path in self._cache +def isempty(self): +# We need to discard any keys that are actually clean before the empty +# commit check. +self._compact() +return len(self._cache) == 0 + def clean(self): self._cache = {} diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -495,11 +495,21 @@ merging = p2 != nullrev editform = cmdutil.mergeeditform(merging, 'rebase') editor = cmdutil.getcommiteditor(editform=editform, **opts) -newnode = concludenode(repo, rev, p1, p2, - extrafn=_makeextrafn(self.extrafns), - editor=editor, - keepbranches=self.keepbranchesf, - date=self.date) +if self.wctx.isinmemory(): +newnode = concludememorynode(repo, rev, p1, p2, +wctx=self.wctx, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) +mergemod.mergestate.clean(repo) +else: +newnode = concludenode(repo, rev, p1, p2, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) + if newnode is None: # If it ended up being a no-op commit, then the normal # merge state clean-up path doesn't happen, so do it @@ -552,13 +562,22 @@ dsguard = None if ui.configbool('rebase', 'singletransaction'): dsguard = dirstateguard.dirstateguard(repo, 'rebase') -with util.acceptintervention(dsguard): -newnode = concludenode(repo, revtoreuse, p1, self.external, - commitmsg=commitmsg, - extrafn=_makeextrafn(self.extrafns), - editor=editor, - keepbranches=self.keepbranchesf, - date=self.date) +if self.inmemory: +newnode = concludememorynode(repo, revtoreuse, p1, +self.external, +commitmsg=commitmsg, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date, wctx=self.wctx) +else: +with util.acceptintervention(dsguard): +newnode = concludenode(repo, revtoreuse, p1, self.external, +commitmsg=commitmsg, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) if newnode is not None: newrev = repo[newnode].rev() for oldrev in self.state.iterkeys(): @@ -964,6 +983,44 @@ (max(destancestors), ', '.join(str(p) for p in sorted(parents +def concludememorynode(repo, rev, p1, p2, wctx=None, + commitmsg=None, editor=None, extrafn=None, + keepbranches=False, date=None): +'''Commit the wd changes with parents p1 and p2. Reuse commit info from rev +but also store useful information in extra. +Return node of committed revision.''' +ctx = repo[rev] +if commitmsg is None: +commitmsg = ctx.description() +keepbranch = keepbranches and repo[p1].branch() != ctx.branch() +extra = {'rebase_source': ctx.hex()} +if extrafn: +extrafn(ctx, extra) + +destphase = max(ctx.phase(), phases.draft) +overrides = {('phases', 'new-commit'): destphase} +with repo.ui.configoverride(overrides, 'rebase'): +if keepbranch: +
D1245: rebase: pass wctx to rebasenode()
This revision was automatically updated to reflect the committed changes. Closed by commit rHG259feddc04e6: rebase: pass wctx to rebasenode() (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1245?vs=4260=4262 REVISION DETAIL https://phab.mercurial-scm.org/D1245 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -481,7 +481,7 @@ ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'rebase') stats = rebasenode(repo, rev, p1, base, self.state, - self.collapsef, dest) + self.collapsef, dest, wctx=self.wctx) if stats and stats[3] > 0: if self.wctx.isinmemory(): raise error.InMemoryMergeConflictsError() @@ -992,7 +992,7 @@ repo.dirstate.setbranch(repo[newnode].branch()) return newnode -def rebasenode(repo, rev, p1, base, state, collapse, dest): +def rebasenode(repo, rev, p1, base, state, collapse, dest, wctx): 'Rebase a single revision rev on top of p1 using base as merge ancestor' # Merge phase # Update to destination and merge it with local To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1247: rebase: pass the wctx object (IMM or on-disk) to merge.update
This revision was automatically updated to reflect the committed changes. Closed by commit rHG2bac2d836ce0: rebase: pass the wctx object (IMM or on-disk) to merge.update (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1247?vs=4212=4264 REVISION DETAIL https://phab.mercurial-scm.org/D1247 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -1017,7 +1017,7 @@ # When collapsing in-place, the parent is the common ancestor, we # have to allow merging with it. stats = mergemod.update(repo, rev, True, True, base, collapse, -labels=['dest', 'source']) +labels=['dest', 'source'], wc=wctx) if collapse: copies.duplicatecopies(repo, wctx, rev, dest) else: To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1249: rebase: rerun a rebase on-disk if IMM merge conflicts arise
This revision was automatically updated to reflect the committed changes. Closed by commit rHGd901a88891fe: rebase: rerun a rebase on-disk if IMM merge conflicts arise (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1249?vs=4261=4266 REVISION DETAIL https://phab.mercurial-scm.org/D1249 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -759,6 +759,25 @@ unresolved conflicts. """ +if opts.get('continue') or opts.get('abort'): +# in-memory rebase is not compatible with resuming rebases. +opts['inmemory'] = False + +if opts.get('inmemory', False): +try: +# in-memory merge doesn't support conflicts, so if we hit any, abort +# and re-run as an on-disk merge. +return _origrebase(ui, repo, **opts) +except error.InMemoryMergeConflictsError: +ui.warn(_('hit merge conflicts; re-running rebase without in-memory' + ' merge\n')) +_origrebase(ui, repo, **{'abort': True}) +opts['inmemory'] = False +return _origrebase(ui, repo, **opts) +else: +return _origrebase(ui, repo, **opts) + +def _origrebase(ui, repo, **opts): opts = pycompat.byteskwargs(opts) if 'inmemory' not in opts: opts['inmemory'] = False To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1246: rebase: do not update if IMM; instead, set the overlaywctx's parents
This revision was automatically updated to reflect the committed changes. Closed by commit rHG5c25fe7fb1e6: rebase: do not update if IMM; instead, set the overlaywctxs parents (authored by phillco, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1246?vs=4259=4263 REVISION DETAIL https://phab.mercurial-scm.org/D1246 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -507,7 +507,10 @@ mergemod.mergestate.clean(repo) else: # Skip commit if we are collapsing -repo.setparents(repo[p1].node()) +if self.wctx.isinmemory(): +self.wctx.setbase(repo[p1]) +else: +repo.setparents(repo[p1].node()) newnode = None # Update the state if newnode is not None: @@ -570,7 +573,8 @@ if newwd < 0: # original directory is a parent of rebase set root or ignored newwd = self.originalwd -if newwd not in [c.rev() for c in repo[None].parents()]: +if (newwd not in [c.rev() for c in repo[None].parents()] and +not self.inmemory): ui.note(_("update back to initial working directory parent\n")) hg.updaterepo(repo, newwd, False) @@ -996,18 +1000,22 @@ 'Rebase a single revision rev on top of p1 using base as merge ancestor' # Merge phase # Update to destination and merge it with local -if repo['.'].rev() != p1: -repo.ui.debug(" update to %d:%s\n" % (p1, repo[p1])) -mergemod.update(repo, p1, False, True) +if wctx.isinmemory(): +wctx.setbase(repo[p1]) else: -repo.ui.debug(" already in destination\n") -repo.dirstate.write(repo.currenttransaction()) +# This is necessary to invalidate workingctx's caches. +wctx = repo[None] +if repo['.'].rev() != p1: +repo.ui.debug(" update to %d:%s\n" % (p1, repo[p1])) +mergemod.update(repo, p1, False, True) +else: +repo.ui.debug(" already in destination\n") +repo.dirstate.write(repo.currenttransaction()) repo.ui.debug(" merge against %d:%s\n" % (rev, repo[rev])) if base is not None: repo.ui.debug(" detach base %d:%s\n" % (base, repo[base])) # When collapsing in-place, the parent is the common ancestor, we # have to allow merging with it. -wctx = repo[None] stats = mergemod.update(repo, rev, True, True, base, collapse, labels=['dest', 'source']) if collapse: To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1249: rebase: rerun a rebase on-disk if IMM merge conflicts arise
phillco added a comment. I've moved the comment back to `rebase()` to fix the help issue. I'm mostly neutral on using recursion or using this approach, though I think having to pass a flag to prevent infinite recursion would be messy. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1249 To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1249: rebase: rerun a rebase on-disk if IMM merge conflicts arise
phillco updated this revision to Diff 4261. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1249?vs=4246=4261 REVISION DETAIL https://phab.mercurial-scm.org/D1249 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -759,6 +759,25 @@ unresolved conflicts. """ +if opts.get('continue') or opts.get('abort'): +# in-memory rebase is not compatible with resuming rebases. +opts['inmemory'] = False + +if opts.get('inmemory', False): +try: +# in-memory merge doesn't support conflicts, so if we hit any, abort +# and re-run as an on-disk merge. +return _origrebase(ui, repo, **opts) +except error.InMemoryMergeConflictsError: +ui.warn(_('hit merge conflicts; re-running rebase without in-memory' + ' merge\n')) +_origrebase(ui, repo, **{'abort': True}) +opts['inmemory'] = False +return _origrebase(ui, repo, **opts) +else: +return _origrebase(ui, repo, **opts) + +def _origrebase(ui, repo, **opts): opts = pycompat.byteskwargs(opts) if 'inmemory' not in opts: opts['inmemory'] = False To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1245: rebase: pass wctx to rebasenode()
phillco added inline comments. INLINE COMMENTS > dlax wrote in rebase.py:995 > Isn't it meant to be used in the function body? I see a `wctx = repo[None]` > below, perhaps it should be dropped. > > But this wouldn't work with a `None` default value as mentioned in the next > patch. Yes, it's used in the next patch. But you're right that it's the only callsite, so I've made it non-optional. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1245 To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1245: rebase: pass wctx to rebasenode()
phillco updated this revision to Diff 4260. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1245?vs=4210=4260 REVISION DETAIL https://phab.mercurial-scm.org/D1245 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -481,7 +481,7 @@ ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'rebase') stats = rebasenode(repo, rev, p1, base, self.state, - self.collapsef, dest) + self.collapsef, dest, wctx=self.wctx) if stats and stats[3] > 0: if self.wctx.isinmemory(): raise error.InMemoryMergeConflictsError() @@ -992,7 +992,7 @@ repo.dirstate.setbranch(repo[newnode].branch()) return newnode -def rebasenode(repo, rev, p1, base, state, collapse, dest): +def rebasenode(repo, rev, p1, base, state, collapse, dest, wctx): 'Rebase a single revision rev on top of p1 using base as merge ancestor' # Merge phase # Update to destination and merge it with local To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1246: rebase: do not update if IMM; instead, set the overlaywctx's parents
phillco added inline comments. INLINE COMMENTS > dlax wrote in rebase.py:1003 > `wctx` has a default value of `None`, so either it shouldn't have that or > there should be a check for `None` here. Good point -- dropped. > dlax wrote in rebase.py:1007 > `wctx` is redefined here. This is intentional. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1246 To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1246: rebase: do not update if IMM; instead, set the overlaywctx's parents
phillco updated this revision to Diff 4259. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1246?vs=4211=4259 REVISION DETAIL https://phab.mercurial-scm.org/D1246 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -507,7 +507,10 @@ mergemod.mergestate.clean(repo) else: # Skip commit if we are collapsing -repo.setparents(repo[p1].node()) +if self.wctx.isinmemory(): +self.wctx.setbase(repo[p1]) +else: +repo.setparents(repo[p1].node()) newnode = None # Update the state if newnode is not None: @@ -570,7 +573,8 @@ if newwd < 0: # original directory is a parent of rebase set root or ignored newwd = self.originalwd -if newwd not in [c.rev() for c in repo[None].parents()]: +if (newwd not in [c.rev() for c in repo[None].parents()] and +not self.inmemory): ui.note(_("update back to initial working directory parent\n")) hg.updaterepo(repo, newwd, False) @@ -996,18 +1000,22 @@ 'Rebase a single revision rev on top of p1 using base as merge ancestor' # Merge phase # Update to destination and merge it with local -if repo['.'].rev() != p1: -repo.ui.debug(" update to %d:%s\n" % (p1, repo[p1])) -mergemod.update(repo, p1, False, True) +if wctx.isinmemory(): +wctx.setbase(repo[p1]) else: -repo.ui.debug(" already in destination\n") -repo.dirstate.write(repo.currenttransaction()) +# This is necessary to invalidate workingctx's caches. +wctx = repo[None] +if repo['.'].rev() != p1: +repo.ui.debug(" update to %d:%s\n" % (p1, repo[p1])) +mergemod.update(repo, p1, False, True) +else: +repo.ui.debug(" already in destination\n") +repo.dirstate.write(repo.currenttransaction()) repo.ui.debug(" merge against %d:%s\n" % (rev, repo[rev])) if base is not None: repo.ui.debug(" detach base %d:%s\n" % (base, repo[base])) # When collapsing in-place, the parent is the common ancestor, we # have to allow merging with it. -wctx = repo[None] stats = mergemod.update(repo, rev, True, True, base, collapse, labels=['dest', 'source']) if collapse: To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1616: rebase: disable `inmemory` if the rebaseset contains the working copy
phillco added a comment. @dlax you mean the parts where we pass `opts` instead of `inmemory`? This is necessary for the function to mutate `opts['inmemory']`. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1616 To: phillco, #hg-reviewers, dlax Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1244: overlayworkingctx: invalidate the manifest cache when changing parents
phillco updated this revision to Diff 4258. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1244?vs=4236=4258 REVISION DETAIL https://phab.mercurial-scm.org/D1244 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1999,6 +1999,10 @@ def setbase(self, wrappedctx): self._wrappedctx = wrappedctx self._parents = [wrappedctx] +# Drop old manifest cache as it is now out of date. +# This is necessary when, e.g., rebasing several nodes with one +# ``overlayworkingctx`` (e.g. with --collapse). +util.clearcachedproperty(self, '_manifest') def data(self, path): if self.isdirty(path): To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1244: overlayworkingctx: invalidate the manifest cache when changing parents
phillco added inline comments. INLINE COMMENTS > dlax wrote in context.py:2003 > Wouldn't `util.clearcachedproperty(self, '_manifest')` work? Thanks! I did not know about it -- will use. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1244 To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1249: rebase: rerun a rebase on-disk if IMM merge conflicts arise
phillco added inline comments. INLINE COMMENTS > durin42 wrote in rebase.py:667 > It's just a style thing. I find avoiding recursion to generally be clearer. > > @phillco dlax is right, the docstring needs fixed here (I'm surprised tests > passed...) huh, weird. not sure how they did. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1249 To: phillco, #hg-reviewers, durin42, dlax Cc: dlax, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1238: overlayworkingctx: add _manifest, files(), added(), removed(), modified()
phillco added a comment. OK, kept it in and passing to `man.setflag()`. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1238 To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1243: overlayworkingctx: add `_compact()`
phillco updated this revision to Diff 4249. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1243?vs=4235=4249 REVISION DETAIL https://phab.mercurial-scm.org/D1243 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2219,6 +2219,29 @@ def clean(self): self._cache = {} +def _compact(self): +"""Removes keys from the cache that are actually clean, by comparing +them with the underlying context. + +This can occur during the merge process, e.g. by passing --tool :local +to resolve a conflict. +""" +keys = [] +for path in self._cache.keys(): +cache = self._cache[path] +try: +underlying = self._wrappedctx[path] +if (underlying.data() == cache['data'] and +underlying.flags() == cache['flags']): +keys.append(path) +except error.ManifestLookupError: +# Path not in the underlying manifest (created). +continue + +for path in keys: +del self._cache[path] +return keys + def _markdirty(self, path, exists, data=None, date=None, flags=''): self._cache[path] = { 'exists': exists, To: phillco, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1617: rebase: extract _assignworkingcopy
phillco updated this revision to Diff 4248. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1617?vs=4243=4248 REVISION DETAIL https://phab.mercurial-scm.org/D1617 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -381,14 +381,16 @@ self.prepared = True -def _performrebase(self, tr): -repo, ui = self.repo, self.ui -# Assign a working copy object. +def _assignworkingcopy(self): if self.inmemory: from mercurial.context import overlayworkingctx self.wctx = overlayworkingctx(self.repo) else: self.wctx = self.repo[None] + +def _performrebase(self, tr): +self._assignworkingcopy() +repo, ui = self.repo, self.ui if self.keepbranchesf: # insert _savebranch at the start of extrafns so if # there's a user-provided extrafn it can clobber branch if To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1248: rebase: add concludememorynode(), and call it when rebasing in-memory
phillco updated this revision to Diff 4245. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1248?vs=4239=4245 REVISION DETAIL https://phab.mercurial-scm.org/D1248 AFFECTED FILES hgext/rebase.py mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2225,6 +2225,12 @@ def isdirty(self, path): return path in self._cache +def isempty(self): +# We need to discard any keys that are actually clean before the empty +# commit check. +self._compact() +return len(self._cache) == 0 + def clean(self): self._cache = {} diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -495,11 +495,21 @@ merging = p2 != nullrev editform = cmdutil.mergeeditform(merging, 'rebase') editor = cmdutil.getcommiteditor(editform=editform, **opts) -newnode = concludenode(repo, rev, p1, p2, - extrafn=_makeextrafn(self.extrafns), - editor=editor, - keepbranches=self.keepbranchesf, - date=self.date) +if self.wctx.isinmemory(): +newnode = concludememorynode(repo, rev, p1, p2, +wctx=self.wctx, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) +mergemod.mergestate.clean(repo) +else: +newnode = concludenode(repo, rev, p1, p2, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) + if newnode is None: # If it ended up being a no-op commit, then the normal # merge state clean-up path doesn't happen, so do it @@ -552,13 +562,22 @@ dsguard = None if ui.configbool('rebase', 'singletransaction'): dsguard = dirstateguard.dirstateguard(repo, 'rebase') -with util.acceptintervention(dsguard): -newnode = concludenode(repo, revtoreuse, p1, self.external, - commitmsg=commitmsg, - extrafn=_makeextrafn(self.extrafns), - editor=editor, - keepbranches=self.keepbranchesf, - date=self.date) +if self.inmemory: +newnode = concludememorynode(repo, revtoreuse, p1, +self.external, +commitmsg=commitmsg, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date, wctx=self.wctx) +else: +with util.acceptintervention(dsguard): +newnode = concludenode(repo, revtoreuse, p1, self.external, +commitmsg=commitmsg, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) if newnode is not None: newrev = repo[newnode].rev() for oldrev in self.state.iterkeys(): @@ -964,6 +983,44 @@ (max(destancestors), ', '.join(str(p) for p in sorted(parents +def concludememorynode(repo, rev, p1, p2, wctx=None, + commitmsg=None, editor=None, extrafn=None, + keepbranches=False, date=None): +'''Commit the wd changes with parents p1 and p2. Reuse commit info from rev +but also store useful information in extra. +Return node of committed revision.''' +ctx = repo[rev] +if commitmsg is None: +commitmsg = ctx.description() +keepbranch = keepbranches and repo[p1].branch() != ctx.branch() +extra = {'rebase_source': ctx.hex()} +if extrafn: +extrafn(ctx, extra) + +destphase = max(ctx.phase(), phases.draft) +overrides = {('phases', 'new-commit'): destphase} +with repo.ui.configoverride(overrides, 'rebase'): +if keepbranch: +repo.ui.setconfig('ui', 'allowemptycommit', True) +# Replicates the empty check in ``repo.commit``. +if wctx.isempty() and not repo.ui.configbool('ui', 'allowemptycommit'): +
D1249: rebase: rerun a rebase on-disk if IMM merge conflicts arise
phillco updated this revision to Diff 4246. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1249?vs=4240=4246 REVISION DETAIL https://phab.mercurial-scm.org/D1249 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -646,6 +646,25 @@ cmdutil.formatteropts, _('[-s REV | -b REV] [-d REV] [OPTION]')) def rebase(ui, repo, **opts): +if opts.get('continue') or opts.get('abort'): +# in-memory rebase is not compatible with resuming rebases. +opts['inmemory'] = False + +if opts.get('inmemory', False): +try: +# in-memory merge doesn't support conflicts, so if we hit any, abort +# and re-run as an on-disk merge. +return _origrebase(ui, repo, **opts) +except error.InMemoryMergeConflictsError: +ui.warn(_('hit merge conflicts; re-running rebase without in-memory' + ' merge\n')) +_origrebase(ui, repo, **{'abort': True}) +opts['inmemory'] = False +return _origrebase(ui, repo, **opts) +else: +return _origrebase(ui, repo, **opts) + +def _origrebase(ui, repo, **opts): """move changeset (and descendants) to a different branch Rebase uses repeated merging to graft changesets from one part of To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1616: rebase: disable `inmemory` if the rebaseset contains the working copy
phillco updated this revision to Diff 4247. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1616?vs=4242=4247 REVISION DETAIL https://phab.mercurial-scm.org/D1616 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -179,7 +179,6 @@ self.keepopen = opts.get('keepopen', False) self.obsoletenotrebased = {} self.obsoletewithoutsuccessorindestination = set() -self.inmemory = opts.get('inmemory', False) @property def repo(self): @@ -830,7 +829,8 @@ else: destmap = _definedestmap(ui, repo, destf, srcf, basef, revf, destspace=destspace, - inmemory=opts['inmemory']) + opts=opts) +rbsrt.inmemory = opts['inmemory'] retcode = rbsrt._preparenewrebase(destmap) if retcode is not None: return retcode @@ -850,7 +850,7 @@ rbsrt._finishrebase() def _definedestmap(ui, repo, destf=None, srcf=None, basef=None, revf=None, - destspace=None, inmemory=False): + destspace=None, opts=None): """use revisions argument to define destmap {srcrev: destrev}""" if revf is None: revf = [] @@ -864,7 +864,7 @@ if revf and srcf: raise error.Abort(_('cannot specify both a revision and a source')) -if not inmemory: +if not opts['inmemory']: cmdutil.checkunfinished(repo) cmdutil.bailifchanged(repo) @@ -939,6 +939,22 @@ ui.status(_('nothing to rebase from %s to %s\n') % ('+'.join(str(repo[r]) for r in base), dest)) return None +# If rebasing the working copy parent, force in-memory merge to be off. +# +# This is because the extra work of checking out the newly rebased commit +# outweights the benefits of rebasing in-memory, and executing an extra +# update command adds a bit of overhead, so better to just do it on disk. In +# all other cases leave it on. +# +# Note that there are cases where this isn't true -- e.g., rebasing large +# stacks that include the WCP. However, I'm not yet sure where the cutoff +# is. +rebasingwcp = repo['.'].rev() in rebaseset +if opts['inmemory'] and rebasingwcp: +opts['inmemory'] = False +# Check these since we did not before. +cmdutil.checkunfinished(repo) +cmdutil.bailifchanged(repo) if not destf: dest = repo[_destrebase(repo, rebaseset, destspace=destspace)] To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1617: rebase: extract _assignworkingcopy
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Slightly cleaner, and makes it easier to hook this in an extension. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1617 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -381,14 +381,16 @@ self.prepared = True -def _performrebase(self, tr): -repo, ui = self.repo, self.ui -# Assign a working copy object. +def _assignworkingcopy(self): if self.inmemory: from mercurial.context import overlayworkingctx self.wctx = overlayworkingctx(self.repo) else: self.wctx = self.repo[None] + +def _performrebase(self, tr): +self._assignworkingcopy() +repo, ui = self.repo, self.ui if self.keepbranchesf: # insert _savebranch at the start of extrafns so if # there's a user-provided extrafn it can clobber branch if To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1616: rebase: disable `inmemory` if the rebaseset contains the working copy
phillco created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY As described in the comment, rebasing the working copy parent with in-memory merge, and then updating to the new commit, isn't much faster because of the extra overhead of uppdating. Best to leavew it off in that case. This commit makes deploying in-memory merge via an extension easier, because you can just set `inmemory=True` based on some config or probability, and this will turn off the cases where it's not desired. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1616 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -179,7 +179,6 @@ self.keepopen = opts.get('keepopen', False) self.obsoletenotrebased = {} self.obsoletewithoutsuccessorindestination = set() -self.inmemory = opts.get('inmemory', False) @property def repo(self): @@ -830,7 +829,8 @@ else: destmap = _definedestmap(ui, repo, destf, srcf, basef, revf, destspace=destspace, - inmemory=opts['inmemory']) + opts=opts) +rbsrt.inmemory = opts['inmemory'] retcode = rbsrt._preparenewrebase(destmap) if retcode is not None: return retcode @@ -850,7 +850,7 @@ rbsrt._finishrebase() def _definedestmap(ui, repo, destf=None, srcf=None, basef=None, revf=None, - destspace=None, inmemory=False): + destspace=None, opts=None): """use revisions argument to define destmap {srcrev: destrev}""" if revf is None: revf = [] @@ -864,7 +864,7 @@ if revf and srcf: raise error.Abort(_('cannot specify both a revision and a source')) -if not inmemory: +if not opts['inmemory']: cmdutil.checkunfinished(repo) cmdutil.bailifchanged(repo) @@ -939,6 +939,22 @@ ui.status(_('nothing to rebase from %s to %s\n') % ('+'.join(str(repo[r]) for r in base), dest)) return None +# If rebasing the working copy parent, force in-memory merge to be off. +# +# This is because the extra work of checking out the newly rebased commit +# outweights the benefits of rebasing in-memory, and executing an extra +# update command adds a bit of overhead, so better to just do it on disk. In +# all other cases leave it on. +# +# Note that there are cases where this isn't true -- e.g., rebasing large +# stacks that include the WCP. However, I'm not yet sure where the cutoff +# is. +rebasingwcp = repo['.'].rev() in rebaseset +if opts['inmemory'] and rebasingwcp: +opts['inmemory'] = False +# Check these since we did not before. +cmdutil.checkunfinished(repo) +cmdutil.bailifchanged(repo) if not destf: dest = repo[_destrebase(repo, rebaseset, destspace=destspace)] To: phillco, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1249: rebase: rerun a rebase on-disk if IMM merge conflicts arise
phillco updated this revision to Diff 4240. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1249?vs=4238=4240 REVISION DETAIL https://phab.mercurial-scm.org/D1249 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -646,6 +646,25 @@ cmdutil.formatteropts, _('[-s REV | -b REV] [-d REV] [OPTION]')) def rebase(ui, repo, **opts): +if opts.get('continue') or opts.get('abort'): +# in-memory rebase is not compatible with resuming rebases. +opts['inmemory'] = False + +if opts.get('inmemory', False): +try: +# in-memory merge doesn't support conflicts, so if we hit any, abort +# and re-run as an on-disk merge. +return _origrebase(ui, repo, **opts) +except error.InMemoryMergeConflictsError: +ui.warn(_('hit merge conflicts; re-running rebase without in-memory' + ' merge\n')) +_origrebase(ui, repo, **{'abort': True}) +opts['inmemory'] = False +return _origrebase(ui, repo, **opts) +else: +return _origrebase(ui, repo, **opts) + +def _origrebase(ui, repo, **opts): """move changeset (and descendants) to a different branch Rebase uses repeated merging to graft changesets from one part of To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1248: rebase: add concludememorynode(), and call it when rebasing in-memory
phillco updated this revision to Diff 4239. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1248?vs=4237=4239 REVISION DETAIL https://phab.mercurial-scm.org/D1248 AFFECTED FILES hgext/rebase.py mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2224,6 +2224,12 @@ def isdirty(self, path): return path in self._cache + +def isempty(self): +# We need to discard any keys that are actually clean before the empty +# commit check. +self._compact() +return len(self._cache) == 0 def clean(self): self._cache = {} diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -495,11 +495,21 @@ merging = p2 != nullrev editform = cmdutil.mergeeditform(merging, 'rebase') editor = cmdutil.getcommiteditor(editform=editform, **opts) -newnode = concludenode(repo, rev, p1, p2, - extrafn=_makeextrafn(self.extrafns), - editor=editor, - keepbranches=self.keepbranchesf, - date=self.date) +if self.wctx.isinmemory(): +newnode = concludememorynode(repo, rev, p1, p2, +wctx=self.wctx, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) +mergemod.mergestate.clean(repo) +else: +newnode = concludenode(repo, rev, p1, p2, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) + if newnode is None: # If it ended up being a no-op commit, then the normal # merge state clean-up path doesn't happen, so do it @@ -552,13 +562,22 @@ dsguard = None if ui.configbool('rebase', 'singletransaction'): dsguard = dirstateguard.dirstateguard(repo, 'rebase') -with util.acceptintervention(dsguard): -newnode = concludenode(repo, revtoreuse, p1, self.external, - commitmsg=commitmsg, - extrafn=_makeextrafn(self.extrafns), - editor=editor, - keepbranches=self.keepbranchesf, - date=self.date) +if self.inmemory: +newnode = concludememorynode(repo, revtoreuse, p1, +self.external, +commitmsg=commitmsg, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date, wctx=self.wctx) +else: +with util.acceptintervention(dsguard): +newnode = concludenode(repo, revtoreuse, p1, self.external, +commitmsg=commitmsg, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) if newnode is not None: newrev = repo[newnode].rev() for oldrev in self.state.iterkeys(): @@ -964,6 +983,44 @@ (max(destancestors), ', '.join(str(p) for p in sorted(parents +def concludememorynode(repo, rev, p1, p2, wctx=None, + commitmsg=None, editor=None, extrafn=None, + keepbranches=False, date=None): +'''Commit the wd changes with parents p1 and p2. Reuse commit info from rev +but also store useful information in extra. +Return node of committed revision.''' +ctx = repo[rev] +if commitmsg is None: +commitmsg = ctx.description() +keepbranch = keepbranches and repo[p1].branch() != ctx.branch() +extra = {'rebase_source': ctx.hex()} +if extrafn: +extrafn(ctx, extra) + +destphase = max(ctx.phase(), phases.draft) +overrides = {('phases', 'new-commit'): destphase} +with repo.ui.configoverride(overrides, 'rebase'): +if keepbranch: +repo.ui.setconfig('ui', 'allowemptycommit', True) +# Replicates the empty check in ``repo.commit``. +if wctx.isempty() and not repo.ui.configbool('ui',
D1249: rebase: rerun a rebase on-disk if IMM merge conflicts arise
phillco updated this revision to Diff 4238. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1249?vs=4214=4238 REVISION DETAIL https://phab.mercurial-scm.org/D1249 AFFECTED FILES hgext/rebase.py CHANGE DETAILS diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -646,6 +646,25 @@ cmdutil.formatteropts, _('[-s REV | -b REV] [-d REV] [OPTION]')) def rebase(ui, repo, **opts): +if opts.get('continue') or opts.get('abort'): +# in-memory rebase is not compatible with resuming rebases. +opts['inmemory'] = False + +if opts.get('inmemory', False): +try: +# in-memory merge doesn't support conflicts, so if we hit any, abort +# and re-run as an on-disk merge. +return _origrebase(ui, repo, **opts) +except error.InMemoryMergeConflictsError: +ui.warn(_('hit merge conflicts; re-running rebase without in-memory' + ' merge\n')) +_origrebase(ui, repo, **{'abort': True}) +opts['inmemory'] = False +return _origrebase(ui, repo, **opts) +else: +return _origrebase(ui, repo, **opts) + +def _origrebase(ui, repo, **opts): """move changeset (and descendants) to a different branch Rebase uses repeated merging to graft changesets from one part of To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1244: overlayworkingctx: invalidate the manifest cache when changing parents
phillco updated this revision to Diff 4236. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1244?vs=4217=4236 REVISION DETAIL https://phab.mercurial-scm.org/D1244 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1999,6 +1999,8 @@ def setbase(self, wrappedctx): self._wrappedctx = wrappedctx self._parents = [wrappedctx] +# Drop old manifest cache: +self._invalidate() def data(self, path): if self.isdirty(path): @@ -2014,6 +2016,13 @@ else: return self._wrappedctx[path].data() +def _invalidate(self): +# Unfortunately, this is necessary when rebasing several nodes with one +# ``overlayworkingctx`` (e.g. with --collapse); the manifest can change +# and make the cache outdated. +self._manifest = None +del self.__dict__["_manifest"] + @propertycache def _manifest(self): parents = self.parents() To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1240: overlayworkingctx: inherit from committablectx instead of workingctx
phillco updated this revision to Diff 4232. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1240?vs=4205=4232 REVISION DETAIL https://phab.mercurial-scm.org/D1240 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1976,9 +1976,9 @@ def setflags(self, l, x): self._repo.wvfs.setflags(self._path, l, x) -class overlayworkingctx(workingctx): -"""Wraps another mutable context with a write-back cache that can be flushed -at a later time. +class overlayworkingctx(committablectx): +"""Wraps another mutable context with a write-back cache that can be +converted into a commit context. self._cache[path] maps to a dict with keys: { 'exists': bool? @@ -2155,7 +2155,7 @@ return overlayworkingfilectx(self._repo, path, parent=self, filelog=filelog) -class overlayworkingfilectx(workingfilectx): +class overlayworkingfilectx(committablefilectx): """Wrap a ``workingfilectx`` but intercepts all writes into an in-memory cache, which can be flushed through later by calling ``flush()``.""" To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1238: overlayworkingctx: add _manifest, files(), added(), removed(), modified()
phillco updated this revision to Diff 4230. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1238?vs=4203=4230 REVISION DETAIL https://phab.mercurial-scm.org/D1238 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2014,6 +2014,43 @@ else: return self._wrappedctx[path].data() +@propertycache +def _manifest(self): +parents = self.parents() +man = parents[0].manifest().copy() + +flag = self._flagfunc +for path in self.added(): +man[path] = addednodeid +man.setflag(path, flag(path)) +for path in self.modified(): +man[path] = modifiednodeid +man.setflag(path, flag(path)) +for path in self.removed(): +del man[path] +return man + +@propertycache +def _flagfunc(self): +def f(path): +return self._cache[path]['flags'] +return f + +def files(self): +return sorted(self.added() + self.modified() + self.removed()) + +def modified(self): +return [f for f in self._cache.keys() if self._cache[f]['exists'] and +self._existsinparent(f)] + +def added(self): +return [f for f in self._cache.keys() if self._cache[f]['exists'] and +not self._existsinparent(f)] + +def removed(self): +return [f for f in self._cache.keys() if +not self._cache[f]['exists'] and self._existsinparent(f)] + def isinmemory(self): return True To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1248: rebase: add concludememorynode(), and call it when rebasing in-memory
phillco updated this revision to Diff 4237. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1248?vs=4213=4237 REVISION DETAIL https://phab.mercurial-scm.org/D1248 AFFECTED FILES hgext/rebase.py mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2224,6 +2224,12 @@ def isdirty(self, path): return path in self._cache + +def isempty(self): +# We need to discard any keys that are actually clean before the empty +# commit check. +self._compact() +return len(self._cache) == 0 def clean(self): self._cache = {} diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -495,11 +495,21 @@ merging = p2 != nullrev editform = cmdutil.mergeeditform(merging, 'rebase') editor = cmdutil.getcommiteditor(editform=editform, **opts) -newnode = concludenode(repo, rev, p1, p2, - extrafn=_makeextrafn(self.extrafns), - editor=editor, - keepbranches=self.keepbranchesf, - date=self.date) +if self.wctx.isinmemory(): +newnode = concludememorynode(repo, rev, p1, p2, +wctx=self.wctx, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) +mergemod.mergestate.clean(repo) +else: +newnode = concludenode(repo, rev, p1, p2, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) + if newnode is None: # If it ended up being a no-op commit, then the normal # merge state clean-up path doesn't happen, so do it @@ -552,13 +562,22 @@ dsguard = None if ui.configbool('rebase', 'singletransaction'): dsguard = dirstateguard.dirstateguard(repo, 'rebase') -with util.acceptintervention(dsguard): -newnode = concludenode(repo, revtoreuse, p1, self.external, - commitmsg=commitmsg, - extrafn=_makeextrafn(self.extrafns), - editor=editor, - keepbranches=self.keepbranchesf, - date=self.date) +if self.inmemory: +newnode = concludememorynode(repo, revtoreuse, p1, +self.external, +commitmsg=commitmsg, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date, wctx=self.wctx) +else: +with util.acceptintervention(dsguard): +newnode = concludenode(repo, revtoreuse, p1, self.external, +commitmsg=commitmsg, +extrafn=_makeextrafn(self.extrafns), +editor=editor, +keepbranches=self.keepbranchesf, +date=self.date) if newnode is not None: newrev = repo[newnode].rev() for oldrev in self.state.iterkeys(): @@ -964,6 +983,44 @@ (max(destancestors), ', '.join(str(p) for p in sorted(parents +def concludememorynode(repo, rev, p1, p2, wctx=None, + commitmsg=None, editor=None, extrafn=None, + keepbranches=False, date=None): +'''Commit the wd changes with parents p1 and p2. Reuse commit info from rev +but also store useful information in extra. +Return node of committed revision.''' +ctx = repo[rev] +if commitmsg is None: +commitmsg = ctx.description() +keepbranch = keepbranches and repo[p1].branch() != ctx.branch() +extra = {'rebase_source': ctx.hex()} +if extrafn: +extrafn(ctx, extra) + +destphase = max(ctx.phase(), phases.draft) +overrides = {('phases', 'new-commit'): destphase} +with repo.ui.configoverride(overrides, 'rebase'): +if keepbranch: +repo.ui.setconfig('ui', 'allowemptycommit', True) +# Replicates the empty check in ``repo.commit``. +if not wctx.isempty() or repo.ui.configbool('ui',
D1243: overlayworkingctx: add `_compact()`
phillco updated this revision to Diff 4235. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1243?vs=4216=4235 REVISION DETAIL https://phab.mercurial-scm.org/D1243 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2219,6 +2219,29 @@ def clean(self): self._cache = {} +def _compact(self): +"""Removes keys from the cache that are actually clean, by comparing +them with the underyting context. + +This can occur during the merge process, e.g. by passing --tool :local +to resolve a conflict. +""" +keys = [] +for path in self._cache.keys(): +cache = self._cache[path] +try: +underlying = self._wrappedctx[path] +if (underlying.data() == cache['data'] and +underlying.flags() == cache['flags']): +keys.append(path) +except error.ManifestLookupError: +# Path not in the underlying manifest (created). +continue + +for path in keys: +del self._cache[path] +return keys + def _markdirty(self, path, exists, data=None, date=None, flags=''): self._cache[path] = { 'exists': exists, To: phillco, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1239: overlayworkingctx: add a no-op ``clearunknown()``
phillco updated this revision to Diff 4231. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1239?vs=4204=4231 REVISION DETAIL https://phab.mercurial-scm.org/D1239 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2211,6 +2211,9 @@ def remove(self, ignoremissing=False): return self._parent.remove(self._path) +def clearunknown(self): +pass + class workingcommitctx(workingctx): """A workingcommitctx object makes access to data related to the revision being committed convenient. To: phillco, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1242: overlayworkingctx: add ``tomemctx()`` and ``commit()``
phillco updated this revision to Diff 4234. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1242?vs=4215=4234 REVISION DETAIL https://phab.mercurial-scm.org/D1242 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2177,6 +2177,42 @@ self._path) return self._wrappedctx[path].size() +def tomemctx(self, text, branch=None, extra=None, date=None, parents=None, + user=None, editor=None): +"""Converts this ``overlayworkingctx`` into a ``memctx`` ready to be +committed. + +``text`` is the commit message. +``parents`` (optional) are rev numbers. +""" +# Default parents to the wrapped contexts' if not passed. +if parents is None: +parents = self._wrappedctx.parents() +if len(parents) == 1: +parents = (parents[0], None) + +# ``parents`` is passed as rev numbers; convert to ``commitctxs``. +if parents[1] is None: +parents = (self._repo[parents[0]], None) +else: +parents = (self._repo[parents[0]], self._repo[parents[1]]) + +files = self._cache.keys() +def getfile(repo, memctx, path): +if self._cache[path]['exists']: +return memfilectx(repo, path, + self._cache[path]['data'], + 'l' in self._cache[path]['flags'], + 'x' in self._cache[path]['flags'], + self._cache[path]['copied'], + memctx) +else: +# Returning None, but including the path in `files`, is +# necessary for memctx to register a deletion. +return None +return memctx(self._repo, parents, text, files, getfile, date=date, + extra=extra, user=user, branch=branch, editor=editor) + def isdirty(self, path): return path in self._cache To: phillco, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1241: overlayworkingctx: add _auditconflicts to write()
phillco updated this revision to Diff 4233. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1241?vs=4206=4233 REVISION DETAIL https://phab.mercurial-scm.org/D1241 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2092,9 +2092,50 @@ except error.ManifestLookupError: return False +def _auditconflicts(self, path): +"""Replicates conflict checks done by wvfs.write(). + +Since we never write to the filesystem and never call `applyupdates` in +IMM, we'll never check that a path is actually writable -- e.g., because +it adds `a/foo`, but `a` is actually a file in the other commit. +""" +def fail(path, component): +# p1() is the base and we're receiving "writes" for p2()'s +# files. +if 'l' in self.p1()[component].flags(): +raise error.Abort("error: %s conflicts with symlink %s " + "in %s." % (path, component, + self.p1().rev())) +else: +raise error.Abort("error: '%s' conflicts with file '%s' in " + "%s." % (path, component, + self.p1().rev())) + +# Test that each new directory to be created to write this path from p2 +# is not a file in p1. +components = path.split('/') +for i in xrange(len(components)): +component = "/".join(components[0:i]) +if component in self.p1(): +fail(path, component) + +# Test the other direction -- that this path from p2 isn't a directory +# in p1 (test that p1 doesn't any paths matching `path/*`). +match = matchmod.match('/', '', [path + '/'], default=b'relpath') +matches = self.p1().manifest().matches(match) +if len(matches) > 0: +if len(matches) == 1 and matches.keys()[0] == path: +return +raise error.Abort("error: file '%s' cannot be written because " + " '%s/' is a folder in %s (containing %d " + "entries: %s)" + % (path, path, self.p1(), len(matches), + ', '.join(matches.keys( + def write(self, path, data, flags=''): if data is None: raise error.ProgrammingError("data must be non-None") +self._auditconflicts(path) self._markdirty(path, exists=True, data=data, date=util.makedate(), flags=flags) To: phillco, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel