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

Side by Side 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: 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved. 2 # Copyright 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 """git drover: A tool for merging changes to release branches.""" 5 """git drover: A tool for merging changes to release branches."""
6 6
7 import argparse 7 import argparse
8 import functools 8 import functools
9 import logging 9 import logging
10 import os 10 import os
11 import shutil 11 import shutil
12 import subprocess 12 import subprocess
13 import sys 13 import sys
14 import tempfile 14 import tempfile
15 15
16 import git_common 16 import git_common
17 17
18 18
19 class Error(Exception): 19 class Error(Exception):
20 pass 20 pass
21 21
22 22
23 if os.name == 'nt':
24 # This is a just-good-enough emulation of os.symlink for drover to work on
25 # Windows. It uses junctioning of directories (most of the contents of
26 # the .git directory), but copies files. Note that we can't use
27 # CreateSymbolicLink or CreateHardLink here, as they both require elevation.
28 # Creating reparse points is what we want for the directories, but doing so
29 # is a relatively messy set of DeviceIoControl work at the API level, so we
30 # simply shell to `mklink /j` instead.
31 def emulate_symlink_windows(source, link_name):
32 if os.path.isdir(source):
33 subprocess.check_call(['mklink', '/j',
34 link_name.replace('/', '\\'),
35 source.replace('/', '\\')],
36 shell=True)
37 else:
38 shutil.copy(source, link_name)
39 os.symlink = emulate_symlink_windows
iannucci 2015/10/07 22:58:26 Though I'm not totally sold on adding this back in
scottmg 2015/10/07 23:03:52 It sort of has to be os.symlink, or else various c
40
41
23 class _Drover(object): 42 class _Drover(object):
24 43
25 def __init__(self, branch, revision, parent_repo, dry_run): 44 def __init__(self, branch, revision, parent_repo, dry_run):
26 self._branch = branch 45 self._branch = branch
27 self._branch_ref = 'refs/remotes/branch-heads/%s' % branch 46 self._branch_ref = 'refs/remotes/branch-heads/%s' % branch
28 self._revision = revision 47 self._revision = revision
29 self._parent_repo = os.path.abspath(parent_repo) 48 self._parent_repo = os.path.abspath(parent_repo)
30 self._dry_run = dry_run 49 self._dry_run = dry_run
31 self._workdir = None 50 self._workdir = None
32 self._branch_name = None 51 self._branch_name = None
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 def _cleanup(self): 84 def _cleanup(self):
66 if self._branch_name: 85 if self._branch_name:
67 try: 86 try:
68 self._run_git_command(['cherry-pick', '--abort']) 87 self._run_git_command(['cherry-pick', '--abort'])
69 except Error: 88 except Error:
70 pass 89 pass
71 self._run_git_command(['checkout', '--detach']) 90 self._run_git_command(['checkout', '--detach'])
72 self._run_git_command(['branch', '-D', self._branch_name]) 91 self._run_git_command(['branch', '-D', self._branch_name])
73 if self._workdir: 92 if self._workdir:
74 logging.debug('Deleting %s', self._workdir) 93 logging.debug('Deleting %s', self._workdir)
75 shutil.rmtree(self._workdir) 94 if os.name == 'nt':
95 # Use rmdir to properly handle the junctions we created.
96 subprocess.check_call(['rmdir', '/s', '/q', self._workdir], shell=True)
97 else:
98 shutil.rmtree(self._workdir)
76 self._dev_null_file.close() 99 self._dev_null_file.close()
77 100
78 @staticmethod 101 @staticmethod
79 def _confirm(message): 102 def _confirm(message):
80 """Show a confirmation prompt with the given message. 103 """Show a confirmation prompt with the given message.
81 104
82 Returns: 105 Returns:
83 A bool representing whether the user wishes to continue. 106 A bool representing whether the user wishes to continue.
84 """ 107 """
85 result = '' 108 result = ''
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 try: 268 try:
246 cherry_pick_change(options.branch, options.cherry_pick, 269 cherry_pick_change(options.branch, options.cherry_pick,
247 options.parent_checkout, options.dry_run) 270 options.parent_checkout, options.dry_run)
248 except Error as e: 271 except Error as e:
249 logging.error(e.message) 272 logging.error(e.message)
250 sys.exit(128) 273 sys.exit(128)
251 274
252 275
253 if __name__ == '__main__': 276 if __name__ == '__main__':
254 main() 277 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698