mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 08:14:42 +04:00
Merge pull request #1339 from andrewhare/andrewhare/post-checkout
Add post-checkout
This commit is contained in:
commit
566f1afcd4
9 changed files with 77 additions and 5 deletions
|
|
@ -74,6 +74,7 @@ def _ns(
|
||||||
remote_name: Optional[str] = None,
|
remote_name: Optional[str] = None,
|
||||||
remote_url: Optional[str] = None,
|
remote_url: Optional[str] = None,
|
||||||
commit_msg_filename: Optional[str] = None,
|
commit_msg_filename: Optional[str] = None,
|
||||||
|
checkout_type: Optional[str] = None,
|
||||||
) -> argparse.Namespace:
|
) -> argparse.Namespace:
|
||||||
return argparse.Namespace(
|
return argparse.Namespace(
|
||||||
color=color,
|
color=color,
|
||||||
|
|
@ -84,6 +85,7 @@ def _ns(
|
||||||
remote_url=remote_url,
|
remote_url=remote_url,
|
||||||
commit_msg_filename=commit_msg_filename,
|
commit_msg_filename=commit_msg_filename,
|
||||||
all_files=all_files,
|
all_files=all_files,
|
||||||
|
checkout_type=checkout_type,
|
||||||
files=(),
|
files=(),
|
||||||
hook=None,
|
hook=None,
|
||||||
verbose=False,
|
verbose=False,
|
||||||
|
|
@ -157,6 +159,11 @@ def _run_ns(
|
||||||
return _ns(hook_type, color, commit_msg_filename=args[0])
|
return _ns(hook_type, color, commit_msg_filename=args[0])
|
||||||
elif hook_type in {'pre-merge-commit', 'pre-commit'}:
|
elif hook_type in {'pre-merge-commit', 'pre-commit'}:
|
||||||
return _ns(hook_type, color)
|
return _ns(hook_type, color)
|
||||||
|
elif hook_type == 'post-checkout':
|
||||||
|
return _ns(
|
||||||
|
hook_type, color, source=args[0], origin=args[1],
|
||||||
|
checkout_type=args[2],
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise AssertionError(f'unexpected hook type: {hook_type}')
|
raise AssertionError(f'unexpected hook type: {hook_type}')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -325,6 +325,9 @@ def run(
|
||||||
environ['PRE_COMMIT_REMOTE_NAME'] = args.remote_name
|
environ['PRE_COMMIT_REMOTE_NAME'] = args.remote_name
|
||||||
environ['PRE_COMMIT_REMOTE_URL'] = args.remote_url
|
environ['PRE_COMMIT_REMOTE_URL'] = args.remote_url
|
||||||
|
|
||||||
|
if args.checkout_type:
|
||||||
|
environ['PRE_COMMIT_CHECKOUT_TYPE'] = args.checkout_type
|
||||||
|
|
||||||
with contextlib.ExitStack() as exit_stack:
|
with contextlib.ExitStack() as exit_stack:
|
||||||
if stash:
|
if stash:
|
||||||
exit_stack.enter_context(staged_files_only(store.directory))
|
exit_stack.enter_context(staged_files_only(store.directory))
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ VERSION = importlib_metadata.version('pre_commit')
|
||||||
# `manual` is not invoked by any installed git hook. See #719
|
# `manual` is not invoked by any installed git hook. See #719
|
||||||
STAGES = (
|
STAGES = (
|
||||||
'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg', 'manual',
|
'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg', 'manual',
|
||||||
'push',
|
'post-checkout', 'push',
|
||||||
)
|
)
|
||||||
|
|
||||||
DEFAULT = 'default'
|
DEFAULT = 'default'
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ def _add_hook_type_option(parser: argparse.ArgumentParser) -> None:
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--hook-type', choices=(
|
'-t', '--hook-type', choices=(
|
||||||
'pre-commit', 'pre-merge-commit', 'pre-push',
|
'pre-commit', 'pre-merge-commit', 'pre-push',
|
||||||
'prepare-commit-msg', 'commit-msg',
|
'prepare-commit-msg', 'commit-msg', 'post-checkout',
|
||||||
),
|
),
|
||||||
action=AppendReplaceDefault,
|
action=AppendReplaceDefault,
|
||||||
default=['pre-commit'],
|
default=['pre-commit'],
|
||||||
|
|
@ -92,11 +92,17 @@ def _add_run_options(parser: argparse.ArgumentParser) -> None:
|
||||||
parser.add_argument('--verbose', '-v', action='store_true', default=False)
|
parser.add_argument('--verbose', '-v', action='store_true', default=False)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--origin', '-o',
|
'--origin', '-o',
|
||||||
help="The origin branch's commit_id when using `git push`.",
|
help=(
|
||||||
|
"The origin branch's commit_id when using `git push`. "
|
||||||
|
'The ref of the previous HEAD when using `git checkout`.'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--source', '-s',
|
'--source', '-s',
|
||||||
help="The remote branch's commit_id when using `git push`.",
|
help=(
|
||||||
|
"The remote branch's commit_id when using `git push`. "
|
||||||
|
'The ref of the new HEAD when using `git checkout`.'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--commit-msg-filename',
|
'--commit-msg-filename',
|
||||||
|
|
@ -123,6 +129,14 @@ def _add_run_options(parser: argparse.ArgumentParser) -> None:
|
||||||
'--files', nargs='*', default=[],
|
'--files', nargs='*', default=[],
|
||||||
help='Specific filenames to run hooks on.',
|
help='Specific filenames to run hooks on.',
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--checkout-type',
|
||||||
|
help=(
|
||||||
|
'Indicates whether the checkout was a branch checkout '
|
||||||
|
'(changing branches, flag=1) or a file checkout (retrieving a '
|
||||||
|
'file from the index, flag=0).'
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _adjust_args_and_chdir(args: argparse.Namespace) -> None:
|
def _adjust_args_and_chdir(args: argparse.Namespace) -> None:
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ def run_opts(
|
||||||
hook_stage='commit',
|
hook_stage='commit',
|
||||||
show_diff_on_failure=False,
|
show_diff_on_failure=False,
|
||||||
commit_msg_filename='',
|
commit_msg_filename='',
|
||||||
|
checkout_type='',
|
||||||
):
|
):
|
||||||
# These are mutually exclusive
|
# These are mutually exclusive
|
||||||
assert not (all_files and files)
|
assert not (all_files and files)
|
||||||
|
|
@ -88,6 +89,7 @@ def run_opts(
|
||||||
hook_stage=hook_stage,
|
hook_stage=hook_stage,
|
||||||
show_diff_on_failure=show_diff_on_failure,
|
show_diff_on_failure=show_diff_on_failure,
|
||||||
commit_msg_filename=commit_msg_filename,
|
commit_msg_filename=commit_msg_filename,
|
||||||
|
checkout_type=checkout_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,16 @@ def test_run_ns_commit_msg():
|
||||||
assert ns.commit_msg_filename == '.git/COMMIT_MSG'
|
assert ns.commit_msg_filename == '.git/COMMIT_MSG'
|
||||||
|
|
||||||
|
|
||||||
|
def test_run_ns_post_checkout():
|
||||||
|
ns = hook_impl._run_ns('post-checkout', True, ('a', 'b', 'c'), b'')
|
||||||
|
assert ns is not None
|
||||||
|
assert ns.hook_stage == 'post-checkout'
|
||||||
|
assert ns.color is True
|
||||||
|
assert ns.source == 'a'
|
||||||
|
assert ns.origin == 'b'
|
||||||
|
assert ns.checkout_type == 'c'
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def push_example(tempdir_factory):
|
def push_example(tempdir_factory):
|
||||||
src = git_dir(tempdir_factory)
|
src = git_dir(tempdir_factory)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ from testing.fixtures import add_config_to_repo
|
||||||
from testing.fixtures import git_dir
|
from testing.fixtures import git_dir
|
||||||
from testing.fixtures import make_consuming_repo
|
from testing.fixtures import make_consuming_repo
|
||||||
from testing.fixtures import remove_config_from_repo
|
from testing.fixtures import remove_config_from_repo
|
||||||
|
from testing.fixtures import write_config
|
||||||
from testing.util import cmd_output_mocked_pre_commit_home
|
from testing.util import cmd_output_mocked_pre_commit_home
|
||||||
from testing.util import cwd
|
from testing.util import cwd
|
||||||
from testing.util import git_commit
|
from testing.util import git_commit
|
||||||
|
|
@ -725,6 +726,31 @@ def test_commit_msg_legacy(commit_msg_repo, tempdir_factory, store):
|
||||||
assert second_line.startswith('Must have "Signed off by:"...')
|
assert second_line.startswith('Must have "Signed off by:"...')
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_checkout_integration(tempdir_factory, store):
|
||||||
|
path = git_dir(tempdir_factory)
|
||||||
|
config = {
|
||||||
|
'repo': 'local',
|
||||||
|
'hooks': [{
|
||||||
|
'id': 'post-checkout',
|
||||||
|
'name': 'Post checkout',
|
||||||
|
'entry': 'bash -c "echo ${PRE_COMMIT_ORIGIN}"',
|
||||||
|
'language': 'system',
|
||||||
|
'always_run': True,
|
||||||
|
'verbose': True,
|
||||||
|
'stages': ['post-checkout'],
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
write_config(path, config)
|
||||||
|
with cwd(path):
|
||||||
|
cmd_output('git', 'add', '.')
|
||||||
|
git_commit()
|
||||||
|
install(C.CONFIG_FILE, store, hook_types=['post-checkout'])
|
||||||
|
retc, _, stderr = cmd_output('git', 'checkout', '-b', 'feature')
|
||||||
|
assert retc == 0
|
||||||
|
_, head, _ = cmd_output('git', 'rev-parse', 'HEAD')
|
||||||
|
assert head in str(stderr)
|
||||||
|
|
||||||
|
|
||||||
def test_prepare_commit_msg_integration_failing(
|
def test_prepare_commit_msg_integration_failing(
|
||||||
failing_prepare_commit_msg_repo, tempdir_factory, store,
|
failing_prepare_commit_msg_repo, tempdir_factory, store,
|
||||||
):
|
):
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ from pre_commit.commands.run import Classifier
|
||||||
from pre_commit.commands.run import filter_by_include_exclude
|
from pre_commit.commands.run import filter_by_include_exclude
|
||||||
from pre_commit.commands.run import run
|
from pre_commit.commands.run import run
|
||||||
from pre_commit.util import cmd_output
|
from pre_commit.util import cmd_output
|
||||||
|
from pre_commit.util import EnvironT
|
||||||
from pre_commit.util import make_executable
|
from pre_commit.util import make_executable
|
||||||
from testing.auto_namedtuple import auto_namedtuple
|
from testing.auto_namedtuple import auto_namedtuple
|
||||||
from testing.fixtures import add_config_to_repo
|
from testing.fixtures import add_config_to_repo
|
||||||
|
|
@ -466,6 +467,15 @@ def test_all_push_options_ok(cap_out, store, repo_with_passing_hook):
|
||||||
assert b'Specify both --origin and --source.' not in printed
|
assert b'Specify both --origin and --source.' not in printed
|
||||||
|
|
||||||
|
|
||||||
|
def test_checkout_type(cap_out, store, repo_with_passing_hook):
|
||||||
|
args = run_opts(origin='', source='', checkout_type='1')
|
||||||
|
environ: EnvironT = {}
|
||||||
|
ret, printed = _do_run(
|
||||||
|
cap_out, store, repo_with_passing_hook, args, environ,
|
||||||
|
)
|
||||||
|
assert environ['PRE_COMMIT_CHECKOUT_TYPE'] == '1'
|
||||||
|
|
||||||
|
|
||||||
def test_has_unmerged_paths(in_merge_conflict):
|
def test_has_unmerged_paths(in_merge_conflict):
|
||||||
assert _has_unmerged_paths() is True
|
assert _has_unmerged_paths() is True
|
||||||
cmd_output('git', 'add', '.')
|
cmd_output('git', 'add', '.')
|
||||||
|
|
|
||||||
|
|
@ -871,7 +871,7 @@ def test_manifest_hooks(tempdir_factory, store):
|
||||||
require_serial=False,
|
require_serial=False,
|
||||||
stages=(
|
stages=(
|
||||||
'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg',
|
'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg',
|
||||||
'manual', 'push',
|
'manual', 'post-checkout', 'push',
|
||||||
),
|
),
|
||||||
types=['file'],
|
types=['file'],
|
||||||
verbose=False,
|
verbose=False,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue