# HG changeset patch # User Pierre-Yves David # Date 1595684952 -7200 # Node ID aea6a812f7cb75f9825af9fa3706dfdb12fbfaf3 # Parent c3376a724e3299042614517734ccd81f229cbd11 commitctx: return a richer object from _prepare_files Instead of returning a lot of different list, we introduce a rich object that hold all the file related information. The unique object help with data consistency and simply functions arguments and return. In the rest of this series we will increase usage of this object to simplify more code. diff -r c3376a724e32 -r aea6a812f7cb mercurial/commit.py --- a/mercurial/commit.py Thu Aug 06 10:53:00 2020 -0700 +++ b/mercurial/commit.py Sat Jul 25 15:49:12 2020 +0200 @@ -64,12 +64,10 @@ user = ctx.user() with repo.lock(), repo.transaction(b"commit") as tr: - r = _prepare_files(tr, ctx, error=error, origctx=origctx) - mn, files, p1copies, p2copies, filesadded, filesremoved = r + mn, files = _prepare_files(tr, ctx, error=error, origctx=origctx) extra = ctx.extra().copy() - files = sorted(files) if extra is not None: for name in ( b'p1copies', @@ -79,16 +77,14 @@ ): extra.pop(name, None) if repo.changelog._copiesstorage == b'extra': - extra = _extra_with_copies( - repo, extra, files, p1copies, p2copies, filesadded, filesremoved - ) + extra = _extra_with_copies(repo, extra, files) # update changelog repo.ui.note(_(b"committing changelog\n")) repo.changelog.delayupdate(tr) n = repo.changelog.add( mn, - files, + files.touched, ctx.description(), tr, p1.node(), @@ -96,10 +92,10 @@ user, ctx.date(), extra, - p1copies, - p2copies, - filesadded, - filesremoved, + files.copied_from_p1, + files.copied_from_p2, + files.added, + files.removed, ) xp1, xp2 = p1.hex(), p2 and p2.hex() or b'' repo.hook( @@ -149,7 +145,19 @@ if origctx and origctx.manifestnode() == mn: touched = origctx.files() - return mn, touched, p1copies, p2copies, filesadded, filesremoved + files = metadata.ChangingFiles() + if touched: + files.update_touched(touched) + if p1copies: + files.update_copies_from_p1(p1copies) + if p2copies: + files.update_copies_from_p2(p2copies) + if filesadded: + files.update_added(filesadded) + if filesremoved: + files.update_removed(filesremoved) + + return mn, files def _process_files(tr, ctx, error=False): @@ -413,10 +421,13 @@ return mn -def _extra_with_copies( - repo, extra, files, p1copies, p2copies, filesadded, filesremoved -): +def _extra_with_copies(repo, extra, files): """encode copy information into a `extra` dictionnary""" + p1copies = files.copied_from_p1 + p2copies = files.copied_from_p2 + filesadded = files.added + filesremoved = files.removed + files = sorted(files.touched) if not _write_copy_meta(repo)[1]: # If writing only to changeset extras, use None to indicate that # no entry should be written. If writing to both, write an empty diff -r c3376a724e32 -r aea6a812f7cb mercurial/metadata.py --- a/mercurial/metadata.py Thu Aug 06 10:53:00 2020 -0700 +++ b/mercurial/metadata.py Sat Jul 25 15:49:12 2020 +0200 @@ -22,6 +22,79 @@ ) +class ChangingFiles(object): + """A class recording the changes made to a file by a revision + """ + + def __init__( + self, touched=(), added=(), removed=(), p1_copies=(), p2_copies=(), + ): + self._added = set(added) + self._removed = set(removed) + self._touched = set(touched) + self._touched.update(self._added) + self._touched.update(self._removed) + self._p1_copies = dict(p1_copies) + self._p2_copies = dict(p2_copies) + + @property + def added(self): + return frozenset(self._added) + + def mark_added(self, filename): + self._added.add(filename) + self._touched.add(filename) + + def update_added(self, filenames): + for f in filenames: + self.mark_added(f) + + @property + def removed(self): + return frozenset(self._removed) + + def mark_removed(self, filename): + self._removed.add(filename) + self._touched.add(filename) + + def update_removed(self, filenames): + for f in filenames: + self.mark_removed(f) + + @property + def touched(self): + return frozenset(self._touched) + + def mark_touched(self, filename): + self._touched.add(filename) + + def update_touched(self, filenames): + for f in filenames: + self.mark_touched(f) + + @property + def copied_from_p1(self): + return self._p1_copies.copy() + + def mark_copied_from_p1(self, source, dest): + self._p1_copies[dest] = source + + def update_copies_from_p1(self, copies): + for dest, source in copies.items(): + self.mark_copied_from_p1(source, dest) + + @property + def copied_from_p2(self): + return self._p2_copies.copy() + + def mark_copied_from_p2(self, source, dest): + self._p2_copies[dest] = source + + def update_copies_from_p2(self, copies): + for dest, source in copies.items(): + self.mark_copied_from_p2(source, dest) + + def computechangesetfilesadded(ctx): """return the list of files added in a changeset """