Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Unified Diff: git_drover.py

Issue 1387223002: Attempt at making git-drover work on Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: don't monkey patch Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « git_common.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: git_drover.py
diff --git a/git_drover.py b/git_drover.py
index 18756d84fbb092f5665afbd83db58e5d46afc7b2..73c92004aa66eb613f6ea2f31179f95044bd7e77 100755
--- a/git_drover.py
+++ b/git_drover.py
@@ -20,6 +20,27 @@ class Error(Exception):
pass
+if os.name == 'nt':
+ # This is a just-good-enough emulation of os.symlink for drover to work on
+ # Windows. It uses junctioning of directories (most of the contents of
+ # the .git directory), but copies files. Note that we can't use
+ # CreateSymbolicLink or CreateHardLink here, as they both require elevation.
+ # Creating reparse points is what we want for the directories, but doing so
+ # is a relatively messy set of DeviceIoControl work at the API level, so we
+ # simply shell to `mklink /j` instead.
+ def emulate_symlink_windows(source, link_name):
+ if os.path.isdir(source):
+ subprocess.check_call(['mklink', '/j',
+ link_name.replace('/', '\\'),
+ source.replace('/', '\\')],
+ shell=True)
+ else:
+ shutil.copy(source, link_name)
+ mk_symlink = emulate_symlink_windows
+else:
+ mk_symlink = os.symlink
+
+
class _Drover(object):
def __init__(self, branch, revision, parent_repo, dry_run):
@@ -72,7 +93,11 @@ class _Drover(object):
self._run_git_command(['branch', '-D', self._branch_name])
if self._workdir:
logging.debug('Deleting %s', self._workdir)
- shutil.rmtree(self._workdir)
+ if os.name == 'nt':
+ # Use rmdir to properly handle the junctions we created.
+ subprocess.check_call(['rmdir', '/s', '/q', self._workdir], shell=True)
+ else:
+ shutil.rmtree(self._workdir)
self._dev_null_file.close()
@staticmethod
@@ -95,8 +120,6 @@ class _Drover(object):
if not os.path.isdir(self._parent_repo):
raise Error('Invalid parent repo path %r' % self._parent_repo)
- if not hasattr(os, 'symlink'):
- raise Error('Symlink support is required')
self._run_git_command(['--help'], error_message='Unable to run git')
self._run_git_command(['status'],
@@ -140,7 +163,7 @@ class _Drover(object):
logging.debug('Creating checkout in %s', self._workdir)
git_dir = os.path.join(self._workdir, '.git')
git_common.make_workdir_common(parent_git_dir, git_dir, self.FILES_TO_LINK,
- self.FILES_TO_COPY)
+ self.FILES_TO_COPY, mk_symlink)
self._run_git_command(['config', 'core.sparsecheckout', 'true'])
with open(os.path.join(git_dir, 'info', 'sparse-checkout'), 'w') as f:
f.write('codereview.settings')
« no previous file with comments | « git_common.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698