Mercurial > hg
comparison mercurial/match.py @ 26000:9ac4e81b9659 stable
match: fix a caseonly rename + explicit path commit on icasefs (issue4768)
The problem was that the former name and the new name are both normalized to the
case in dirstate, so matcher._files would be ['ABC.txt', 'ABC.txt'].
localrepo.commit() calls localrepo.status(), passing along the matcher. Inside
dirstate.status(), _walkexplicit() simply grabs matcher.files() and processes
those items. Since the old name isn't present, it is silently dropped. There's
a fundamental tension here, because the status command should also accept files
that don't match the filesystem, so we can't drop the normalization in status.
The problem originated in baa11dde8c0e.
Unfortunately with this change, the case of the old file must still be specified
exactly, or the old file is again silently excluded. I went back to
baa11dde8c0e^, and that had the same behavior, so we are no worse off. I'm open
to ideas from a matcher or dirstate expert on how to fix that half.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Thu, 06 Aug 2015 21:00:16 -0400 |
parents | 511e1949d557 |
children | a5f62af29517 |
comparison
equal
deleted
inserted
replaced
25997:d4e1e947444b | 26000:9ac4e81b9659 |
---|---|
384 """ | 384 """ |
385 | 385 |
386 def __init__(self, root, cwd, patterns, include, exclude, default, auditor, | 386 def __init__(self, root, cwd, patterns, include, exclude, default, auditor, |
387 ctx, listsubrepos=False, badfn=None): | 387 ctx, listsubrepos=False, badfn=None): |
388 init = super(icasefsmatcher, self).__init__ | 388 init = super(icasefsmatcher, self).__init__ |
389 self._dsnormalize = ctx.repo().dirstate.normalize | 389 self._dirstate = ctx.repo().dirstate |
390 self._dsnormalize = self._dirstate.normalize | |
390 | 391 |
391 init(root, cwd, patterns, include, exclude, default, auditor=auditor, | 392 init(root, cwd, patterns, include, exclude, default, auditor=auditor, |
392 ctx=ctx, listsubrepos=listsubrepos, badfn=badfn) | 393 ctx=ctx, listsubrepos=listsubrepos, badfn=badfn) |
393 | 394 |
394 # m.exact(file) must be based off of the actual user input, otherwise | 395 # m.exact(file) must be based off of the actual user input, otherwise |
400 self._kp = super(icasefsmatcher, self)._normalize(patterns, default, | 401 self._kp = super(icasefsmatcher, self)._normalize(patterns, default, |
401 root, cwd, auditor) | 402 root, cwd, auditor) |
402 kindpats = [] | 403 kindpats = [] |
403 for kind, pats, source in self._kp: | 404 for kind, pats, source in self._kp: |
404 if kind not in ('re', 'relre'): # regex can't be normalized | 405 if kind not in ('re', 'relre'): # regex can't be normalized |
406 p = pats | |
405 pats = self._dsnormalize(pats) | 407 pats = self._dsnormalize(pats) |
408 | |
409 # Preserve the original to handle a case only rename. | |
410 if p != pats and p in self._dirstate: | |
411 kindpats.append((kind, p, source)) | |
412 | |
406 kindpats.append((kind, pats, source)) | 413 kindpats.append((kind, pats, source)) |
407 return kindpats | 414 return kindpats |
408 | 415 |
409 def patkind(pattern, default=None): | 416 def patkind(pattern, default=None): |
410 '''If pattern is 'kind:pat' with a known kind, return kind.''' | 417 '''If pattern is 'kind:pat' with a known kind, return kind.''' |