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".
--- a/hgext/largefiles/lfutil.py Wed Nov 05 23:24:47 2014 +0900
+++ b/hgext/largefiles/lfutil.py Wed Nov 05 23:24:47 2014 +0900
@@ -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
--- a/hgext/largefiles/overrides.py Wed Nov 05 23:24:47 2014 +0900
+++ b/hgext/largefiles/overrides.py Wed Nov 05 23:24:47 2014 +0900
@@ -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):
--- a/tests/test-largefiles-update.t Wed Nov 05 23:24:47 2014 +0900
+++ b/tests/test-largefiles-update.t Wed Nov 05 23:24:47 2014 +0900
@@ -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.