git_run_options: reduce differences with svn_run_options.
[cvs2svn.git] / cvs2svn_lib / git_run_options.py
blobc4e3c0a6c2ad1157cbc52dfabb7524c947c03072
1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2000-2009 CollabNet. All rights reserved.
6 # This software is licensed as described in the file COPYING, which
7 # you should have received as part of this distribution. The terms
8 # are also available at http://subversion.tigris.org/license-1.html.
9 # If newer versions of this license are posted there, you may use a
10 # newer version instead, at your option.
12 # This software consists of voluntary contributions made by many
13 # individuals. For exact contribution history, see the revision
14 # history and logs, available at http://cvs2svn.tigris.org/.
15 # ====================================================================
17 """This module manages cvs2git run options."""
20 import sys
21 import datetime
22 import codecs
24 from cvs2svn_lib.version import VERSION
25 from cvs2svn_lib.common import error_prefix
26 from cvs2svn_lib.common import FatalError
27 from cvs2svn_lib.log import Log
28 from cvs2svn_lib.context import Ctx
29 from cvs2svn_lib.run_options import not_both
30 from cvs2svn_lib.run_options import RunOptions
31 from cvs2svn_lib.run_options import ContextOption
32 from cvs2svn_lib.run_options import IncompatibleOption
33 from cvs2svn_lib.run_options import authors
34 from cvs2svn_lib.man_writer import ManWriter
35 from cvs2svn_lib.project import Project
36 from cvs2svn_lib.rcs_revision_manager import RCSRevisionReader
37 from cvs2svn_lib.cvs_revision_manager import CVSRevisionReader
38 from cvs2svn_lib.git_revision_recorder import GitRevisionRecorder
39 from cvs2svn_lib.git_output_option import GitRevisionMarkWriter
40 from cvs2svn_lib.git_output_option import GitOutputOption
41 from cvs2svn_lib.revision_manager import NullRevisionRecorder
42 from cvs2svn_lib.revision_manager import NullRevisionExcluder
43 from cvs2svn_lib.fulltext_revision_recorder \
44 import SimpleFulltextRevisionRecorderAdapter
47 short_desc = 'convert a cvs repository into a git repository'
49 synopsis = """\
50 .B cvs2git
51 [\\fIOPTION\\fR]... \\fIOUTPUT-OPTIONS CVS-REPOS-PATH\\fR
52 .br
53 .B cvs2git
54 [\\fIOPTION\\fR]... \\fI--options=PATH\\fR
55 """
57 long_desc = """\
58 Create a new git repository based on the version history stored in a
59 CVS repository. Each CVS commit will be mirrored in the git
60 repository, including such information as date of commit and id of the
61 committer.
63 The output of this program are a "blobfile" and a "dumpfile", which
64 together can be loaded into a git repository using "git fast-import".
66 \\fICVS-REPOS-PATH\\fR is the filesystem path of the part of the CVS
67 repository that you want to convert. This path doesn't have to be the
68 top level directory of a CVS repository; it can point at a project
69 within a repository, in which case only that project will be
70 converted. This path or one of its parent directories has to contain
71 a subdirectory called CVSROOT (though the CVSROOT directory can be
72 empty).
74 It is not possible directly to convert a CVS repository to which you
75 only have remote access, but the FAQ describes tools that may be used
76 to create a local copy of a remote CVS repository.
77 """
79 files = """\
80 A directory called \\fIcvs2svn-tmp\\fR (or the directory specified by
81 \\fB--tmpdir\\fR) is used as scratch space for temporary data files.
82 """
84 see_also = [
85 ('cvs', '1'),
86 ('git', '1'),
87 ('git-fast-import', '1'),
91 class GitRunOptions(RunOptions):
92 def __init__(self, progname, cmd_args, pass_manager):
93 Ctx().cross_project_commits = False
94 Ctx().cross_branch_commits = False
95 RunOptions.__init__(self, progname, cmd_args, pass_manager)
97 def _get_output_options_group(self):
98 group = RunOptions._get_output_options_group(self)
100 group.add_option(IncompatibleOption(
101 '--blobfile', type='string',
102 action='store',
103 help='path to which the "blob" data should be written',
104 man_help=(
105 'Write the "blob" data (containing revision contents) to '
106 '\\fIpath\\fR.'
108 metavar='PATH',
110 group.add_option(IncompatibleOption(
111 '--dumpfile', type='string',
112 action='store',
113 help='path to which the revision data should be written',
114 man_help=(
115 'Write the revision data (branches and commits) to \\fIpath\\fR.'
117 metavar='PATH',
119 group.add_option(ContextOption(
120 '--dry-run',
121 action='store_true',
122 help=(
123 'do not create any output; just print what would happen.'
125 man_help=(
126 'Do not create any output; just print what would happen.'
130 return group
132 def _get_extraction_options_group(self):
133 group = RunOptions._get_extraction_options_group(self)
135 self.parser.set_default('use_cvs', False)
136 group.add_option(IncompatibleOption(
137 '--use-cvs',
138 action='store_true',
139 help=(
140 'use CVS to extract revision contents (slower than '
141 '--use-rcs but more reliable) (default)'
143 man_help=(
144 'Use CVS to extract revision contents. This option is slower '
145 'than \\fB--use-rcs\\fR but more reliable.'
148 self.parser.set_default('use_rcs', False)
149 group.add_option(IncompatibleOption(
150 '--use-rcs',
151 action='store_true',
152 help=(
153 'use RCS to extract revision contents (faster than '
154 '--use-cvs but fails in some cases)'
156 man_help=(
157 'Use RCS \'co\' to extract revision contents. This option is '
158 'faster than \\fB--use-cvs\\fR but fails in some cases.'
162 return group
164 def callback_manpage(self, option, opt_str, value, parser):
165 f = codecs.getwriter('utf_8')(sys.stdout)
166 ManWriter(
167 parser,
168 section='1',
169 date=datetime.date.today(),
170 source='Version %s' % (VERSION,),
171 manual='User Commands',
172 short_desc=short_desc,
173 synopsis=synopsis,
174 long_desc=long_desc,
175 files=files,
176 authors=authors,
177 see_also=see_also,
178 ).write_manpage(f)
179 sys.exit(0)
181 def process_extraction_options(self):
182 """Process options related to extracting data from the CVS
183 repository."""
184 ctx = Ctx()
185 options = self.options
187 not_both(options.use_rcs, '--use-rcs',
188 options.use_cvs, '--use-cvs')
190 if options.use_rcs:
191 revision_reader = RCSRevisionReader(
192 co_executable=options.co_executable
194 else:
195 # --use-cvs is the default:
196 revision_reader = CVSRevisionReader(
197 cvs_executable=options.cvs_executable
200 if ctx.dry_run:
201 ctx.revision_recorder = NullRevisionRecorder()
202 else:
203 if not (options.blobfile and options.dumpfile):
204 raise FatalError("must pass '--blobfile' and '--dumpfile' options.")
205 ctx.revision_recorder = SimpleFulltextRevisionRecorderAdapter(
206 revision_reader,
207 GitRevisionRecorder(options.blobfile),
210 ctx.revision_excluder = NullRevisionExcluder()
211 ctx.revision_reader = None
213 def process_output_options(self):
214 """Process options related to fastimport output."""
215 ctx = Ctx()
216 ctx.output_option = GitOutputOption(
217 self.options.dumpfile,
218 GitRevisionMarkWriter(),
219 max_merges=None,
220 # Optional map from CVS author names to git author names:
221 author_transforms={}, # FIXME
224 def set_project(
225 self,
226 project_cvs_repos_path,
227 symbol_transforms=None,
228 symbol_strategy_rules=[],
230 """Set the project to be converted.
232 If a project had already been set, overwrite it.
234 Most arguments are passed straight through to the Project
235 constructor. SYMBOL_STRATEGY_RULES is an iterable of
236 SymbolStrategyRules that will be applied to symbols in this
237 project."""
239 symbol_strategy_rules = list(symbol_strategy_rules)
241 project = Project(
243 project_cvs_repos_path,
244 symbol_transforms=symbol_transforms,
247 self.projects = [project]
248 self.project_symbol_strategy_rules = [symbol_strategy_rules]
250 def process_options(self):
251 # Consistency check for options and arguments.
252 if len(self.args) == 0:
253 self.usage()
254 sys.exit(1)
256 if len(self.args) > 1:
257 Log().error(error_prefix + ": must pass only one CVS repository.\n")
258 self.usage()
259 sys.exit(1)
261 cvsroot = self.args[0]
263 self.process_extraction_options()
264 self.process_output_options()
265 self.process_symbol_strategy_options()
266 self.process_property_setter_options()
268 # Create the project:
269 self.set_project(
270 cvsroot,
271 symbol_transforms=self.options.symbol_transforms,
272 symbol_strategy_rules=self.options.symbol_strategy_rules,