[PATCH STABLE] largefiles: fix an explicit largefile commit after a remove (issue4969)
Yuya Nishihara
yuya at tcha.org
Tue Jan 26 08:38:20 CST 2016
On Mon, 25 Jan 2016 20:29:09 -0500, Matt Harbison wrote:
> On Mon, 25 Jan 2016 10:07:21 -0500, Yuya Nishihara <yuya at tcha.org> wrote:
>
> > On Sat, 23 Jan 2016 20:58:00 -0500, Matt Harbison wrote:
> >> # HG changeset patch
> >> # User Matt Harbison <matt_harbison at yahoo.com>
> >> # Date 1453600277 18000
> >> # Sat Jan 23 20:51:17 2016 -0500
> >> # Branch stable
> >> # Node ID d07901a07264cc495565bce44eccb7d80afb7a25
> >> # Parent 4c6053a6b17d682b34fb88bbeb5e94ed9085d900
> >> largefiles: fix an explicit largefile commit after a remove (issue4969)
> >>
> >> The change in b68797f244e4 to handle a normal -> largefile switch was
> >> too
> >> aggressive in preserving the original matcher names. If a largefile is
> >> explicitly provided by the user, but only the standin exists in
> >> dirstate, then
> >> only the standin can be committed.
> >>
> >> There's still maybe an issue when the largefile is deleted outside of
> >> Mercurial:
> >>
> >> $ rm large
> >> $ hg ci -m "oops" large
> >> large: The system cannot find the file specified
> >> nothing changed
> >> [1]
> >>
> >> That may be OK, since the standin file could have been changed since
> >> the last
> >> commit, and this seems safer since the largefile isn't present to
> >> regenerate it.
> >>
> >> diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py
> >> --- a/hgext/largefiles/lfutil.py
> >> +++ b/hgext/largefiles/lfutil.py
> >> @@ -575,11 +575,15 @@
> >> fstandin = standin(f)
> >>
> >> # For largefiles, only one of the normal and standin should be
> >> - # committed (except if one of them is a remove).
> >> + # committed (except if one of them is a remove). In the case
> >> of a
> >> + # standin removal, drop the normal file if it is unknown to
> >> dirstate.
> >> # Thus, skip plain largefile names but keep the standin.
> >> - if (f in lfiles or fstandin in standins) and \
> >> - repo.dirstate[f] != 'r' and repo.dirstate[fstandin] != 'r':
> >> - continue
> >> + if f in lfiles or fstandin in standins:
> >> + if repo.dirstate[fstandin] != 'r':
> >> + if repo.dirstate[f] != 'r':
> >> + continue
> >> + elif repo.dirstate[f] == '?':
> >> + continue
> >
> > Looks good to me, but I'm not confident. I want to clarify my
> > understanding:
> >
> > (dirstate[f], dirstate[fstandin])
> > = ('?', 'r') => removal of 'f', exclude 'f' but not 'fstandin'
>
> Yes, this is the case of removing only a largefile. The tracked standin
> is committed, and the largefile is untracked in dirstate.
>
> > ('r', _) | (_, 'r') => might be add/remove pair, include both
>
> I believe so. This was the previous logic to handle changing between
> large and normal for 'f', and then it makes sense to commit both. All I
> did was unroll the conditional to tack on the elif branch for the case
> above.
Thanks, pushed to the clowncopter.
More information about the Mercurial-devel
mailing list