3 Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 from optparse import make_option
21 from stgit import utils
22 from stgit.commands import common
23 from stgit.lib import git as gitlib, transaction
25 help = 'create a new patch and make it the topmost one'
26 usage = """%prog [options] [name]
28 Create a new, empty patch and make it the topmost one. If the
29 '--message' option is not passed, an editor is invoked with the
30 .git/patchdescr.tmpl, ~/.stgit/templates/patchdescr.tmpl or
31 /usr/share/stgit/templates/patchdescr.tmpl file used a as template,
32 together with generated lines. The local changes in the working tree
33 are not included in the patch; an "stg refresh" command is needed for
36 If no name is given for the new patch, one is generated from the first
37 line of the commit message."""
39 directory = common.DirectoryHasRepositoryLib()
40 options = [make_option('-m', '--message',
41 help = 'use MESSAGE as the patch description'),
42 make_option('-a', '--author', metavar = '"NAME <EMAIL>"',
43 help = 'use "NAME <EMAIL>" as the author details'),
44 make_option('--authname',
45 help = 'use AUTHNAME as the author name'),
46 make_option('--authemail',
47 help = 'use AUTHEMAIL as the author e-mail'),
48 make_option('--authdate',
49 help = 'use AUTHDATE as the author date'),
50 make_option('--commname',
51 help = 'use COMMNAME as the committer name'),
52 make_option('--commemail',
53 help = 'use COMMEMAIL as the committer e-mail')
54 ] + utils.make_sign_options()
56 def func(parser, options, args):
57 """Create a new patch."""
58 stack = directory.repository.current_stack
59 if stack.repository.default_index.conflicts():
60 raise common.CmdException(
61 'Cannot create a new patch -- resolve conflicts first')
63 # Choose a name for the new patch -- or None, which means make one
64 # up later when we've gotten hold of the commit message.
69 if stack.patches.exists(name):
70 raise common.CmdException('%s: patch already exists' % name)
72 parser.error('incorrect number of arguments')
74 head = directory.repository.refs.get(directory.repository.head)
75 cd = gitlib.Commitdata(tree = head.data.tree, parents = [head],
78 # Set patch commit message from commandline.
79 if options.message != None:
80 cd = cd.set_message(options.message)
82 # Specify author and committer data.
83 if options.author != None:
84 options.authname, options.authemail = common.name_email(options.author)
85 for p, f, val in [('author', 'name', options.authname),
86 ('author', 'email', options.authemail),
87 ('author', 'date', gitlib.Date.maybe(options.authdate)),
88 ('committer', 'name', options.commname),
89 ('committer', 'email', options.commemail)]:
91 cd = getattr(cd, 'set_' + p)(
92 getattr(getattr(cd, p), 'set_' + f)(val))
94 # Add Signed-off-by: or similar.
95 if options.sign_str != None:
96 cd = cd.set_message(utils.add_sign_line(
97 cd.message, options.sign_str, gitlib.Person.committer().name,
98 gitlib.Person.committer().email))
100 # Let user edit the commit message manually.
101 if not options.message:
102 cd = cd.set_message(utils.edit_string(cd.message, '.stgit-new.txt'))
104 name = utils.make_patch_name(cd.message,
105 lambda name: stack.patches.exists(name))
107 # Write the new patch.
108 iw = stack.repository.default_iw
109 trans = transaction.StackTransaction(stack, 'new')
110 trans.patches[name] = stack.repository.commit(cd)
111 trans.applied.append(name)