Patchwork [6,of,9,V2] largefiles: update standins only at the 1st commit of "hg rebase --continue"

login
register
mail settings
Submitter Katsunori FUJIWARA
Date Nov. 5, 2014, 2:34 p.m.
Message ID <f726b05ecfe682b2cf4d.1415198055@feefifofum>
Download mbox | patch
Permalink /patch/6577/
State Accepted
Headers show

Comments

Katsunori FUJIWARA - Nov. 5, 2014, 2:34 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1415197487 -32400
#      Wed Nov 05 23:24:47 2014 +0900
# Node ID f726b05ecfe682b2cf4d5baee73903bc2c889f87
# Parent  6de61d0b773f912010d137efc78cc47409c06d71
largefiles: update standins only at the 1st commit of "hg rebase --continue"

Before this patch, "hg rebase --continue" may record incorrect
standins, because largefiles extension always avoid updating standins
while rebasing, even though largefiles in the working directory may be
modified manually at the 1st commit of "hg rebase --continue".

But, on the other hand, updating standins should be avoided at
subsequent commits for efficiency reason.

To update standins only at the 1st commit of "hg rebase --continue",
this patch introduces state-full callable object
"automatedcommithook", which updates standins by
"lfutil.updatestandinsbymatch()" only at the 1st commit of resuming.

Even after this patch, "repo._isrebasing = True" is still needed to
avoid some status report while updating largefiles in
"lfcommands.updatelfiles()".

This is reason why this patch omits not "repo._isrebasing = True" in
"overriderebase" but examination of "getattr(repo, "_isrebasing",
False)" in "updatestandinsbymatch".

Patch

diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py
--- a/hgext/largefiles/lfutil.py
+++ b/hgext/largefiles/lfutil.py
@@ -447,8 +447,7 @@ 
     # (2) aborting when standins are matched by "match",
     #     because automated committing may specify them directly
     #
-    if getattr(repo, "_isrebasing", False) or \
-            getattr(repo, "_istransplanting", False):
+    if getattr(repo, "_istransplanting", False):
         return match
 
     # Case 1: user calls commit with no specific files or
@@ -537,3 +536,24 @@ 
     match.matchfn = matchfn
 
     return match
+
+class automatedcommithook(object):
+    '''Statefull hook to update standins at the 1st commit of resuming
+
+    For efficiency, updating standins in the working directory should
+    be avoided while automated committing (like rebase, transplant and
+    so on), because they should be updated before committing.
+
+    But the 1st commit of resuming automated committing (e.g. ``rebase
+    --continue``) should update them, because largefiles may be
+    modified manually.
+    '''
+    def __init__(self, resuming):
+        self.resuming = resuming
+
+    def __call__(self, repo, match):
+        if self.resuming:
+            self.resuming = False # avoids updating at subsequent commits
+            return updatestandinsbymatch(repo, match)
+        else:
+            return match
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -790,11 +790,14 @@ 
     return result
 
 def overriderebase(orig, ui, repo, **opts):
+    resuming = opts.get('continue')
+    repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
     repo._isrebasing = True
     try:
         return orig(ui, repo, **opts)
     finally:
         repo._isrebasing = False
+        repo._lfcommithooks.pop()
 
 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
             prefix=None, mtime=None, subrepos=None):
diff --git a/tests/test-largefiles-update.t b/tests/test-largefiles-update.t
--- a/tests/test-largefiles-update.t
+++ b/tests/test-largefiles-update.t
@@ -509,8 +509,25 @@ 
   $ cat large1
   large1 in #1
 
-  $ hg rebase -q --abort
-  rebase aborted
+Test that rebase updates standins for manually modified largefiles at
+the 1st commit of resuming.
+
+  $ echo "manually modified before 'hg rebase --continue'" > large1
+  $ hg resolve -m normal1
+  (no more unresolved files)
+  $ hg rebase --continue --config ui.interactive=True <<EOF
+  > c
+  > EOF
+  local changed .hglf/large1 which remote deleted
+  use (c)hanged version or (d)elete? c
+
+  $ hg diff -c "tip~1" --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
+  -e5bb990443d6a92aaf7223813720f7566c9dd05b
+  +8a4f783556e7dea21139ca0466eafce954c75c13
+  $ rm -f large1
+  $ hg update -q -C tip
+  $ cat large1
+  manually modified before 'hg rebase --continue'
 
 Test that transplant updates largefiles, of which standins are safely
 changed, even if it is aborted by conflict of other.