From 4217a82bec7b95c1a0bc7b081a1764a6a6d6c59b Mon Sep 17 00:00:00 2001 From: Josip Sokcevic Date: Wed, 24 Jan 2024 13:54:25 -0800 Subject: [PATCH] project: Rename if deletion fails If a project contains files not owned by the current user, remove will fail. In order to ensure repo sync continues to work, rename the affected project instead, and let user know about it. Bug: 321273512 Change-Id: I0779d61fc67042308a0226adea7d98167252a5d3 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/404372 Reviewed-by: Mike Frysinger Tested-by: Josip Sokcevic Commit-Queue: Josip Sokcevic --- project.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/project.py b/project.py index db74c651..1821c354 100644 --- a/project.py +++ b/project.py @@ -1848,7 +1848,7 @@ class Project: platform_utils.remove(path) except OSError as e: if e.errno != errno.ENOENT: - logger.error("error: %s: Failed to remove: %s", path, e) + logger.warning("%s: Failed to remove: %s", path, e) failed = True errors.append(e) dirs[:] = [ @@ -1867,7 +1867,7 @@ class Project: platform_utils.remove(d) except OSError as e: if e.errno != errno.ENOENT: - logger.error("error: %s: Failed to remove: %s", d, e) + logger.warning("%s: Failed to remove: %s", d, e) failed = True errors.append(e) elif not platform_utils.listdir(d): @@ -1875,18 +1875,30 @@ class Project: platform_utils.rmdir(d) except OSError as e: if e.errno != errno.ENOENT: - logger.error("error: %s: Failed to remove: %s", d, e) + logger.warning("%s: Failed to remove: %s", d, e) failed = True errors.append(e) if failed: - logger.error( - "error: %s: Failed to delete obsolete checkout.", - self.RelPath(local=False), + rename_path = ( + f"{self.worktree}_repo_to_be_deleted_{int(time.time())}" ) - logger.error( - " Remove manually, then run `repo sync -l`.", - ) - raise DeleteWorktreeError(aggregate_errors=errors) + try: + platform_utils.rename(self.worktree, rename_path) + logger.warning( + "warning: renamed %s to %s. You can delete it, but you " + "might need elevated permissions (e.g. root)", + self.worktree, + rename_path, + ) + # Rename successful! Clear the errors. + errors = [] + except OSError: + logger.error( + "%s: Failed to delete obsolete checkout.\n", + " Remove manually, then run `repo sync -l`.", + self.RelPath(local=False), + ) + raise DeleteWorktreeError(aggregate_errors=errors) # Try deleting parent dirs if they are empty. path = self.worktree