summaryrefslogtreecommitdiffstats
path: root/project.py
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2022-01-06 05:42:24 -0500
committerMike Frysinger <vapier@google.com>2022-01-07 20:17:14 +0000
commit89ed8acdbe468fd76d531cd8b7b2ace5b414f0bd (patch)
treef0dcf219ba20bb8e4d74e551ebf3bc0572104a99 /project.py
parent71e48b76728dcc50b3265d320ee1c2d1ea09a4f5 (diff)
downloadgit-repo-89ed8acdbe468fd76d531cd8b7b2ace5b414f0bd.tar.gz
project: abort a bit earlier before migrating .git/
Verify all the .git/ paths will be handled by the migration logic before starting the migration. This way we still abort & log an error, but the user gets to see it before we put the tree into a state that they have to manually recover. Also add a few more known-safe-to-clobber paths. Bug: https://crbug.com/gerrit/15273 Change-Id: If49d69b341bc960ddcafa30da333fb5ec7145b51 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/327557 Reviewed-by: Colin Cross <ccross@android.com> Tested-by: Mike Frysinger <vapier@google.com>
Diffstat (limited to 'project.py')
-rw-r--r--project.py38
1 files changed, 27 insertions, 11 deletions
diff --git a/project.py b/project.py
index de593c83..48287858 100644
--- a/project.py
+++ b/project.py
@@ -2818,24 +2818,40 @@ class Project(object):
2818 } 2818 }
2819 # Paths that we know will be in both, but are safe to clobber in .repo/projects/. 2819 # Paths that we know will be in both, but are safe to clobber in .repo/projects/.
2820 SAFE_TO_CLOBBER = { 2820 SAFE_TO_CLOBBER = {
2821 'COMMIT_EDITMSG', 'FETCH_HEAD', 'HEAD', 'index', 'ORIG_HEAD', 2821 'COMMIT_EDITMSG', 'FETCH_HEAD', 'HEAD', 'gitk.cache', 'index', 'ORIG_HEAD',
2822 } 2822 }
2823 2823
2824 # Now walk the paths and sync the .git/ to .repo/projects/. 2824 # First see if we'd succeed before starting the migration.
2825 unknown_paths = []
2825 for name in platform_utils.listdir(dotgit): 2826 for name in platform_utils.listdir(dotgit):
2827 # Ignore all temporary/backup names. These are common with vim & emacs.
2828 if name.endswith('~') or (name[0] == '#' and name[-1] == '#'):
2829 continue
2830
2826 dotgit_path = os.path.join(dotgit, name) 2831 dotgit_path = os.path.join(dotgit, name)
2827 if name in KNOWN_LINKS: 2832 if name in KNOWN_LINKS:
2828 if platform_utils.islink(dotgit_path): 2833 if not platform_utils.islink(dotgit_path):
2829 platform_utils.remove(dotgit_path) 2834 unknown_paths.append(f'{dotgit_path}: should be a symlink')
2830 else:
2831 raise GitError(f'{dotgit_path}: should be a symlink')
2832 else: 2835 else:
2833 gitdir_path = os.path.join(gitdir, name) 2836 gitdir_path = os.path.join(gitdir, name)
2834 if name in SAFE_TO_CLOBBER or not os.path.exists(gitdir_path): 2837 if name not in SAFE_TO_CLOBBER and os.path.exists(gitdir_path):
2835 platform_utils.remove(gitdir_path, missing_ok=True) 2838 unknown_paths.append(f'{dotgit_path}: unknown file; please file a bug')
2836 platform_utils.rename(dotgit_path, gitdir_path) 2839 if unknown_paths:
2837 else: 2840 raise GitError('Aborting migration: ' + '\n'.join(unknown_paths))
2838 raise GitError(f'{dotgit_path}: unknown file; please file a bug') 2841
2842 # Now walk the paths and sync the .git/ to .repo/projects/.
2843 for name in platform_utils.listdir(dotgit):
2844 dotgit_path = os.path.join(dotgit, name)
2845
2846 # Ignore all temporary/backup names. These are common with vim & emacs.
2847 if name.endswith('~') or (name[0] == '#' and name[-1] == '#'):
2848 platform_utils.remove(dotgit_path)
2849 elif name in KNOWN_LINKS:
2850 platform_utils.remove(dotgit_path)
2851 else:
2852 gitdir_path = os.path.join(gitdir, name)
2853 platform_utils.remove(gitdir_path, missing_ok=True)
2854 platform_utils.rename(dotgit_path, gitdir_path)
2839 2855
2840 # Now that the dir should be empty, clear it out, and symlink it over. 2856 # Now that the dir should be empty, clear it out, and symlink it over.
2841 platform_utils.rmdir(dotgit) 2857 platform_utils.rmdir(dotgit)