From 7951e143852bd861da21253275131d1fa79714d0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 21 Feb 2020 00:04:15 -0500 Subject: [PATCH] project: fallback to hardlinks with git hooks Windows requires Administrator access to create symlinks. We can mitigate this a bit by falling back to hardlinks as those may be created by any user on the system. Do this with the git hooks as these are supposed to be internal only and people shouldn't be modifying them. If they do, they'll have to delink first. This seems worth it to allow repo usage without extra privileges. Change-Id: I996ea9c9238f7bd7d27d1d9b1f2786593bf75ef7 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/256312 Reviewed-by: David Pursehouse Tested-by: Mike Frysinger --- project.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/project.py b/project.py index 99ef238f..d83dd2d7 100644 --- a/project.py +++ b/project.py @@ -2860,19 +2860,23 @@ class Project(object): if platform_utils.islink(dst): continue if os.path.exists(dst): - if filecmp.cmp(stock_hook, dst, shallow=False): - platform_utils.remove(dst) - else: + # If the files are the same, we'll leave it alone. We create symlinks + # below by default but fallback to hardlinks if the OS blocks them. + # So if we're here, it's probably because we made a hardlink below. + if not filecmp.cmp(stock_hook, dst, shallow=False): if not quiet: _warn("%s: Not replacing locally modified %s hook", self.relpath, name) - continue + continue try: platform_utils.symlink( os.path.relpath(stock_hook, os.path.dirname(dst)), dst) except OSError as e: if e.errno == errno.EPERM: - raise GitError(self._get_symlink_error_message()) + try: + os.link(stock_hook, dst) + except OSError: + raise GitError(self._get_symlink_error_message()) else: raise