commit: 7a336e85052530c62acf25b5df10e2d02a17e779 Author: John Helmert III <ajak <AT> gentoo <DOT> org> AuthorDate: Sun Oct 30 02:33:44 2022 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Sun Nov 20 03:12:47 2022 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=7a336e85
GitSync.update: clobber changes to git repo as rsync does Check `git diff --quiet` and if tree is dirty, do a hard reset to the upstream HEAD instead of simply merging. Thanks to a limitation in git, also `git reset --hard` if the merge fails. Closes: https://github.com/gentoo/portage/pull/931 Signed-off-by: John Helmert III <ajak <AT> gentoo.org> Signed-off-by: Sam James <sam <AT> gentoo.org> lib/portage/sync/modules/git/git.py | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/portage/sync/modules/git/git.py b/lib/portage/sync/modules/git/git.py index b4c470160..8bc5a3811 100644 --- a/lib/portage/sync/modules/git/git.py +++ b/lib/portage/sync/modules/git/git.py @@ -228,7 +228,21 @@ class GitSync(NewBase): if not self.verify_head(revision="refs/remotes/%s" % remote_branch): return (1, False) - if shallow: + # `git diff --quiet` returns 0 on a clean tree and 1 otherwise + is_clean = ( + portage.process.spawn( + f"{self.bin_command} diff --quiet", + cwd=portage._unicode_encode(self.repo.location), + **self.spawn_kwargs, + ) + == 0 + ) + + if not is_clean: + # If the repo isn't clean, clobber any changes for parity + # with rsync + merge_cmd = [self.bin_command, "reset", "--hard"] + elif shallow: # Since the default merge strategy typically fails when # the depth is not unlimited, `git reset --merge`. merge_cmd = [self.bin_command, "reset", "--merge"] @@ -244,10 +258,20 @@ class GitSync(NewBase): ) if exitcode != os.EX_OK: - msg = "!!! git merge error in %s" % self.repo.location - self.logger(self.xterm_titles, msg) - writemsg_level(msg + "\n", level=logging.ERROR, noiselevel=-1) - return (exitcode, False) + # HACK - sometimes merging results in a tree diverged from + # upstream, so try to hack around it + # https://stackoverflow.com/questions/41075972/how-to-update-a-git-shallow-clone/41081908#41081908 + exitcode = portage.process.spawn( + f"{self.bin_command} reset --hard refs/remotes/{remote_branch}", + cwd=portage._unicode_encode(self.repo.location), + **self.spawn_kwargs, + ) + + if exitcode != os.EX_OK: + msg = "!!! git merge error in %s" % self.repo.location + self.logger(self.xterm_titles, msg) + writemsg_level(msg + "\n", level=logging.ERROR, noiselevel=-1) + return (exitcode, False) current_rev = subprocess.check_output( rev_cmd, cwd=portage._unicode_encode(self.repo.location)
