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)

Reply via email to