mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-10-19 07:23:51 +00:00
Rebase local plugin commits during updates
Divergent local and upstream commits caused plugin updates to fail because git pull had no reconciliation strategy. Fetch the configured upstream and rebase local commits. Abort conflicting rebases and restore the original commits and edits, preserving the stash index during rollback. Refuse existing Git operations and leave other branch refs untouched. Include escaped conflicting filenames in a persistent error toast and retain the existing detail view. Validation: 12 updater tests passed. Isolated installer/API checks covered Git and ZIP installation, ordinary updates, rebasing, conflicts, and an unavailable remote. Browser checks verified the conflict toast and filename escaping.
This commit is contained in:
parent
4470d206b7
commit
40a4303637
6 changed files with 115 additions and 18 deletions
|
|
@ -109,6 +109,87 @@ def test_update_repo_restores_original_plugin_and_local_edit_after_conflict(tmp_
|
|||
assert run_git(installed, "stash", "list") == ""
|
||||
|
||||
|
||||
def test_update_repo_rebases_local_commits_on_the_configured_upstream(tmp_path: Path):
|
||||
_, source, installed = make_plugin_repos(tmp_path)
|
||||
run_git(installed, "branch", "-m", "local")
|
||||
run_git(installed, "config", "pull.ff", "only")
|
||||
run_git(installed, "config", "rebase.updateRefs", "true")
|
||||
(installed / "local.py").write_text("local change\n")
|
||||
run_git(installed, "add", "local.py")
|
||||
run_git(installed, "commit", "-m", "local commit")
|
||||
original_head = run_git(installed, "rev-parse", "HEAD")
|
||||
run_git(installed, "branch", "keep-local")
|
||||
(installed / "README.md").write_text("uncommitted edit\n")
|
||||
(installed / ".toggle-1").write_text("")
|
||||
push_source_change(source, "plugin.py", "value = 'upstream'\n")
|
||||
|
||||
git_helpers.update_repo(str(installed))
|
||||
|
||||
assert run_git(installed, "branch", "--show-current") == "local"
|
||||
assert run_git(installed, "rev-parse", "HEAD^") == run_git(source, "rev-parse", "HEAD")
|
||||
assert run_git(installed, "rev-parse", "HEAD") != original_head
|
||||
assert run_git(installed, "rev-parse", "keep-local") == original_head
|
||||
assert (installed / "local.py").read_text() == "local change\n"
|
||||
assert (installed / "plugin.py").read_text() == "value = 'upstream'\n"
|
||||
assert (installed / "README.md").read_text() == "uncommitted edit\n"
|
||||
assert (installed / ".toggle-1").exists()
|
||||
assert run_git(installed, "stash", "list") == ""
|
||||
|
||||
|
||||
@pytest.mark.parametrize("dirty", [False, True])
|
||||
def test_rebase_conflict_restores_commits_edits_and_existing_stashes(tmp_path: Path, dirty: bool):
|
||||
_, source, installed = make_plugin_repos(tmp_path)
|
||||
(installed / "README.md").write_text("previous stash\n")
|
||||
run_git(installed, "stash", "push", "-m", "user stash")
|
||||
previous_stash = run_git(installed, "rev-parse", "refs/stash")
|
||||
(installed / "plugin.py").write_text("value = 'local commit'\n")
|
||||
run_git(installed, "add", "plugin.py")
|
||||
run_git(installed, "commit", "-m", "local commit")
|
||||
original_head = run_git(installed, "rev-parse", "HEAD")
|
||||
if dirty:
|
||||
(installed / "README.md").write_text("staged edit\n")
|
||||
run_git(installed, "add", "README.md")
|
||||
(installed / "README.md").write_text("staged and unstaged edit\n")
|
||||
(installed / ".toggle-1").write_text("enabled\n")
|
||||
original_status = git_status(installed)
|
||||
original_index = run_git(installed, "diff", "--cached")
|
||||
original_edits = run_git(installed, "diff")
|
||||
push_source_change(source, "plugin.py", "value = 'upstream'\n")
|
||||
|
||||
with pytest.raises(git_helpers.DirtyTreeConflictError) as error:
|
||||
git_helpers.update_repo(str(installed))
|
||||
|
||||
assert error.value.conflicting_files == ["plugin.py"]
|
||||
assert run_git(installed, "branch", "--show-current") == "main"
|
||||
assert run_git(installed, "rev-parse", "HEAD") == original_head
|
||||
assert git_status(installed) == original_status
|
||||
assert run_git(installed, "diff", "--cached") == original_index
|
||||
assert run_git(installed, "diff") == original_edits
|
||||
assert run_git(installed, "rev-parse", "refs/stash") == previous_stash
|
||||
assert not (installed / ".git/rebase-merge").exists()
|
||||
assert not (installed / ".git/rebase-apply").exists()
|
||||
|
||||
|
||||
def test_update_repo_leaves_an_existing_rebase_untouched(tmp_path: Path):
|
||||
_, source, installed = make_plugin_repos(tmp_path)
|
||||
(installed / "plugin.py").write_text("local\n")
|
||||
run_git(installed, "add", "plugin.py")
|
||||
run_git(installed, "commit", "-m", "local commit")
|
||||
push_source_change(source, "plugin.py", "upstream\n")
|
||||
run_git(installed, "fetch")
|
||||
result = subprocess.run(
|
||||
["git", "-C", str(installed), "rebase", "origin/main"], capture_output=True,
|
||||
)
|
||||
assert result.returncode != 0
|
||||
before = git_status(installed)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
git_helpers.update_repo(str(installed))
|
||||
|
||||
assert git_status(installed) == before
|
||||
assert (installed / ".git/rebase-merge").is_dir()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("extension", ["png", "jpg"])
|
||||
def test_thumbnail_download_preserves_repo_image_and_allows_upstream_updates(
|
||||
tmp_path: Path, monkeypatch, extension: str
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue