mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
project: make syncing a little more self-healing
We have a few files that we optionally symlink from the work tree .git/ to the .repo/projects/ path. If they don't exist when we first initialize, then we skip creating symlinks. If the files are created later on under the work tree .git/, repo gets upset. This can happen with the packed-refs file: if we don't have any packed refs initially, we don't symlink it. But if git tries to pack refs later on and creates the file, the project gets wedged. We could create an empty file initially and then symlink it, but for some files, it's not clear we want to always do that (e.g. the .git/shallow setting). Instead, lets make handling of these paths more dynamic. If they show up later on in the work tree .git/ only, we'll take care of relocating & symlinking. This also makes repo a little more robust and autorecovers incase a path goes missing in one of the dirs. Ideally we wouldn't monkey around at all here, but considering the only option we give to users currently is to blow things away with --force-sync, this seems a bit better. Bug: https://crbug.com/gerrit/12324 Change-Id: Ia6960f1896ac6d890c762d7d053684a1c6ab2c87 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/254632 Reviewed-by: David Pursehouse <dpursehouse@collab.net> Tested-by: Mike Frysinger <vapier@google.com>
This commit is contained in:
parent
719675bcec
commit
ed4f2113d2
26
project.py
26
project.py
@ -2760,9 +2760,31 @@ class Project(object):
|
|||||||
symlink_dirs += self.working_tree_dirs
|
symlink_dirs += self.working_tree_dirs
|
||||||
to_symlink = symlink_files + symlink_dirs
|
to_symlink = symlink_files + symlink_dirs
|
||||||
for name in set(to_symlink):
|
for name in set(to_symlink):
|
||||||
dst = platform_utils.realpath(os.path.join(destdir, name))
|
# Try to self-heal a bit in simple cases.
|
||||||
|
dst_path = os.path.join(destdir, name)
|
||||||
|
src_path = os.path.join(srcdir, name)
|
||||||
|
|
||||||
|
if name in self.working_tree_dirs:
|
||||||
|
# If the dir is missing under .repo/projects/, create it.
|
||||||
|
if not os.path.exists(src_path):
|
||||||
|
os.makedirs(src_path)
|
||||||
|
|
||||||
|
elif name in self.working_tree_files:
|
||||||
|
# If it's a file under the checkout .git/ and the .repo/projects/ has
|
||||||
|
# nothing, move the file under the .repo/projects/ tree.
|
||||||
|
if not os.path.exists(src_path) and os.path.isfile(dst_path):
|
||||||
|
platform_utils.rename(dst_path, src_path)
|
||||||
|
|
||||||
|
# If the path exists under the .repo/projects/ and there's no symlink
|
||||||
|
# under the checkout .git/, recreate the symlink.
|
||||||
|
if name in self.working_tree_dirs or name in self.working_tree_files:
|
||||||
|
if os.path.exists(src_path) and not os.path.exists(dst_path):
|
||||||
|
platform_utils.symlink(
|
||||||
|
os.path.relpath(src_path, os.path.dirname(dst_path)), dst_path)
|
||||||
|
|
||||||
|
dst = platform_utils.realpath(dst_path)
|
||||||
if os.path.lexists(dst):
|
if os.path.lexists(dst):
|
||||||
src = platform_utils.realpath(os.path.join(srcdir, name))
|
src = platform_utils.realpath(src_path)
|
||||||
# Fail if the links are pointing to the wrong place
|
# Fail if the links are pointing to the wrong place
|
||||||
if src != dst:
|
if src != dst:
|
||||||
_error('%s is different in %s vs %s', name, destdir, srcdir)
|
_error('%s is different in %s vs %s', name, destdir, srcdir)
|
||||||
|
Loading…
Reference in New Issue
Block a user