chiark / gitweb /
6288acc22e1aaba72452db6bda7bfb9fefd1e5b2
[stgit] / stgit / commands / refresh.py
1
2 __copyright__ = """
3 Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
4
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.
8
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.
13
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
17 """
18
19 import sys, os
20 from optparse import OptionParser, make_option
21
22 from stgit.commands.common import *
23 from stgit.utils import *
24 from stgit.out import *
25 from stgit import stack, git
26 from stgit.config import config
27
28
29 help = 'generate a new commit for the current patch'
30 usage = """%prog [options] [<files or dirs>]
31
32 Include the latest tree changes in the current patch. This command
33 generates a new GIT commit object with the patch details, the previous
34 one no longer being visible. The '--force' option is useful
35 when a commit object was created with a different tool
36 but the changes need to be included in the current patch."""
37
38 directory = DirectoryHasRepository()
39 options = [make_option('-f', '--force',
40                        help = 'force the refresh even if HEAD and '\
41                        'top differ',
42                        action = 'store_true'),
43            make_option('--update',
44                        help = 'only update the current patch files',
45                        action = 'store_true'),
46            make_option('--undo',
47                        help = 'revert the commit generated by the last refresh',
48                        action = 'store_true'),
49            make_option('-a', '--annotate', metavar = 'NOTE',
50                        help = 'annotate the patch log entry'),
51            make_option('-p', '--patch',
52                        help = 'refresh (applied) PATCH instead of the top one')
53            ]
54
55 def func(parser, options, args):
56     """Generate a new commit for the current or given patch.
57     """
58     args = git.ls_files(args)
59     directory.cd_to_topdir()
60
61     autoresolved = config.get('stgit.autoresolved')
62     if autoresolved != 'yes':
63         check_conflicts()
64
65     if options.patch:
66         if args or options.update:
67             raise CmdException, \
68                   'Only full refresh is available with the --patch option'
69         patch = options.patch
70         if not crt_series.patch_applied(patch):
71             raise CmdException, 'Patches "%s" not applied' % patch
72     else:
73         patch = crt_series.get_current()
74         if not patch:
75             raise CmdException, 'No patches applied'
76
77     if not options.force:
78         check_head_top_equal(crt_series)
79
80     if options.undo:
81         out.start('Undoing the refresh of "%s"' % patch)
82         crt_series.undo_refresh()
83         out.done()
84         return
85
86     files = [path for (stat, path) in git.tree_status(files = args, verbose = True)]
87
88     if files or not crt_series.head_top_equal():
89         if options.patch:
90             applied = crt_series.get_applied()
91             between = applied[:applied.index(patch):-1]
92             pop_patches(crt_series, between, keep = True)
93         elif options.update:
94             rev1 = git_id(crt_series, '//bottom')
95             rev2 = git_id(crt_series, '//top')
96             patch_files = git.barefiles(rev1, rev2).split('\n')
97             files = [f for f in files if f in patch_files]
98             if not files:
99                 out.info('No modified files for updating patch "%s"' % patch)
100                 return
101
102         out.start('Refreshing patch "%s"' % patch)
103
104         if autoresolved == 'yes':
105             resolved_all()
106         crt_series.refresh_patch(files = files,
107                                  backup = True, notes = options.annotate)
108
109         if crt_series.empty_patch(patch):
110             out.done('empty patch')
111         else:
112             out.done()
113
114         if options.patch:
115             between.reverse()
116             push_patches(crt_series, between)
117     elif options.annotate:
118         # only annotate the top log entry as there is no need to
119         # refresh the patch and generate a full commit
120         crt_series.log_patch(crt_series.get_patch(patch), None,
121                              notes = options.annotate)
122     else:
123         out.info('Patch "%s" is already up to date' % patch)