Skip to content

Commit a60db81

Browse files
committed
reset to main on every new task
1 parent 3e9e3cc commit a60db81

File tree

1 file changed

+54
-1
lines changed

1 file changed

+54
-1
lines changed

swe_af/app.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ async def build(
7777
raise ValueError("Either repo_path or repo_url must be provided")
7878

7979
# Clone if repo_url is set and target doesn't exist yet
80-
if cfg.repo_url and not os.path.exists(os.path.join(repo_path, ".git")):
80+
git_dir = os.path.join(repo_path, ".git")
81+
if cfg.repo_url and not os.path.exists(git_dir):
8182
app.note(f"Cloning {cfg.repo_url}{repo_path}", tags=["build", "clone"])
8283
os.makedirs(repo_path, exist_ok=True)
8384
clone_result = subprocess.run(
@@ -89,6 +90,58 @@ async def build(
8990
err = clone_result.stderr.strip()
9091
app.note(f"Clone failed (exit {clone_result.returncode}): {err}", tags=["build", "clone", "error"])
9192
raise RuntimeError(f"git clone failed (exit {clone_result.returncode}): {err}")
93+
elif cfg.repo_url and os.path.exists(git_dir):
94+
# Repo already cloned by a prior build — reset to remote default branch
95+
# so git_init creates the integration branch from a clean baseline.
96+
default_branch = cfg.github_pr_base or "main"
97+
app.note(
98+
f"Repo already exists at {repo_path} — resetting to origin/{default_branch}",
99+
tags=["build", "clone", "reset"],
100+
)
101+
102+
# Remove stale worktrees on disk before touching branches
103+
worktrees_dir = os.path.join(repo_path, ".worktrees")
104+
if os.path.isdir(worktrees_dir):
105+
import shutil
106+
shutil.rmtree(worktrees_dir, ignore_errors=True)
107+
subprocess.run(
108+
["git", "worktree", "prune"],
109+
cwd=repo_path, capture_output=True, text=True,
110+
)
111+
112+
# Fetch latest remote state
113+
fetch = subprocess.run(
114+
["git", "fetch", "origin"],
115+
cwd=repo_path, capture_output=True, text=True,
116+
)
117+
if fetch.returncode != 0:
118+
app.note(f"git fetch failed: {fetch.stderr.strip()}", tags=["build", "clone", "error"])
119+
120+
# Force-checkout default branch (handles dirty working tree from crashed builds)
121+
subprocess.run(
122+
["git", "checkout", "-f", default_branch],
123+
cwd=repo_path, capture_output=True, text=True,
124+
)
125+
reset = subprocess.run(
126+
["git", "reset", "--hard", f"origin/{default_branch}"],
127+
cwd=repo_path, capture_output=True, text=True,
128+
)
129+
if reset.returncode != 0:
130+
# Hard reset failed — nuke and re-clone as last resort
131+
app.note(
132+
f"Reset to origin/{default_branch} failed — re-cloning",
133+
tags=["build", "clone", "reclone"],
134+
)
135+
import shutil
136+
shutil.rmtree(repo_path, ignore_errors=True)
137+
os.makedirs(repo_path, exist_ok=True)
138+
clone_result = subprocess.run(
139+
["git", "clone", cfg.repo_url, repo_path],
140+
capture_output=True, text=True,
141+
)
142+
if clone_result.returncode != 0:
143+
err = clone_result.stderr.strip()
144+
raise RuntimeError(f"git re-clone failed: {err}")
92145
else:
93146
# Ensure repo_path exists even when no repo_url is provided (fresh init case)
94147
# This is needed because planning agents may need to read the repo in parallel with git_init

0 commit comments

Comments
 (0)