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

Side by Side Diff: git_cl.py

Issue 14104005: Fix 236148: Avoid triggering a pager in internal git commands. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Fixed some tests and other calls too. Created 7 years, 7 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 | scm.py » ('j') | 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 (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 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 5
6 # Copyright (C) 2008 Evan Martin <martine@danga.com> 6 # Copyright (C) 2008 Evan Martin <martine@danga.com>
7 7
8 """A git-command for integrating reviews on Rietveld.""" 8 """A git-command for integrating reviews on Rietveld."""
9 9
10 import json 10 import json
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 logging.debug('Failed running %s', args) 58 logging.debug('Failed running %s', args)
59 if not error_ok: 59 if not error_ok:
60 DieWithError( 60 DieWithError(
61 'Command "%s" failed.\n%s' % ( 61 'Command "%s" failed.\n%s' % (
62 ' '.join(args), error_message or e.stdout or '')) 62 ' '.join(args), error_message or e.stdout or ''))
63 return e.stdout 63 return e.stdout
64 64
65 65
66 def RunGit(args, **kwargs): 66 def RunGit(args, **kwargs):
67 """Returns stdout.""" 67 """Returns stdout."""
68 return RunCommand(['git'] + args, **kwargs) 68 return RunCommand(['git', '--no-pager'] + args, **kwargs)
69 69
70 70
71 def RunGitWithCode(args): 71 def RunGitWithCode(args):
72 """Returns return code and stdout.""" 72 """Returns return code and stdout."""
73 try: 73 try:
74 out, code = subprocess2.communicate(['git'] + args, stdout=subprocess2.PIPE) 74 out, code = subprocess2.communicate(['git', '--no-pager'] + args,
75 stdout=subprocess2.PIPE)
75 return code, out[0] 76 return code, out[0]
76 except ValueError: 77 except ValueError:
77 # When the subprocess fails, it returns None. That triggers a ValueError 78 # When the subprocess fails, it returns None. That triggers a ValueError
78 # when trying to unpack the return value into (out, code). 79 # when trying to unpack the return value into (out, code).
79 return 1, '' 80 return 1, ''
80 81
81 82
82 def usage(more): 83 def usage(more):
83 def hook(fn): 84 def hook(fn):
84 fn.usage_more = more 85 fn.usage_more = more
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 if 'GIT_EXTERNAL_DIFF' in env: 222 if 'GIT_EXTERNAL_DIFF' in env:
222 del env['GIT_EXTERNAL_DIFF'] 223 del env['GIT_EXTERNAL_DIFF']
223 224
224 if find_copies: 225 if find_copies:
225 similarity_options = ['--find-copies-harder', '-l100000', 226 similarity_options = ['--find-copies-harder', '-l100000',
226 '-C%s' % similarity] 227 '-C%s' % similarity]
227 else: 228 else:
228 similarity_options = ['-M%s' % similarity] 229 similarity_options = ['-M%s' % similarity]
229 230
230 return subprocess2.call( 231 return subprocess2.call(
231 ['git', 'diff', '--no-ext-diff', '--stat'] + similarity_options + args, 232 ['git', '--no-pager',
233 'diff', '--no-ext-diff', '--stat'] + similarity_options + args,
232 env=env) 234 env=env)
233 235
234 236
235 class Settings(object): 237 class Settings(object):
236 def __init__(self): 238 def __init__(self):
237 self.default_server = None 239 self.default_server = None
238 self.cc = None 240 self.cc = None
239 self.root = None 241 self.root = None
240 self.is_git_svn = None 242 self.is_git_svn = None
241 self.svn_branch = None 243 self.svn_branch = None
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 # Strategy: 292 # Strategy:
291 # 1) iterate through our branch history and find the svn URL. 293 # 1) iterate through our branch history and find the svn URL.
292 # 2) find the svn-remote that fetches from the URL. 294 # 2) find the svn-remote that fetches from the URL.
293 295
294 # regexp matching the git-svn line that contains the URL. 296 # regexp matching the git-svn line that contains the URL.
295 git_svn_re = re.compile(r'^\s*git-svn-id: (\S+)@', re.MULTILINE) 297 git_svn_re = re.compile(r'^\s*git-svn-id: (\S+)@', re.MULTILINE)
296 298
297 # We don't want to go through all of history, so read a line from the 299 # We don't want to go through all of history, so read a line from the
298 # pipe at a time. 300 # pipe at a time.
299 # The -100 is an arbitrary limit so we don't search forever. 301 # The -100 is an arbitrary limit so we don't search forever.
300 cmd = ['git', 'log', '-100', '--pretty=medium'] 302 cmd = ['git', '--no-pager', 'log', '-100', '--pretty=medium']
301 proc = subprocess2.Popen(cmd, stdout=subprocess2.PIPE) 303 proc = subprocess2.Popen(cmd, stdout=subprocess2.PIPE)
302 url = None 304 url = None
303 for line in proc.stdout: 305 for line in proc.stdout:
304 match = git_svn_re.match(line) 306 match = git_svn_re.match(line)
305 if match: 307 if match:
306 url = match.group(1) 308 url = match.group(1)
307 proc.stdout.close() # Cut pipe. 309 proc.stdout.close() # Cut pipe.
308 break 310 break
309 311
310 if url: 312 if url:
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 RunGit(['config', self._RietveldServer(), self.rietveld_server]) 661 RunGit(['config', self._RietveldServer(), self.rietveld_server])
660 else: 662 else:
661 RunGit(['config', '--unset', self._IssueSetting()]) 663 RunGit(['config', '--unset', self._IssueSetting()])
662 self.SetPatchset(0) 664 self.SetPatchset(0)
663 self.has_issue = False 665 self.has_issue = False
664 666
665 def GetChange(self, upstream_branch, author): 667 def GetChange(self, upstream_branch, author):
666 if not self.GitSanityChecks(upstream_branch): 668 if not self.GitSanityChecks(upstream_branch):
667 DieWithError('\nGit sanity check failure') 669 DieWithError('\nGit sanity check failure')
668 670
669 root = RunCommand(['git', 'rev-parse', '--show-cdup']).strip() or '.' 671 root = RunCommand(['git', '--no-pager', 'rev-parse', '--show-cdup']).strip()
672 if not root:
673 root = '.'
670 absroot = os.path.abspath(root) 674 absroot = os.path.abspath(root)
671 675
672 # We use the sha1 of HEAD as a name of this change. 676 # We use the sha1 of HEAD as a name of this change.
673 name = RunCommand(['git', 'rev-parse', 'HEAD']).strip() 677 name = RunCommand(['git', '--no-pager', 'rev-parse', 'HEAD']).strip()
674 # Need to pass a relative path for msysgit. 678 # Need to pass a relative path for msysgit.
675 try: 679 try:
676 files = scm.GIT.CaptureStatus([root], '.', upstream_branch) 680 files = scm.GIT.CaptureStatus([root], '.', upstream_branch)
677 except subprocess2.CalledProcessError: 681 except subprocess2.CalledProcessError:
678 DieWithError( 682 DieWithError(
679 ('\nFailed to diff against upstream branch %s!\n\n' 683 ('\nFailed to diff against upstream branch %s!\n\n'
680 'This branch probably doesn\'t exist anymore. To reset the\n' 684 'This branch probably doesn\'t exist anymore. To reset the\n'
681 'tracking branch, please run\n' 685 'tracking branch, please run\n'
682 ' git branch --set-upstream %s trunk\n' 686 ' git branch --set-upstream %s trunk\n'
683 'replacing trunk with origin/master or the relevant branch') % 687 'replacing trunk with origin/master or the relevant branch') %
684 (upstream_branch, self.GetBranch())) 688 (upstream_branch, self.GetBranch()))
685 689
686 issue = self.GetIssue() 690 issue = self.GetIssue()
687 patchset = self.GetPatchset() 691 patchset = self.GetPatchset()
688 if issue: 692 if issue:
689 description = self.GetDescription() 693 description = self.GetDescription()
690 else: 694 else:
691 # If the change was never uploaded, use the log messages of all commits 695 # If the change was never uploaded, use the log messages of all commits
692 # up to the branch point, as git cl upload will prefill the description 696 # up to the branch point, as git cl upload will prefill the description
693 # with these log messages. 697 # with these log messages.
694 description = RunCommand(['git', 'log', '--pretty=format:%s%n%n%b', 698 description = RunCommand(['git', '--no-pager',
699 'log', '--pretty=format:%s%n%n%b',
695 '%s...' % (upstream_branch)]).strip() 700 '%s...' % (upstream_branch)]).strip()
696 701
697 if not author: 702 if not author:
698 author = RunGit(['config', 'user.email']).strip() or None 703 author = RunGit(['config', 'user.email']).strip() or None
699 return presubmit_support.GitChange( 704 return presubmit_support.GitChange(
700 name, 705 name,
701 description, 706 description,
702 absroot, 707 absroot,
703 files, 708 files,
704 issue, 709 issue,
(...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 # re.sub() should be used but flags=re.MULTILINE is only in python 2.7. 1706 # re.sub() should be used but flags=re.MULTILINE is only in python 2.7.
1702 try: 1707 try:
1703 patch_data = subprocess2.check_output( 1708 patch_data = subprocess2.check_output(
1704 ['sed', '-e', 's|^--- a/|--- |; s|^+++ b/|+++ |'], stdin=patch_data) 1709 ['sed', '-e', 's|^--- a/|--- |; s|^+++ b/|+++ |'], stdin=patch_data)
1705 except subprocess2.CalledProcessError: 1710 except subprocess2.CalledProcessError:
1706 DieWithError('Git patch mungling failed.') 1711 DieWithError('Git patch mungling failed.')
1707 logging.info(patch_data) 1712 logging.info(patch_data)
1708 # We use "git apply" to apply the patch instead of "patch" so that we can 1713 # We use "git apply" to apply the patch instead of "patch" so that we can
1709 # pick up file adds. 1714 # pick up file adds.
1710 # The --index flag means: also insert into the index (so we catch adds). 1715 # The --index flag means: also insert into the index (so we catch adds).
1711 cmd = ['git', 'apply', '--index', '-p0'] 1716 cmd = ['git', '--no-pager', 'apply', '--index', '-p0']
1712 if options.reject: 1717 if options.reject:
1713 cmd.append('--reject') 1718 cmd.append('--reject')
1714 try: 1719 try:
1715 subprocess2.check_call(cmd, stdin=patch_data, stdout=subprocess2.VOID) 1720 subprocess2.check_call(cmd, stdin=patch_data, stdout=subprocess2.VOID)
1716 except subprocess2.CalledProcessError: 1721 except subprocess2.CalledProcessError:
1717 DieWithError('Failed to apply the patch') 1722 DieWithError('Failed to apply the patch')
1718 1723
1719 # If we had an issue, commit the current state and register the issue. 1724 # If we had an issue, commit the current state and register the issue.
1720 if not options.nocommit: 1725 if not options.nocommit:
1721 RunGit(['commit', '-m', 'patch from issue %s' % issue]) 1726 RunGit(['commit', '-m', 'patch from issue %s' % issue])
1722 cl = Changelist() 1727 cl = Changelist()
1723 cl.SetIssue(issue) 1728 cl.SetIssue(issue)
1724 cl.SetPatchset(patchset) 1729 cl.SetPatchset(patchset)
1725 print "Committed patch locally." 1730 print "Committed patch locally."
1726 else: 1731 else:
1727 print "Patch applied to index." 1732 print "Patch applied to index."
1728 return 0 1733 return 0
1729 1734
1730 1735
1731 def CMDrebase(parser, args): 1736 def CMDrebase(parser, args):
1732 """rebase current branch on top of svn repo""" 1737 """rebase current branch on top of svn repo"""
1733 # Provide a wrapper for git svn rebase to help avoid accidental 1738 # Provide a wrapper for git svn rebase to help avoid accidental
1734 # git svn dcommit. 1739 # git svn dcommit.
1735 # It's the only command that doesn't use parser at all since we just defer 1740 # It's the only command that doesn't use parser at all since we just defer
1736 # execution to git-svn. 1741 # execution to git-svn.
1737 return subprocess2.call(['git', 'svn', 'rebase'] + args) 1742 return subprocess2.call(['git', '--no-pager', 'svn', 'rebase'] + args)
1738 1743
1739 1744
1740 def GetTreeStatus(): 1745 def GetTreeStatus():
1741 """Fetches the tree status and returns either 'open', 'closed', 1746 """Fetches the tree status and returns either 'open', 'closed',
1742 'unknown' or 'unset'.""" 1747 'unknown' or 'unset'."""
1743 url = settings.GetTreeStatusUrl(error_ok=True) 1748 url = settings.GetTreeStatusUrl(error_ok=True)
1744 if url: 1749 if url:
1745 status = urllib2.urlopen(url).read().lower() 1750 status = urllib2.urlopen(url).read().lower()
1746 if status.find('closed') != -1 or status == '0': 1751 if status.find('closed') != -1 or status == '0':
1747 return 'closed' 1752 return 'closed'
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1992 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) 1997 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e)))
1993 1998
1994 # Not a known command. Default to help. 1999 # Not a known command. Default to help.
1995 GenUsage(parser, 'help') 2000 GenUsage(parser, 'help')
1996 return CMDhelp(parser, argv) 2001 return CMDhelp(parser, argv)
1997 2002
1998 2003
1999 if __name__ == '__main__': 2004 if __name__ == '__main__':
2000 fix_encoding.fix_encoding() 2005 fix_encoding.fix_encoding()
2001 sys.exit(main(sys.argv[1:])) 2006 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « no previous file | scm.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698