mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-01 03:43:46 +08:00
110 lines
5.1 KiB
Python
110 lines
5.1 KiB
Python
"""Refuse destructive checkout when ordinary patches cannot preserve local files."""
|
|
import pytest
|
|
|
|
from test_version_install_index import checkout, git, install, installer, repository_snapshot
|
|
|
|
|
|
@pytest.mark.parametrize('flag', ['assume-unchanged', 'skip-worktree'])
|
|
def test_hidden_index_flags_refuse_install_without_mutation(checkout, flag):
|
|
repo, data, old, latest = checkout
|
|
git(repo, 'update-index', '--' + flag, 'tracked.txt')
|
|
(repo / 'tracked.txt').write_bytes(b'valuable hidden working edit\n')
|
|
before = repository_snapshot(repo, data)
|
|
flags = git(repo, 'ls-files', '-v', '-z')
|
|
with pytest.raises(installer.InstallError, match='assume-unchanged|skip-worktree'):
|
|
install(checkout)
|
|
assert repository_snapshot(repo, data) == before
|
|
assert git(repo, 'ls-files', '-v', '-z') == flags
|
|
assert not (data / 'starpilot/version-backups').exists()
|
|
|
|
|
|
@pytest.mark.parametrize('flag', ['assume-unchanged', 'skip-worktree'])
|
|
def test_hidden_index_flags_refuse_restore_without_mutation(checkout, flag):
|
|
repo, data, old, latest = checkout
|
|
backup = install(checkout)
|
|
git(repo, 'update-index', '--' + flag, 'tracked.txt')
|
|
(repo / 'tracked.txt').write_bytes(b'valuable hidden post-install edit\n')
|
|
before = repository_snapshot(repo, data)
|
|
flags = git(repo, 'ls-files', '-v', '-z')
|
|
with pytest.raises(installer.InstallError, match='assume-unchanged|skip-worktree'):
|
|
installer.restore(backup, check_parked=lambda: installer.require_parked(data))
|
|
assert repository_snapshot(repo, data) == before
|
|
assert git(repo, 'ls-files', '-v', '-z') == flags
|
|
|
|
|
|
def ignored_checkout(checkout, shape):
|
|
repo, data, old, latest = checkout
|
|
target_path = 'hidden-local/child.txt' if shape == 'ancestor' else 'hidden-local'
|
|
target = repo / target_path
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_bytes(b'target committed content\n')
|
|
git(repo, 'add', target_path)
|
|
git(repo, 'commit', '-m', 'Target containing collision path')
|
|
target_sha = git(repo, 'rev-parse', 'HEAD').decode().strip()
|
|
git(repo, 'rm', target_path)
|
|
git(repo, 'commit', '-m', 'Current without collision path')
|
|
current = git(repo, 'rev-parse', 'HEAD').decode().strip()
|
|
(repo / '.git/info/exclude').write_text('hidden-local\n')
|
|
local = repo / ('hidden-local/child.txt' if shape == 'descendant' else 'hidden-local')
|
|
local.parent.mkdir(parents=True, exist_ok=True)
|
|
outside = data / 'outside-sentinel'
|
|
outside.write_bytes(b'valuable local ignored content\n')
|
|
if shape == 'symlink':
|
|
local.symlink_to(outside)
|
|
else:
|
|
local.write_bytes(outside.read_bytes())
|
|
return (repo, data, target_sha, current), local, outside
|
|
|
|
|
|
@pytest.mark.parametrize('shape', ['exact', 'ancestor', 'descendant', 'symlink'])
|
|
def test_ignored_conflicts_refuse_install_before_backup(checkout, shape):
|
|
state, local, outside = ignored_checkout(checkout, shape)
|
|
repo, data, old, latest = state
|
|
before = repository_snapshot(repo, data)
|
|
with pytest.raises(installer.InstallError, match='[Ii]gnored'):
|
|
install(state)
|
|
assert repository_snapshot(repo, data) == before
|
|
assert local.read_bytes() == outside.read_bytes() == b'valuable local ignored content\n'
|
|
assert local.is_symlink() == (shape == 'symlink')
|
|
assert not (data / 'starpilot/version-backups').exists()
|
|
|
|
|
|
@pytest.mark.parametrize('shape', ['exact', 'ancestor', 'descendant', 'symlink'])
|
|
def test_ignored_conflicts_refuse_restore_without_mutation(checkout, shape):
|
|
state, local, outside = ignored_checkout(checkout, shape)
|
|
repo, data, target, current = state
|
|
# Save source that tracks the conflicting path, then mimic a later checkout
|
|
# with a newly created ignored file. Restore must inspect that live state.
|
|
if local.is_symlink() or local.is_file():
|
|
local.unlink()
|
|
else:
|
|
raise AssertionError('Expected a file or symlink')
|
|
if shape == 'descendant':
|
|
local.parent.rmdir()
|
|
git(repo, 'checkout', '--force', '-B', 'Dom', target)
|
|
backup = installer._backup(repo, {'branch': 'Dom', 'commit': current, 'pinned': False}, data)
|
|
git(repo, 'checkout', '--force', '-B', 'Dom', current)
|
|
local.parent.mkdir(parents=True, exist_ok=True)
|
|
if shape == 'symlink':
|
|
local.symlink_to(outside)
|
|
else:
|
|
local.write_bytes(outside.read_bytes())
|
|
before = repository_snapshot(repo, data)
|
|
with pytest.raises(installer.InstallError, match='[Ii]gnored'):
|
|
installer.restore(backup, check_parked=lambda: installer.require_parked(data))
|
|
assert repository_snapshot(repo, data) == before
|
|
assert local.read_bytes() == outside.read_bytes() == b'valuable local ignored content\n'
|
|
assert local.is_symlink() == (shape == 'symlink')
|
|
|
|
|
|
def test_nonconflicting_ignored_files_allow_install_and_restore(checkout):
|
|
repo, data, old, latest = checkout
|
|
(repo / '.git/info/exclude').write_text('local-cache/\ntracked.txt.extra\n')
|
|
paths = [repo / 'local-cache/data.bin', repo / 'tracked.txt.extra']
|
|
for path in paths:
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
path.write_bytes(b'kept ignored content\n')
|
|
backup = install(checkout)
|
|
installer.restore(backup, check_parked=lambda: installer.require_parked(data))
|
|
assert all(path.read_bytes() == b'kept ignored content\n' for path in paths)
|