1 from stgit
import argparse
, utils
2 from stgit
.argparse
import opt
3 from stgit
.commands
.common
import (
5 DirectoryHasRepository
,
9 from stgit
.config
import config
10 from stgit
.lib
.edit
import auto_edit_patch
, interactive_edit_patch
11 from stgit
.lib
.git
import CommitData
, IndexAndWorktree
12 from stgit
.lib
.transaction
import (
17 from stgit
.out
import out
18 from stgit
.run
import RunException
19 from stgit
.utils
import get_hook
22 Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
23 Copyright (C) 2008, Karl Hasselström <kha@treskal.com>
25 This program is free software; you can redistribute it and/or modify
26 it under the terms of the GNU General Public License version 2 as
27 published by the Free Software Foundation.
29 This program is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 GNU General Public License for more details.
34 You should have received a copy of the GNU General Public License
35 along with this program; if not, see http://www.gnu.org/licenses/.
38 help = 'Generate a new commit for the current patch'
40 usage
= ['[options] [--] [<files or dirs>]']
42 Include the latest work tree and index changes in the current patch.
43 This command generates a new git commit object for the patch; the old
44 commit is no longer visible.
46 Refresh will warn if the index is dirty, and require use of either the
47 '--index' or '--force' options to override this check. This is to prevent
48 accidental full refresh when only some changes were staged using git add
51 You may optionally list one or more files or directories relative to
52 the current working directory; if you do, only matching files will be
55 Behind the scenes, stg refresh first creates a new temporary patch
56 with your updates, and then merges that patch into the patch you asked
57 to have refreshed. If you asked to refresh a patch other than the
58 topmost patch, there can be conflicts; in that case, the temporary
59 patch will be left for you to take care of, for example with stg
62 The creation of the temporary patch is recorded in a separate entry in
63 the patch stack log; this means that one undo step will undo the merge
64 between the other patch and the temp patch, and two undo steps will
65 additionally get rid of the temp patch.
67 Additionally, the '--spill' option resets the topmost patch, emptying
68 the patch while leaving the patch's changes intact in the worktree."""
70 args
= ['dirty_files']
76 short
='Only update the current patch files',
82 short
='Refresh from index instead of worktree',
84 Instead of setting the patch top to the current contents of
85 the worktree, set it to the current contents of the index.""",
91 short
='Force refresh even if index is dirty',
93 Instead of warning the user when some work has already been staged
94 (such as with git add interactive mode) force a full refresh.""",
99 args
=['other_applied_patches', 'unapplied_patches'],
100 short
='Refresh (applied) PATCH instead of the top patch',
106 short
='Invoke an editor for the patch description',
112 short
='Show diff when editing patch description',
118 short
='Annotate the patch log entry',
124 short
='Include submodules when refreshing patch contents',
128 action
='store_false',
130 short
='Exclude submodules when refreshing patch contents',
136 short
='Spill patch content to worktree and index, erasing patch content.',
139 options
.extend(argparse
.message_options(save_template
=False))
140 options
.extend(argparse
.hook_options())
141 options
.extend(argparse
.trailer_options())
142 options
.extend(argparse
.author_options())
143 options
.extend(argparse
.diff_opts_option())
145 directory
= DirectoryHasRepository()
148 def get_patch(stack
, given_patch
):
149 """Get the name of the patch we are to refresh."""
151 patch_name
= given_patch
152 if patch_name
not in stack
.patches
:
153 raise CmdException('%s: no such patch' % patch_name
)
156 if not stack
.patchorder
.applied
:
158 'Cannot refresh top patch because no patches are applied'
160 return stack
.patchorder
.applied
[-1]
163 def list_files(stack
, patch_name
, path_limits
, update
, submodules
):
164 """Figure out which files to update."""
165 iw
= stack
.repository
.default_iw
166 paths
= iw
.changed_files(stack
.head
.data
.tree
, path_limits
or [])
168 # --update: Restrict update to the paths that were already part of the patch.
170 commit
= stack
.patches
[patch_name
]
171 for dt
in stack
.repository
.diff_tree_files(
172 commit
.data
.parent
.data
.tree
, commit
.data
.tree
174 _
, _
, _
, _
, _
, oldname
, newname
= dt
175 patch_paths
.add(oldname
)
176 patch_paths
.add(newname
)
179 # Avoid including submodule files by default. This is to ensure that
180 # users in repositories with submodueles do not accidentally include
181 # submodule changes to patches just because they happen to have not
182 # run "git submodule update" prior to running stg refresh. We won't
183 # exclude them if we're explicitly told to include them, or if we're
184 # given explicit paths.
185 if not path_limits
and not submodules
:
186 paths
-= stack
.repository
.submodules(stack
.head
.data
.tree
)
190 def write_tree(stack
, paths
, use_temp_index
):
191 """Possibly update the index, and then write its tree.
193 If any path limiting is in effect, use a temp index.
195 :return: The written tree.
196 :rtype: :class:`Tree<stgit.git.Tree>`
200 with stack
.repository
.temp_index() as index
:
201 iw
= IndexAndWorktree(index
, stack
.repository
.default_worktree
)
203 index
.read_tree(stack
.head
)
205 iw
.update_index(paths
)
206 return index
.write_tree()
208 stack
.repository
.default_iw
.update_index(paths
)
210 iw
= stack
.repository
.default_iw
212 iw
.update_index(paths
)
213 return iw
.index
.write_tree()
216 def make_temp_patch(stack
, patch_name
, tree
):
217 """Commit tree to temp patch, in a complete transaction."""
218 commit
= stack
.repository
.commit(
221 parents
=[stack
.head
],
222 message
='Refresh of %s' % patch_name
,
225 temp_name
= stack
.patches
.make_name('refresh-temp')
226 trans
= StackTransaction(stack
)
227 trans
.patches
[temp_name
] = commit
228 trans
.applied
.append(temp_name
)
231 'refresh (create temporary patch)',
232 stack
.repository
.default_iw
,
233 print_current_patch
=False,
239 def absorb_applied(trans
, iw
, patch_name
, temp_name
, edit_fun
):
240 """Absorb temp patch into the given patch, which must be applied.
242 If the absorption succeeds, call ``edit_fun`` on the resulting
243 :class:`stgit.lib.git.CommitData` before committing it, then commit the return
246 :returns: True if the temp patch is successfully absorbed or False if there remain
247 conflicts for the user to resolve
250 temp_absorbed
= False
252 # Pop any patch on top of the patch we're refreshing.
253 to_pop
= trans
.applied
[trans
.applied
.index(patch_name
) + 1 :]
255 popped_extra
= trans
.pop_patches(lambda pn
: pn
in to_pop
)
256 assert not popped_extra
# no other patches were popped
257 trans
.push_patch(temp_name
, iw
)
258 top_name
= to_pop
.pop()
259 assert top_name
== temp_name
261 # Absorb the temp patch.
262 temp_cd
= trans
.patches
[temp_name
].data
263 assert trans
.patches
[patch_name
] == temp_cd
.parent
264 cd
, new_patch_name
= edit_fun(
265 trans
.patches
[patch_name
].data
.set_tree(temp_cd
.tree
)
267 trans
.patches
[patch_name
] = trans
.stack
.repository
.commit(cd
)
268 if new_patch_name
and patch_name
!= new_patch_name
:
269 trans
.rename_patch(patch_name
, new_patch_name
)
271 popped_extra
= trans
.delete_patches(lambda pn
: pn
== temp_name
, quiet
=True)
272 assert not popped_extra
# the temp patch was topmost
275 # Push back any patch we were forced to pop earlier.
277 trans
.push_patch(pn
, iw
)
278 except TransactionHalted
:
283 def absorb_unapplied(trans
, iw
, patch_name
, temp_name
, edit_fun
):
284 """Absorb the temp patch into the given patch, which must be unapplied.
286 If the absorption succeeds, call ``edit_fun`` on the resulting
287 :class:`stgit.lib.git.CommitData` before committing it, then commit the return
291 :returns: True if the temp patch is absorbed successfully or False
292 if user resolvable conflicts remain
295 # Pop the temp patch.
296 popped_extra
= trans
.pop_patches(lambda pn
: pn
== temp_name
)
297 assert not popped_extra
# the temp patch was topmost
299 # Try to create the new tree of the refreshed patch. (This is the
300 # same operation as pushing the temp patch onto the patch we're
301 # trying to refresh -- but we don't have a worktree to spill
302 # conflicts to, so if the simple merge doesn't succeed, we have to
304 patch_cd
= trans
.patches
[patch_name
].data
305 temp_cd
= trans
.patches
[temp_name
].data
306 new_tree
= trans
.stack
.repository
.simple_merge(
307 base
=temp_cd
.parent
.data
.tree
,
312 # It worked. Refresh the patch with the new tree, and delete
314 cd
, new_patch_name
= edit_fun(patch_cd
.set_tree(new_tree
))
315 trans
.patches
[patch_name
] = trans
.stack
.repository
.commit(cd
)
316 if new_patch_name
and patch_name
!= new_patch_name
:
317 trans
.rename_patch(patch_name
, new_patch_name
)
318 popped_extra
= trans
.delete_patches(lambda pn
: pn
== temp_name
, quiet
=True)
319 assert not popped_extra
# the temp patch was not applied
322 # Nope, we couldn't create the new tree, so we'll just have to
323 # leave the temp patch for the user.
327 def absorb(stack
, patch_name
, temp_name
, edit_fun
, annotate
=None):
328 """Absorb the temp patch into the target patch."""
331 log_msg
+= '\n\n' + annotate
333 check_head_top_equal(stack
)
334 trans
= StackTransaction(stack
)
335 iw
= stack
.repository
.default_iw
336 if patch_name
in trans
.applied
:
337 absorbed
= absorb_applied(trans
, iw
, patch_name
, temp_name
, edit_fun
)
339 absorbed
= absorb_unapplied(trans
, iw
, patch_name
, temp_name
, edit_fun
)
341 r
= trans
.execute(log_msg
, iw
)
345 'The new changes did not apply cleanly to %s.' % patch_name
,
346 'They were saved in %s.' % temp_name
,
352 def __refresh_spill(annotate
):
353 stack
= directory
.repository
.current_stack
355 # Fetch the topmost patch.
356 patchname
= get_patch(stack
, None)
358 cd
= stack
.patches
[patchname
].data
360 # Set the tree of the patch to the parent.
361 cd
= cd
.set_tree(cd
.parent
.data
.tree
)
363 log_msg
= 'refresh (spill)'
365 log_msg
+= '\n\n' + annotate
367 check_head_top_equal(stack
)
368 trans
= StackTransaction(stack
, allow_conflicts
=True)
369 trans
.patches
[patchname
] = stack
.repository
.commit(cd
)
371 # Either a complete success, or a conflict during push. But in
372 # either case, we've successfully effected the edits the user
374 return trans
.execute(log_msg
)
375 except TransactionException
:
376 # Transaction aborted -- we couldn't check out files due to
377 # dirty index/worktree. The edits were not carried out.
378 out
.error('Unable to spill the topmost patch')
379 return utils
.STGIT_COMMAND_ERROR
390 use_temp_index
=False,
391 refresh_from_index
=False,
392 only_update_patchfiles
=False,
393 include_submodules
=False,
399 stack
= directory
.repository
.current_stack
401 patch_name
= get_patch(stack
, target_patch
)
403 if refresh_from_index
:
410 only_update_patchfiles
,
414 # Make sure there are no conflicts in the files we want to
416 if stack
.repository
.default_index
.conflicts() & paths
:
417 raise CmdException('Cannot refresh -- resolve conflicts first')
419 # Make sure the index is clean before performing a full refresh
420 if not refresh_from_index
and not force
:
422 stack
.repository
.default_index
.is_clean(stack
.head
)
423 or stack
.repository
.default_iw
.worktree_clean()
426 'The index is dirty. Did you mean --index? '
427 'To force a full refresh use --force.'
430 check_head_top_equal(stack
)
432 # Update index and write tree
433 tree
= write_tree(stack
, paths
, use_temp_index
=use_temp_index
)
435 # Run pre-commit hook, if fails, abort refresh
437 pre_commit_hook
= get_hook(
440 extra_env
={} if invoke_editor
else {'GIT_EDITOR': ':'},
447 'pre-commit hook failed, review the changes using `stg diff`, '
448 'run `stg add` to add them to index and run `stg refresh` again'
451 # Update index and rewrite tree if hook updated files in index
452 if not stack
.repository
.default_index
.is_clean(tree
):
453 tree
= write_tree(stack
, paths
, use_temp_index
=use_temp_index
)
455 # Commit tree to temp patch, and absorb it into the target patch.
456 retval
, temp_name
= make_temp_patch(stack
, patch_name
, tree
)
458 if retval
!= utils
.STGIT_SUCCESS
:
462 orig_msg
= cd
.message
464 if message
is not None:
465 new_msg
= message
.encode(config
.get('i18n.commitencoding'))
466 cd
= auto_edit_patch(
473 new_patch_name
= None
475 cd
, new_patch_name
, failed_diff
= interactive_edit_patch(
476 stack
.repository
, cd
, patch_name
, edit_diff
, diff_flags
478 assert not failed_diff
479 if not no_verify
and (invoke_editor
or cd
.message
!= orig_msg
):
480 cd
= run_commit_msg_hook(stack
.repository
, cd
, invoke_editor
)
481 # Refresh the committer information
482 return cd
.set_committer(None), new_patch_name
484 return absorb(stack
, patch_name
, temp_name
, edit_fun
, annotate
=annotate
)
487 def func(parser
, options
, args
):
488 """Generate a new commit for the current or given patch."""
492 # TODO: would be nice if path limiting could be used with spill.
493 raise CmdException('Cannot use path limiting with --spill')
494 for opt_name
, opt_value
in [
495 ('--index', options
.index
),
496 ('--edit', options
.edit
),
497 ('--update', options
.update
),
498 ('--patch', options
.patch
),
499 ('--force', options
.force
),
500 ('--no-verify', options
.no_verify
),
501 ('--sign', options
.trailers
),
502 ('--ack', options
.trailers
),
503 ('--review', options
.trailers
),
506 raise CmdException('Cannot combine --spill with %s' % opt_name
)
507 return __refresh_spill(annotate
=options
.annotate
)
509 # Catch illegal argument combinations.
510 is_path_limiting
= bool(args
or options
.update
)
511 if options
.index
and is_path_limiting
:
512 raise CmdException('Only full refresh is available with the --index option')
514 if options
.index
and options
.force
:
516 'You cannot --force a full refresh when using --index mode'
519 if options
.update
and options
.submodules
:
521 '--submodules is meaningless when only updating modified files'
524 if options
.index
and options
.submodules
:
526 '--submodules is meaningless when keeping the current index'
529 # If submodules was not specified on the command line, infer a default
530 # from configuration.
531 if options
.submodules
is None:
532 options
.submodules
= config
.getbool('stgit.refreshsubmodules')
537 target_patch
=options
.patch
,
538 message
=options
.message
,
539 author
=options
.author
,
540 trailers
=options
.trailers
,
541 annotate
=options
.annotate
,
542 use_temp_index
=is_path_limiting
,
543 refresh_from_index
=options
.index
,
544 only_update_patchfiles
=options
.update
,
545 include_submodules
=options
.submodules
,
546 no_verify
=options
.no_verify
,
547 invoke_editor
=options
.edit
,
548 edit_diff
=options
.diff
,
549 diff_flags
=options
.diff_flags
,