Commit 1c7db8e6 authored by maruel@chromium.org's avatar maruel@chromium.org

Add "diff against" support when sending try patches.

This is mostly useful with git when diffing against arbitrary branches.

Review URL: http://codereview.chromium.org/524046

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@35684 0039d316-1c4b-4281-b951-d872f2087c98
parent 01d8c1d1
......@@ -550,7 +550,7 @@ class SVN(object):
return output
@staticmethod
def DiffItem(filename, full_move=False):
def DiffItem(filename, full_move=False, revision=None):
"""Diffs a single file.
Be sure to be in the appropriate directory before calling to have the
......@@ -570,7 +570,10 @@ class SVN(object):
bogus_dir = tempfile.mkdtemp()
try:
# Grabs the diff data.
data = SVN.Capture(["diff", "--config-dir", bogus_dir, filename], None)
command = ["diff", "--config-dir", bogus_dir, filename]
if revision is not None:
command.extend(['--revision', revision])
data = SVN.Capture(command, None)
if data:
pass
elif SVN.IsMoved(filename):
......@@ -600,7 +603,7 @@ class SVN(object):
return data
@staticmethod
def GenerateDiff(filenames, root=None, full_move=False):
def GenerateDiff(filenames, root=None, full_move=False, revision=None):
"""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
......@@ -618,7 +621,7 @@ class SVN(object):
try:
os.chdir(root)
diff = "".join(filter(None,
[SVN.DiffItem(RelativePath(f, root),
[SVN.DiffItem(RelativePath(f, root, revision),
full_move=full_move)
for f in filenames]))
finally:
......
......@@ -63,8 +63,10 @@ class SVNUnittest(TryChangeTestsBase):
def testBasic(self):
trychange.scm.SVN.GetCheckoutRoot(self.fake_root).AndReturn(self.fake_root)
trychange.scm.SVN.GenerateDiff(['foo.txt', 'bar.txt'], self.fake_root,
full_move=True).AndReturn('A diff')
trychange.scm.SVN.GenerateDiff(['foo.txt', 'bar.txt'],
self.fake_root,
full_move=True,
revision=None).AndReturn('A diff')
trychange.scm.SVN.GetEmail(self.fake_root).AndReturn('georges@example.com')
self.mox.ReplayAll()
svn = trychange.SVN(self.options, self.fake_root)
......@@ -87,7 +89,8 @@ class GITUnittest(TryChangeTestsBase):
def testBasic(self):
trychange.scm.GIT.GetCheckoutRoot(self.fake_root).AndReturn(self.fake_root)
trychange.scm.GIT.GenerateDiff(self.fake_root,
full_move=True).AndReturn('A diff')
full_move=True,
branch=None).AndReturn('A diff')
trychange.scm.GIT.GetPatchName(self.fake_root).AndReturn('bleh-1233')
trychange.scm.GIT.GetEmail(self.fake_root).AndReturn('georges@example.com')
self.mox.ReplayAll()
......
......@@ -74,8 +74,12 @@ def EscapeDot(name):
class SCM(object):
"""Simplistic base class to implement one function: ProcessOptions."""
def __init__(self, options, cwd):
self.checkout_root = cwd
def __init__(self, options, path):
items = path.split('@')
assert len(items) <= 2
self.checkout_root = items[0]
items.append(None)
self.diff_against = items[1]
self.options = options
self.files = self.options.files
self.options.files = None
......@@ -176,7 +180,8 @@ class SVN(SCM):
if f[0][0] not in excluded
]
os.chdir(previous_cwd)
return scm.SVN.GenerateDiff(self.files, self.checkout_root, full_move=True)
return scm.SVN.GenerateDiff(self.files, self.checkout_root, full_move=True,
revision=self.diff_against)
class GIT(SCM):
......@@ -202,7 +207,8 @@ class GIT(SCM):
def GenerateDiff(self):
# For now, ignores self.files
return scm.GIT.GenerateDiff(self.checkout_root, full_move=True)
return scm.GIT.GenerateDiff(self.checkout_root, full_move=True,
branch=self.diff_against)
def _ParseSendChangeOptions(options):
......@@ -365,16 +371,17 @@ def GuessVCS(options, path):
A SCM instance. Exits if the SCM can't be guessed.
"""
__pychecker__ = 'no-returnvalues'
real_path = path.split('@')[0]
logging.info("GuessVCS(%s)" % path)
# Subversion has a .svn in all working directories.
if os.path.isdir(os.path.join(path, '.svn')):
if os.path.isdir(os.path.join(real_path, '.svn')):
return SVN(options, path)
# 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"],
path)
real_path)
return GIT(options, path)
except gclient_utils.CheckCallError, e:
if e.retcode != errno.ENOENT and e.retcode != 128:
......@@ -464,7 +471,9 @@ def TryChange(argv,
help="Used as -pN parameter to patch")
group.add_option("-s", "--sub_rep", action="append", default=[],
help="Subcheckout to use in addition. This is mainly "
"useful for gclient-style checkouts.")
"useful for gclient-style checkouts. Use @rev or "
"@branch or @branch1..branch2 to specify the "
"revision/branch to diff against.")
group.add_option("--no_gclient", action="store_true",
help="Disable automatic search for gclient checkout.")
parser.add_option_group(group)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment