comparison mercurial/subrepo.py @ 33364:bf2daeddd42b

subrepo: consider the parent repo dirty when a file is missing This simply passes the 'missing' argument down from the context of the parent repo, so the same rules apply. subrepo.bailifchanged() is hardcoded to care about missing files, because cmdutil.bailifchanged() is too. In the end, it looks like this addresses inconsistencies with 'archive', 'identify', blackbox logs, 'merge', and 'update --check'. I wasn't sure how to implement this in git, so that's left for someone more familiar with it.
author Matt Harbison <matt_harbison@yahoo.com>
date Sun, 09 Jul 2017 02:55:46 -0400
parents 746e12a767b3
children 6d88468d435b
comparison
equal deleted inserted replaced
33363:3047167733dc 33364:bf2daeddd42b
458 returns true if the repository has not changed since it was last 458 returns true if the repository has not changed since it was last
459 cloned from or pushed to a given repository. 459 cloned from or pushed to a given repository.
460 """ 460 """
461 return False 461 return False
462 462
463 def dirty(self, ignoreupdate=False): 463 def dirty(self, ignoreupdate=False, missing=False):
464 """returns true if the dirstate of the subrepo is dirty or does not 464 """returns true if the dirstate of the subrepo is dirty or does not
465 match current stored state. If ignoreupdate is true, only check 465 match current stored state. If ignoreupdate is true, only check
466 whether the subrepo has uncommitted changes in its dirstate. 466 whether the subrepo has uncommitted changes in its dirstate. If missing
467 is true, check for deleted files.
467 """ 468 """
468 raise NotImplementedError 469 raise NotImplementedError
469 470
470 def dirtyreason(self, ignoreupdate=False): 471 def dirtyreason(self, ignoreupdate=False, missing=False):
471 """return reason string if it is ``dirty()`` 472 """return reason string if it is ``dirty()``
472 473
473 Returned string should have enough information for the message 474 Returned string should have enough information for the message
474 of exception. 475 of exception.
475 476
476 This returns None, otherwise. 477 This returns None, otherwise.
477 """ 478 """
478 if self.dirty(ignoreupdate=ignoreupdate): 479 if self.dirty(ignoreupdate=ignoreupdate, missing=missing):
479 return _("uncommitted changes in subrepository '%s'" 480 return _("uncommitted changes in subrepository '%s'"
480 ) % subrelpath(self) 481 ) % subrelpath(self)
481 482
482 def bailifchanged(self, ignoreupdate=False, hint=None): 483 def bailifchanged(self, ignoreupdate=False, hint=None):
483 """raise Abort if subrepository is ``dirty()`` 484 """raise Abort if subrepository is ``dirty()``
484 """ 485 """
485 dirtyreason = self.dirtyreason(ignoreupdate=ignoreupdate) 486 dirtyreason = self.dirtyreason(ignoreupdate=ignoreupdate,
487 missing=True)
486 if dirtyreason: 488 if dirtyreason:
487 raise error.Abort(dirtyreason, hint=hint) 489 raise error.Abort(dirtyreason, hint=hint)
488 490
489 def basestate(self): 491 def basestate(self):
490 """current working directory base state, disregarding .hgsubstate 492 """current working directory base state, disregarding .hgsubstate
813 total += s.archive(archiver, prefix + self._path + '/', submatch, 815 total += s.archive(archiver, prefix + self._path + '/', submatch,
814 decode) 816 decode)
815 return total 817 return total
816 818
817 @annotatesubrepoerror 819 @annotatesubrepoerror
818 def dirty(self, ignoreupdate=False): 820 def dirty(self, ignoreupdate=False, missing=False):
819 r = self._state[1] 821 r = self._state[1]
820 if r == '' and not ignoreupdate: # no state recorded 822 if r == '' and not ignoreupdate: # no state recorded
821 return True 823 return True
822 w = self._repo[None] 824 w = self._repo[None]
823 if r != w.p1().hex() and not ignoreupdate: 825 if r != w.p1().hex() and not ignoreupdate:
824 # different version checked out 826 # different version checked out
825 return True 827 return True
826 return w.dirty() # working directory changed 828 return w.dirty(missing=missing) # working directory changed
827 829
828 def basestate(self): 830 def basestate(self):
829 return self._repo['.'].hex() 831 return self._repo['.'].hex()
830 832
831 def checknested(self, path): 833 def checknested(self, path):
1200 for ext in externals: 1202 for ext in externals:
1201 if path == ext or path.startswith(ext + pycompat.ossep): 1203 if path == ext or path.startswith(ext + pycompat.ossep):
1202 return True, True, bool(missing) 1204 return True, True, bool(missing)
1203 return bool(changes), False, bool(missing) 1205 return bool(changes), False, bool(missing)
1204 1206
1205 def dirty(self, ignoreupdate=False): 1207 def dirty(self, ignoreupdate=False, missing=False):
1206 if not self._wcchanged()[0]: 1208 wcchanged = self._wcchanged()
1209 changed = wcchanged[0] or (missing and wcchanged[2])
1210 if not changed:
1207 if self._state[1] in self._wcrevs() or ignoreupdate: 1211 if self._state[1] in self._wcrevs() or ignoreupdate:
1208 return False 1212 return False
1209 return True 1213 return True
1210 1214
1211 def basestate(self): 1215 def basestate(self):
1553 if not self._githavelocally(revision): 1557 if not self._githavelocally(revision):
1554 raise error.Abort(_("revision %s does not exist in subrepo %s\n") % 1558 raise error.Abort(_("revision %s does not exist in subrepo %s\n") %
1555 (revision, self._relpath)) 1559 (revision, self._relpath))
1556 1560
1557 @annotatesubrepoerror 1561 @annotatesubrepoerror
1558 def dirty(self, ignoreupdate=False): 1562 def dirty(self, ignoreupdate=False, missing=False):
1559 if self._gitmissing(): 1563 if self._gitmissing():
1560 return self._state[1] != '' 1564 return self._state[1] != ''
1561 if self._gitisbare(): 1565 if self._gitisbare():
1562 return True 1566 return True
1563 if not ignoreupdate and self._state[1] != self._gitstate(): 1567 if not ignoreupdate and self._state[1] != self._gitstate():