fix: failing post-checkout on single file checkout

This commit is contained in:
Vitalii Budnik 2024-12-23 17:30:15 +03:00
parent cb14bc2d9c
commit 54485588e5
No known key found for this signature in database
GPG key ID: AA40142F2E432041
2 changed files with 53 additions and 2 deletions

View file

@ -344,8 +344,20 @@ def run(
# Check if we have unresolved merge conflict files and fail fast. # Check if we have unresolved merge conflict files and fail fast.
if stash and _has_unmerged_paths(): if stash and _has_unmerged_paths():
# Do not fail on unmerged files if this is a post-checkout hooks.
# This handles cases when there are unmerged paths and:
# * resolving conflict with `git checkout --ours/--theirs -- <paths>`
# * or checking out single files with `git checkout <b> -- <paths>`.
if args.hook_stage == 'post-checkout':
output.write_line(
f'Skipping `{args.hook_stage}` hooks since '
f'it\'s a file checkout or same head ref',
)
return 0
else:
logger.error('Unmerged files. Resolve before committing.') logger.error('Unmerged files. Resolve before committing.')
return 1 return 1
if bool(args.from_ref) != bool(args.to_ref): if bool(args.from_ref) != bool(args.to_ref):
logger.error('Specify both --from-ref and --to-ref.') logger.error('Specify both --from-ref and --to-ref.')
return 1 return 1

View file

@ -536,6 +536,22 @@ def test_merge_conflict(cap_out, store, in_merge_conflict):
assert b'Unmerged files. Resolve before committing.' in printed assert b'Unmerged files. Resolve before committing.' in printed
def test_merge_conflict_post_checkout(cap_out, store, in_merge_conflict):
ret, printed = _do_run(
cap_out,
store,
in_merge_conflict,
run_opts(hook_stage='post-checkout'),
)
assert ret == 0
assert b'Unmerged files. Resolve before committing.' not in printed
msg = (
b'Skipping `post-checkout` hooks since '
b'it\'s a file checkout or same head ref'
)
assert msg in printed
def test_files_during_merge_conflict(cap_out, store, in_merge_conflict): def test_files_during_merge_conflict(cap_out, store, in_merge_conflict):
opts = run_opts(files=['placeholder']) opts = run_opts(files=['placeholder'])
ret, printed = _do_run(cap_out, store, in_merge_conflict, opts) ret, printed = _do_run(cap_out, store, in_merge_conflict, opts)
@ -554,6 +570,29 @@ def test_merge_conflict_modified(cap_out, store, in_merge_conflict):
assert b'Unmerged files. Resolve before committing.' in printed assert b'Unmerged files. Resolve before committing.' in printed
def test_merge_conflict_modified_post_checkout(
cap_out, store, in_merge_conflict
):
# Touch another file so we have unstaged non-conflicting things
assert os.path.exists('placeholder')
with open('placeholder', 'w') as placeholder_file:
placeholder_file.write('bar\nbaz\n')
ret, printed = _do_run(
cap_out,
store,
in_merge_conflict,
run_opts(hook_stage='post-checkout'),
)
assert ret == 0
assert b'Unmerged files. Resolve before committing.' not in printed
msg = (
b'Skipping `post-checkout` hooks since '
b'it\'s a file checkout or same head ref'
)
assert msg in printed
def test_merge_conflict_resolved(cap_out, store, in_merge_conflict): def test_merge_conflict_resolved(cap_out, store, in_merge_conflict):
cmd_output('git', 'add', '.') cmd_output('git', 'add', '.')
ret, printed = _do_run(cap_out, store, in_merge_conflict, run_opts()) ret, printed = _do_run(cap_out, store, in_merge_conflict, run_opts())