Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 179 lines (141 sloc) 6.06 kb
406e897 Fix python paths in scripts
Adam Simpkins authored
1 #!/usr/bin/python -tt
8563952 Initial commit
Adam Simpkins authored
2 #
3 # Copyright 2009-2010 Facebook, Inc.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 # not use this file except in compliance with the License. You may obtain
7 # a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
15 # under the License.
16 #
17 """
18 git-review - a tool to review changes in a git repository
19
20 This tool provides an interactive shell for reviewing diffs in a git
21 repository. It accepts arguments similar to "git diff" for specifying the
22 diffs to review. When started, it walks the user through each file changed,
23 prompting to open an external diff program or text editor for each file.
24
25 Configuration:
26
27 - GIT_REVIEW_DIFF
28 If set, this environment variable specifies the program to use to view diffs
29 for modified files. If unset, the default diff program is tkdiff when
30 DISPLAY is set, and "vimdiff -R" when DISPLAY is unset.
31
32 - GIT_REVIEW_VIEW, GIT_EDITOR, VISUAL, EDITOR
33 These environment variables are checked in order to find the program to use
34 to view new files. If none of these are set, vi is used.
35 """
36
37 import optparse
38 import os
39 import sys
40
41 import gitreview.git as git
42 import gitreview.review as review
43
44 RETCODE_SUCCESS = 0
45 RETCODE_ARGUMENTS_ERROR = 1
46
47 f_progname = os.path.basename(sys.argv[0])
48
49
50 class OptionsError(Exception):
51 pass
52
53
54 class UsageError(Exception):
55 pass
56
57
58 class NoDiffsError(Exception):
59 pass
60
61
62 class Options(optparse.OptionParser):
63 def __init__(self):
64 optparse.OptionParser.__init__(self, add_help_option=False,
65 usage='%prog [options]')
66 self.add_option('-c', '--commit',
67 action='store', dest='commit', default=None,
68 help='Diff the specified commit against its parent')
69 self.add_option('--cached',
70 action='store_true', dest='cached', default=False,
71 help='Diff against the index instead of the working '
72 'tree')
73 self.add_option('--git-dir',
74 action='store', dest='gitDir',
75 metavar='DIRECTORY', default=None,
76 help='Path to the git repository directory')
77 self.add_option('--work-tree',
78 action='store', dest='workTree',
79 metavar='DIRECTORY', default=None,
80 help='Path to the git repository working tree')
81 self.add_option('-?', '--help',
82 action='callback', callback=self.__helpCallback,
83 help='Print this help message and exit')
84
85 def __helpCallback(self, option, opt, value, parser):
86 raise UsageError()
87
88 def error(self, msg):
89 # This is called automatically by optparse when an error in the command
90 # line options is encountered.
91 raise OptionsError(msg)
92
93 def printUsage(self, file = sys.stdout):
94 self.print_usage(file = file)
95
96 def printHelp(self, file = sys.stdout):
97 self.print_help(file = file)
98
99 def __getattr__(self, name):
100 if name.startswith('__'):
101 raise AttributeError(name)
102
103 # Allow attributes of self.__options to be accessed directly
104 return getattr(self.__options, name)
105
106 def parseArgv(self, argv):
107 # parse the options
108 (self.__options, args) = self.parse_args(argv[1:])
109
110 # Parse the commit arguments
111 if self.__options.commit is not None:
112 # If --commit was specified, diff that commit against its parent
113 if self.__options.cached:
114 msg = '--commit and --cached are mutually exclusive'
115 raise OptionsError(msg)
116 if args:
117 msg = ('additional commit arguments may not be specified '
118 'with --commit')
119 raise OptionsError(msg)
120
121 self.parentCommit = self.__options.commit + '^'
122 self.childCommit = self.__options.commit
123 else:
124 # Default parent and child commits, if not otherwise specified
125 if self.__options.cached:
126 self.parentCommit = git.COMMIT_HEAD
127 self.childCommit = git.COMMIT_INDEX
128 else:
129 self.parentCommit = git.COMMIT_INDEX
130 self.childCommit = git.COMMIT_WD
131
132 # Parse the remaining arguments
133 num_args = len(args)
134 if num_args == 1:
135 self.parentCommit = args[0]
136 elif num_args == 2:
137 if self.__options.cached:
138 msg = 'cannot specify --cached with two commits'
139 raise OptionsError(msg)
140 self.parentCommit = args[0]
141 self.childCommit = args[1]
142 elif num_args > 2:
143 raise OptionsError('trailing arguments: ' + ' '.join(args[2:]))
144
145
146 def error_msg(msg):
147 sys.stderr.write('%s: error: %s\n' % (f_progname, msg))
148
149
150 def warning_msg(msg):
151 sys.stderr.write('%s: warning: %s\n' % (f_progname, msg))
152
153
154 def main(argv):
155 # Parse the command line options
156 options = Options()
157 try:
158 options.parseArgv(argv)
159 except OptionsError, error:
160 options.printUsage(sys.stderr)
161 error_msg(error)
162 return RETCODE_ARGUMENTS_ERROR
163 except UsageError, error:
164 options.printHelp()
165 return RETCODE_SUCCESS
166
167 # Get a Repository object
168 repo = git.get_repo(git_dir=options.gitDir,
169 working_dir=options.workTree)
170
171 diff = repo.getDiff(options.parentCommit, options.childCommit)
172 rev = review.Review(repo, diff)
173
174 return review.CliReviewer(rev).run()
175
176
177 if __name__ == '__main__':
178 sys.exit(main(sys.argv))
Something went wrong with that request. Please try again.