def run_commit_msg_hook(repo, cd, editor_is_used=True): """Run the commit-msg hook (if any) on a commit. @param cd: The L{CommitData<stgit.lib.git.CommitData>} to run the hook on. Return the new L{CommitData<stgit.lib.git.CommitData>}.""" env = dict(cd.env) if not editor_is_used: env['GIT_EDITOR'] = ':' commit_msg_hook = get_hook(repo, 'commit-msg', env) try: new_msg = run_hook_on_string(commit_msg_hook, cd.message) except RunException as exc: raise EditorException(str(exc)) return cd.set_message(new_msg)
def run_commit_msg_hook(repo, cd, editor_is_used=True): """Run the commit-msg hook (if any) on a commit. :param cd: The :class:`stgit.lib.git.CommitData` to run the hook on. :returns: the new :class:`stgit.lib.git.CommitData` """ env = dict(cd.env) if not editor_is_used: env['GIT_EDITOR'] = ':' commit_msg_hook = get_hook(repo, 'commit-msg', env) if commit_msg_hook: try: new_msg = run_hook_on_bytes(commit_msg_hook, cd.message) except RunException as exc: raise EditorException(str(exc)) return cd.set_message(new_msg) else: return cd
def func(parser, options, args): """Generate a new commit for the current or given patch.""" # Catch illegal argument combinations. path_limiting = bool(args or options.update) if options.index and path_limiting: raise CmdException( 'Only full refresh is available with the --index option') if options.index and options.force: raise CmdException( 'You cannot --force a full refresh when using --index mode') if options.update and options.submodules: raise CmdException( '--submodules is meaningless when only updating modified files') if options.index and options.submodules: raise CmdException( '--submodules is meaningless when keeping the current index') # If submodules was not specified on the command line, infer a default # from configuration. if options.submodules is None: options.submodules = config.getbool('stgit.refreshsubmodules') stack = directory.repository.current_stack patch_name = get_patch(stack, options.patch) paths = list_files( stack, patch_name, args, options.index, options.update, options.submodules, ) # Make sure there are no conflicts in the files we want to # refresh. if stack.repository.default_index.conflicts() & paths: raise CmdException('Cannot refresh -- resolve conflicts first') # Make sure the index is clean before performing a full refresh if not options.index and not options.force: if not (stack.repository.default_index.is_clean(stack.head) or stack.repository.default_iw.worktree_clean()): raise CmdException('The index is dirty. Did you mean --index? ' 'To force a full refresh use --force.') # Update index and write tree tree = write_tree(stack, paths, temp_index=path_limiting) # Run pre-commit hook, if fails, abort refresh if not options.no_verify: pre_commit_hook = get_hook( stack.repository, 'pre-commit', extra_env={} if options.edit else {'GIT_EDITOR': ':'}, ) if pre_commit_hook: try: pre_commit_hook() except RunException: raise CmdException( 'pre-commit hook failed, review the changes using `stg diff`, ' 'run `stg add` to add them to index and run `stg refresh` again' ) else: # Update index and rewrite tree if hook updated files in index if not stack.repository.default_index.is_clean(tree): tree = write_tree(stack, paths, temp_index=path_limiting) # Commit tree to temp patch, and absorb it into the target patch. retval, temp_name = make_temp_patch(stack, patch_name, tree) if retval != utils.STGIT_SUCCESS: return retval def edit_fun(cd): orig_msg = cd.message cd = auto_edit_patch( stack.repository, cd, msg=(None if options.message is None else options.message.encode( config.get('i18n.commitencoding'))), author=options.author, sign_str=options.sign_str, ) if options.edit: cd, failed_diff = interactive_edit_patch(stack.repository, cd, edit_diff=False, diff_flags=[]) assert not failed_diff if not options.no_verify and (options.edit or cd.message != orig_msg): cd = run_commit_msg_hook(stack.repository, cd, options.edit) # Refresh the committer information return cd.set_committer(None) return absorb(stack, patch_name, temp_name, edit_fun, annotate=options.annotate)
def __refresh( args, force=False, target_patch=None, message=None, author=None, sign_str=None, annotate=None, use_temp_index=False, refresh_from_index=False, only_update_patchfiles=False, include_submodules=False, no_verify=False, invoke_editor=False, edit_diff=False, diff_flags=(), ): stack = directory.repository.current_stack patch_name = get_patch(stack, target_patch) if refresh_from_index: paths = set() else: paths = list_files( stack, patch_name, args, only_update_patchfiles, include_submodules, ) # Make sure there are no conflicts in the files we want to # refresh. if stack.repository.default_index.conflicts() & paths: raise CmdException('Cannot refresh -- resolve conflicts first') # Make sure the index is clean before performing a full refresh if not refresh_from_index and not force: if not (stack.repository.default_index.is_clean(stack.head) or stack.repository.default_iw.worktree_clean()): raise CmdException('The index is dirty. Did you mean --index? ' 'To force a full refresh use --force.') # Update index and write tree tree = write_tree(stack, paths, use_temp_index=use_temp_index) # Run pre-commit hook, if fails, abort refresh if not no_verify: pre_commit_hook = get_hook( stack.repository, 'pre-commit', extra_env={} if invoke_editor else {'GIT_EDITOR': ':'}, ) if pre_commit_hook: try: pre_commit_hook() except RunException: raise CmdException( 'pre-commit hook failed, review the changes using `stg diff`, ' 'run `stg add` to add them to index and run `stg refresh` again' ) else: # Update index and rewrite tree if hook updated files in index if not stack.repository.default_index.is_clean(tree): tree = write_tree(stack, paths, use_temp_index=use_temp_index) # Commit tree to temp patch, and absorb it into the target patch. retval, temp_name = make_temp_patch(stack, patch_name, tree) if retval != utils.STGIT_SUCCESS: return retval def edit_fun(cd): orig_msg = cd.message new_msg = None if message is not None: new_msg = message.encode(config.get('i18n.commitencoding')) cd = auto_edit_patch( stack.repository, cd, msg=new_msg, author=author, sign_str=sign_str, ) if invoke_editor: cd, failed_diff = interactive_edit_patch(stack.repository, cd, edit_diff, diff_flags) assert not failed_diff if not no_verify and (invoke_editor or cd.message != orig_msg): cd = run_commit_msg_hook(stack.repository, cd, invoke_editor) # Refresh the committer information return cd.set_committer(None) return absorb(stack, patch_name, temp_name, edit_fun, annotate=annotate)