Index: trychange.py |
diff --git a/trychange.py b/trychange.py |
index 38d817ca8ed4960ca1dc562ceedbe223981890bb..abae97182eba3c657bbeeee400158215cf2ce5eb 100755 |
--- a/trychange.py |
+++ b/trychange.py |
@@ -72,42 +72,42 @@ def EscapeDot(name): |
class SCM(object): |
"""Simplistic base class to implement one function: ProcessOptions.""" |
- def __init__(self, options): |
+ def __init__(self, options, cwd): |
+ self.checkout_root = cwd |
self.options = options |
+ self.files = self.options.files |
+ self.options.files = None |
def GetFileNames(self): |
"""Return the list of files in the diff.""" |
- return self.options.files |
+ return self.files |
class SVN(SCM): |
"""Gathers the options and diff for a subversion checkout.""" |
def __init__(self, *args, **kwargs): |
SCM.__init__(self, *args, **kwargs) |
- self.checkout_root = scm.SVN.GetCheckoutRoot(os.getcwd()) |
- if not self.options.diff: |
- # Generate the diff from the scm. |
- self.options.diff = self._GenerateDiff() |
+ self.checkout_root = scm.SVN.GetCheckoutRoot(self.checkout_root) |
if not self.options.email: |
# Assumes the svn credential is an email address. |
self.options.email = scm.SVN.GetEmail(self.checkout_root) |
- def _GenerateDiff(self): |
+ def GenerateDiff(self): |
"""Returns a string containing the diff for the given file list. |
The files in the list should either be absolute paths or relative to the |
given root. |
""" |
- if not self.options.files: |
+ if not self.files: |
previous_cwd = os.getcwd() |
os.chdir(self.checkout_root) |
excluded = ['!', '?', 'X', ' ', '~'] |
- self.options.files = [ |
+ self.files = [ |
f[1] for f in scm.SVN.CaptureStatus(self.checkout_root) |
if f[0][0] not in excluded |
] |
os.chdir(previous_cwd) |
- return scm.SVN.GenerateDiff(self.options.files, full_move=True) |
+ return scm.SVN.GenerateDiff(self.files, self.checkout_root, full_move=True) |
def GetLocalRoot(self): |
"""Return the path of the repository root.""" |
@@ -130,10 +130,7 @@ class GIT(SCM): |
"""Gathers the options and diff for a git checkout.""" |
def __init__(self, *args, **kwargs): |
SCM.__init__(self, *args, **kwargs) |
- self.checkout_root = scm.GIT.GetCheckoutRoot(os.getcwd()) |
- if not self.options.diff: |
- self.options.diff = scm.GIT.GenerateDiff(self.checkout_root, |
- full_move=True) |
+ self.checkout_root = scm.GIT.GetCheckoutRoot(self.checkout_root) |
if not self.options.name: |
self.options.name = scm.GIT.GetPatchName(self.checkout_root) |
if not self.options.email: |
@@ -143,6 +140,10 @@ class GIT(SCM): |
"""Return the path of the repository root.""" |
return self.checkout_root |
+ def GenerateDiff(self): |
+ # For now, ignores self.files |
+ return scm.GIT.GenerateDiff(self.checkout_root, full_move=True) |
+ |
def GetBots(self): |
try: |
# A git checkout is always a full checkout. |
@@ -291,7 +292,7 @@ def _SendChangeSVN(options): |
shutil.rmtree(temp_dir, True) |
-def GuessVCS(options): |
+def GuessVCS(options, cwd): |
"""Helper to guess the version control system. |
NOTE: Very similar to upload.GuessVCS. Doesn't look for hg since we don't |
@@ -306,16 +307,16 @@ def GuessVCS(options): |
""" |
__pychecker__ = 'no-returnvalues' |
# Subversion has a .svn in all working directories. |
- if os.path.isdir('.svn'): |
+ if os.path.isdir(os.path.join(cwd, '.svn')): |
logging.info("Guessed VCS = Subversion") |
- return SVN(options) |
+ return SVN(options, cwd) |
# Git has a command to test if you're in a git tree. |
# Try running it, but don't die if we don't have git installed. |
try: |
- gclient_utils.CheckCall(["git", "rev-parse", "--is-inside-work-tree"]) |
+ gclient_utils.CheckCall(["git", "rev-parse", "--is-inside-work-tree"], cwd) |
logging.info("Guessed VCS = Git") |
- return GIT(options) |
+ return GIT(options, cwd) |
except gclient_utils.CheckCallError, e: |
if e.retcode != 2: # ENOENT -- they don't have git installed. |
raise |
@@ -398,6 +399,9 @@ def TryChange(argv, |
"patch created in a subdirectory") |
group.add_option("--patchlevel", type='int', metavar="LEVEL", |
help="Used as -pN parameter to patch") |
+ group.add_option("--sub_rep", action="append", default=["."], |
+ help="Subcheckout to use in addition. This is mainly " |
+ "useful for gclient-style checkouts.") |
parser.add_option_group(group) |
group = optparse.OptionGroup(parser, "Access the try server by HTTP") |
@@ -440,6 +444,15 @@ def TryChange(argv, |
parser.error('Please specify an access method.') |
try: |
+ # Process the VCS in any case at least to retrieve the email address. |
+ checkouts = [] |
+ for item in options.sub_rep: |
+ checkout = GuessVCS(options, item) |
+ if checkout.GetLocalRoot() in [c.GetLocalRoot() for c in checkouts]: |
+ parser.error('Specified the root %s two times.' % |
+ checkout.GetLocalRoot()) |
+ checkouts.append(checkout) |
+ |
# Convert options.diff into the content of the diff. |
if options.url: |
if options.files: |
@@ -449,26 +462,30 @@ def TryChange(argv, |
if options.files: |
parser.error('You cannot specify files and --diff at the same time.') |
options.diff = gclient_utils.FileRead(options.diff, 'rb') |
- # Process the VCS in any case at least to retrieve the email address. |
- try: |
- options.scm = GuessVCS(options) |
- except NoTryServerAccess, e: |
- # If we got the diff, we don't care. |
- if not options.diff: |
- # TODO(maruel): Raise what? |
- raise |
- |
- # Get try slaves from PRESUBMIT.py files if not specified. |
+ else: |
+ # Use this as the base. |
+ root = checkouts[0].GetLocalRoot() |
+ diffs = [] |
+ for checkout in checkouts: |
+ diff = checkout.GenerateDiff().splitlines(True) |
+ # Munge it. |
+ path_diff = gclient_utils.PathDifference(root, checkout.GetLocalRoot()) |
+ for i in range(len(diff)): |
+ if diff[i].startswith('--- ') or diff[i].startswith('+++ '): |
+ diff[i] = diff[i][0:3] + path_diff + diff[i][4:] |
+ diffs.extend(diff) |
+ options.diff = ''.join(diffs) |
+ |
if not options.bot: |
+ # Get try slaves from PRESUBMIT.py files if not specified. |
# Even if the diff comes from options.url, use the local checkout for bot |
# selection. |
try: |
- # Get try slaves from PRESUBMIT.py files if not specified. |
import presubmit_support |
- root_presubmit = options.scm.GetBots() |
+ root_presubmit = checkouts[0].GetBots() |
options.bot = presubmit_support.DoGetTrySlaves( |
- options.scm.GetFileNames(), |
- options.scm.GetLocalRoot(), |
+ checkouts[0].GetFileNames(), |
+ checkouts[0].GetLocalRoot(), |
root_presubmit, |
False, |
sys.stdout) |