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

Side by Side Diff: git_cl.py

Issue 18173003: Replace --no-pager with GIT_PAGER=cat (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Code review comments addressed Created 7 years, 5 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 difflib 10 import difflib
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 logging.debug('Failed running %s', args) 62 logging.debug('Failed running %s', args)
63 if not error_ok: 63 if not error_ok:
64 DieWithError( 64 DieWithError(
65 'Command "%s" failed.\n%s' % ( 65 'Command "%s" failed.\n%s' % (
66 ' '.join(args), error_message or e.stdout or '')) 66 ' '.join(args), error_message or e.stdout or ''))
67 return e.stdout 67 return e.stdout
68 68
69 69
70 def RunGit(args, **kwargs): 70 def RunGit(args, **kwargs):
71 """Returns stdout.""" 71 """Returns stdout."""
72 return RunCommand(['git', '--no-pager'] + args, **kwargs) 72 return RunCommand(['git'] + args, **kwargs)
73 73
74 74
75 def RunGitWithCode(args): 75 def RunGitWithCode(args):
76 """Returns return code and stdout.""" 76 """Returns return code and stdout."""
77 try: 77 try:
78 out, code = subprocess2.communicate(['git', '--no-pager'] + args, 78 env = os.environ.copy()
79 # 'cat' is a magical git string that disables pagers on all platforms.
80 env['GIT_PAGER'] = 'cat'
81 out, code = subprocess2.communicate(['git'] + args,
82 env=env,
79 stdout=subprocess2.PIPE) 83 stdout=subprocess2.PIPE)
80 return code, out[0] 84 return code, out[0]
81 except ValueError: 85 except ValueError:
82 # When the subprocess fails, it returns None. That triggers a ValueError 86 # When the subprocess fails, it returns None. That triggers a ValueError
83 # when trying to unpack the return value into (out, code). 87 # when trying to unpack the return value into (out, code).
84 return 1, '' 88 return 1, ''
85 89
86 90
87 def usage(more): 91 def usage(more):
88 def hook(fn): 92 def hook(fn):
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 222
219 223
220 def print_stats(similarity, find_copies, args): 224 def print_stats(similarity, find_copies, args):
221 """Prints statistics about the change to the user.""" 225 """Prints statistics about the change to the user."""
222 # --no-ext-diff is broken in some versions of Git, so try to work around 226 # --no-ext-diff is broken in some versions of Git, so try to work around
223 # this by overriding the environment (but there is still a problem if the 227 # this by overriding the environment (but there is still a problem if the
224 # git config key "diff.external" is used). 228 # git config key "diff.external" is used).
225 env = os.environ.copy() 229 env = os.environ.copy()
226 if 'GIT_EXTERNAL_DIFF' in env: 230 if 'GIT_EXTERNAL_DIFF' in env:
227 del env['GIT_EXTERNAL_DIFF'] 231 del env['GIT_EXTERNAL_DIFF']
232 # 'cat' is a magical git string that disables pagers on all platforms.
233 env['GIT_PAGER'] = 'cat'
228 234
229 if find_copies: 235 if find_copies:
230 similarity_options = ['--find-copies-harder', '-l100000', 236 similarity_options = ['--find-copies-harder', '-l100000',
231 '-C%s' % similarity] 237 '-C%s' % similarity]
232 else: 238 else:
233 similarity_options = ['-M%s' % similarity] 239 similarity_options = ['-M%s' % similarity]
234 240
235 return subprocess2.call( 241 return subprocess2.call(
236 ['git', '--no-pager', 242 ['git',
237 'diff', '--no-ext-diff', '--stat'] + similarity_options + args, 243 'diff', '--no-ext-diff', '--stat'] + similarity_options + args,
238 env=env) 244 env=env)
239 245
240 246
241 class Settings(object): 247 class Settings(object):
242 def __init__(self): 248 def __init__(self):
243 self.default_server = None 249 self.default_server = None
244 self.cc = None 250 self.cc = None
245 self.root = None 251 self.root = None
246 self.is_git_svn = None 252 self.is_git_svn = None
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 DieWithError('Repo doesn\'t appear to be a git-svn repo.') 300 DieWithError('Repo doesn\'t appear to be a git-svn repo.')
295 301
296 # Try to figure out which remote branch we're based on. 302 # Try to figure out which remote branch we're based on.
297 # Strategy: 303 # Strategy:
298 # 1) iterate through our branch history and find the svn URL. 304 # 1) iterate through our branch history and find the svn URL.
299 # 2) find the svn-remote that fetches from the URL. 305 # 2) find the svn-remote that fetches from the URL.
300 306
301 # regexp matching the git-svn line that contains the URL. 307 # regexp matching the git-svn line that contains the URL.
302 git_svn_re = re.compile(r'^\s*git-svn-id: (\S+)@', re.MULTILINE) 308 git_svn_re = re.compile(r'^\s*git-svn-id: (\S+)@', re.MULTILINE)
303 309
310 env = os.environ.copy()
311 # 'cat' is a magical git string that disables pagers on all platforms.
312 env['GIT_PAGER'] = 'cat'
313
304 # We don't want to go through all of history, so read a line from the 314 # We don't want to go through all of history, so read a line from the
305 # pipe at a time. 315 # pipe at a time.
306 # The -100 is an arbitrary limit so we don't search forever. 316 # The -100 is an arbitrary limit so we don't search forever.
307 cmd = ['git', '--no-pager', 'log', '-100', '--pretty=medium'] 317 cmd = ['git', 'log', '-100', '--pretty=medium']
308 proc = subprocess2.Popen(cmd, stdout=subprocess2.PIPE) 318 proc = subprocess2.Popen(cmd, stdout=subprocess2.PIPE, env=env)
309 url = None 319 url = None
310 for line in proc.stdout: 320 for line in proc.stdout:
311 match = git_svn_re.match(line) 321 match = git_svn_re.match(line)
312 if match: 322 if match:
313 url = match.group(1) 323 url = match.group(1)
314 proc.stdout.close() # Cut pipe. 324 proc.stdout.close() # Cut pipe.
315 break 325 break
316 326
317 if url: 327 if url:
318 svn_remote_re = re.compile(r'^svn-remote\.([^.]+)\.url (.*)$') 328 svn_remote_re = re.compile(r'^svn-remote\.([^.]+)\.url (.*)$')
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 RunGit(['config', self._RietveldServer(), self.rietveld_server]) 687 RunGit(['config', self._RietveldServer(), self.rietveld_server])
678 else: 688 else:
679 RunGit(['config', '--unset', self._IssueSetting()]) 689 RunGit(['config', '--unset', self._IssueSetting()])
680 self.SetPatchset(0) 690 self.SetPatchset(0)
681 self.has_issue = False 691 self.has_issue = False
682 692
683 def GetChange(self, upstream_branch, author): 693 def GetChange(self, upstream_branch, author):
684 if not self.GitSanityChecks(upstream_branch): 694 if not self.GitSanityChecks(upstream_branch):
685 DieWithError('\nGit sanity check failure') 695 DieWithError('\nGit sanity check failure')
686 696
687 root = RunCommand(['git', '--no-pager', 'rev-parse', '--show-cdup']).strip() 697 env = os.environ.copy()
698 # 'cat' is a magical git string that disables pagers on all platforms.
699 env['GIT_PAGER'] = 'cat'
700
701 root = RunCommand(['git', 'rev-parse', '--show-cdup'], env=env).strip()
688 if not root: 702 if not root:
689 root = '.' 703 root = '.'
690 absroot = os.path.abspath(root) 704 absroot = os.path.abspath(root)
691 705
692 # We use the sha1 of HEAD as a name of this change. 706 # We use the sha1 of HEAD as a name of this change.
693 name = RunCommand(['git', '--no-pager', 'rev-parse', 'HEAD']).strip() 707 name = RunCommand(['git', 'rev-parse', 'HEAD'], env=env).strip()
694 # Need to pass a relative path for msysgit. 708 # Need to pass a relative path for msysgit.
695 try: 709 try:
696 files = scm.GIT.CaptureStatus([root], '.', upstream_branch) 710 files = scm.GIT.CaptureStatus([root], '.', upstream_branch)
697 except subprocess2.CalledProcessError: 711 except subprocess2.CalledProcessError:
698 DieWithError( 712 DieWithError(
699 ('\nFailed to diff against upstream branch %s!\n\n' 713 ('\nFailed to diff against upstream branch %s!\n\n'
700 'This branch probably doesn\'t exist anymore. To reset the\n' 714 'This branch probably doesn\'t exist anymore. To reset the\n'
701 'tracking branch, please run\n' 715 'tracking branch, please run\n'
702 ' git branch --set-upstream %s trunk\n' 716 ' git branch --set-upstream %s trunk\n'
703 'replacing trunk with origin/master or the relevant branch') % 717 'replacing trunk with origin/master or the relevant branch') %
704 (upstream_branch, self.GetBranch())) 718 (upstream_branch, self.GetBranch()))
705 719
706 issue = self.GetIssue() 720 issue = self.GetIssue()
707 patchset = self.GetPatchset() 721 patchset = self.GetPatchset()
708 if issue: 722 if issue:
709 description = self.GetDescription() 723 description = self.GetDescription()
710 else: 724 else:
711 # If the change was never uploaded, use the log messages of all commits 725 # If the change was never uploaded, use the log messages of all commits
712 # up to the branch point, as git cl upload will prefill the description 726 # up to the branch point, as git cl upload will prefill the description
713 # with these log messages. 727 # with these log messages.
714 description = RunCommand(['git', '--no-pager', 728 description = RunCommand(['git',
715 'log', '--pretty=format:%s%n%n%b', 729 'log', '--pretty=format:%s%n%n%b',
716 '%s...' % (upstream_branch)]).strip() 730 '%s...' % (upstream_branch)],
731 env=env).strip()
717 732
718 if not author: 733 if not author:
719 author = RunGit(['config', 'user.email']).strip() or None 734 author = RunGit(['config', 'user.email']).strip() or None
720 return presubmit_support.GitChange( 735 return presubmit_support.GitChange(
721 name, 736 name,
722 description, 737 description,
723 absroot, 738 absroot,
724 files, 739 files,
725 issue, 740 issue,
726 patchset, 741 patchset,
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 # Git patches have a/ at the beginning of source paths. We strip that out 1759 # Git patches have a/ at the beginning of source paths. We strip that out
1745 # with a sed script rather than the -p flag to patch so we can feed either 1760 # with a sed script rather than the -p flag to patch so we can feed either
1746 # Git or svn-style patches into the same apply command. 1761 # Git or svn-style patches into the same apply command.
1747 # re.sub() should be used but flags=re.MULTILINE is only in python 2.7. 1762 # re.sub() should be used but flags=re.MULTILINE is only in python 2.7.
1748 try: 1763 try:
1749 patch_data = subprocess2.check_output( 1764 patch_data = subprocess2.check_output(
1750 ['sed', '-e', 's|^--- a/|--- |; s|^+++ b/|+++ |'], stdin=patch_data) 1765 ['sed', '-e', 's|^--- a/|--- |; s|^+++ b/|+++ |'], stdin=patch_data)
1751 except subprocess2.CalledProcessError: 1766 except subprocess2.CalledProcessError:
1752 DieWithError('Git patch mungling failed.') 1767 DieWithError('Git patch mungling failed.')
1753 logging.info(patch_data) 1768 logging.info(patch_data)
1769 env = os.environ.copy()
1770 # 'cat' is a magical git string that disables pagers on all platforms.
1771 env['GIT_PAGER'] = 'cat'
1772
1754 # We use "git apply" to apply the patch instead of "patch" so that we can 1773 # We use "git apply" to apply the patch instead of "patch" so that we can
1755 # pick up file adds. 1774 # pick up file adds.
1756 # The --index flag means: also insert into the index (so we catch adds). 1775 # The --index flag means: also insert into the index (so we catch adds).
1757 cmd = ['git', '--no-pager', 'apply', '--index', '-p0'] 1776 cmd = ['git', 'apply', '--index', '-p0']
1758 if options.reject: 1777 if options.reject:
1759 cmd.append('--reject') 1778 cmd.append('--reject')
1760 try: 1779 try:
1761 subprocess2.check_call(cmd, stdin=patch_data, stdout=subprocess2.VOID) 1780 subprocess2.check_call(cmd, env=env,
1781 stdin=patch_data, stdout=subprocess2.VOID)
1762 except subprocess2.CalledProcessError: 1782 except subprocess2.CalledProcessError:
1763 DieWithError('Failed to apply the patch') 1783 DieWithError('Failed to apply the patch')
1764 1784
1765 # If we had an issue, commit the current state and register the issue. 1785 # If we had an issue, commit the current state and register the issue.
1766 if not options.nocommit: 1786 if not options.nocommit:
1767 RunGit(['commit', '-m', 'patch from issue %s' % issue]) 1787 RunGit(['commit', '-m', 'patch from issue %s' % issue])
1768 cl = Changelist() 1788 cl = Changelist()
1769 cl.SetIssue(issue) 1789 cl.SetIssue(issue)
1770 cl.SetPatchset(patchset) 1790 cl.SetPatchset(patchset)
1771 print "Committed patch locally." 1791 print "Committed patch locally."
1772 else: 1792 else:
1773 print "Patch applied to index." 1793 print "Patch applied to index."
1774 return 0 1794 return 0
1775 1795
1776 1796
1777 def CMDrebase(parser, args): 1797 def CMDrebase(parser, args):
1778 """rebase current branch on top of svn repo""" 1798 """rebase current branch on top of svn repo"""
1779 # Provide a wrapper for git svn rebase to help avoid accidental 1799 # Provide a wrapper for git svn rebase to help avoid accidental
1780 # git svn dcommit. 1800 # git svn dcommit.
1781 # It's the only command that doesn't use parser at all since we just defer 1801 # It's the only command that doesn't use parser at all since we just defer
1782 # execution to git-svn. 1802 # execution to git-svn.
1783 return subprocess2.call(['git', '--no-pager', 'svn', 'rebase'] + args) 1803 env = os.environ.copy()
1804 # 'cat' is a magical git string that disables pagers on all platforms.
1805 env['GIT_PAGER'] = 'cat'
1806
1807 return subprocess2.call(['git', 'svn', 'rebase'] + args, env=env)
1784 1808
1785 1809
1786 def GetTreeStatus(): 1810 def GetTreeStatus():
1787 """Fetches the tree status and returns either 'open', 'closed', 1811 """Fetches the tree status and returns either 'open', 'closed',
1788 'unknown' or 'unset'.""" 1812 'unknown' or 'unset'."""
1789 url = settings.GetTreeStatusUrl(error_ok=True) 1813 url = settings.GetTreeStatusUrl(error_ok=True)
1790 if url: 1814 if url:
1791 status = urllib2.urlopen(url).read().lower() 1815 status = urllib2.urlopen(url).read().lower()
1792 if status.find('closed') != -1 or status == '0': 1816 if status.find('closed') != -1 or status == '0':
1793 return 'closed' 1817 return 'closed'
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
2142 GenUsage(parser, 'help') 2166 GenUsage(parser, 'help')
2143 return CMDhelp(parser, argv) 2167 return CMDhelp(parser, argv)
2144 2168
2145 2169
2146 if __name__ == '__main__': 2170 if __name__ == '__main__':
2147 # These affect sys.stdout so do it outside of main() to simplify mocks in 2171 # These affect sys.stdout so do it outside of main() to simplify mocks in
2148 # unit testing. 2172 # unit testing.
2149 fix_encoding.fix_encoding() 2173 fix_encoding.fix_encoding()
2150 colorama.init() 2174 colorama.init()
2151 sys.exit(main(sys.argv[1:])) 2175 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