Skip to content

Commit b26465c

Browse files
authored
Merge pull request #182 from konard/issue-181-09bf075a5254
fix(shell): pass explicit origin and branch to git pull --rebase
2 parents 27394a9 + f0261a4 commit b26465c

File tree

7 files changed

+46
-11
lines changed

7 files changed

+46
-11
lines changed

packages/lib/src/core/templates-entrypoint.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
renderEntrypointZshShell,
1212
renderEntrypointZshUserRc
1313
} from "./templates-entrypoint/base.js"
14-
import { renderEntrypointDnsRepair } from "./templates-entrypoint/dns-repair.js"
1514
import { renderEntrypointClaudeConfig } from "./templates-entrypoint/claude.js"
1615
import {
1716
renderEntrypointAgentsNotice,
@@ -20,6 +19,7 @@ import {
2019
renderEntrypointCodexSharedAuth,
2120
renderEntrypointMcpPlaywright
2221
} from "./templates-entrypoint/codex.js"
22+
import { renderEntrypointDnsRepair } from "./templates-entrypoint/dns-repair.js"
2323
import { renderEntrypointGeminiConfig } from "./templates-entrypoint/gemini.js"
2424
import { renderEntrypointGitConfig, renderEntrypointGitHooks } from "./templates-entrypoint/git.js"
2525
import { renderEntrypointDockerGitBootstrap } from "./templates-entrypoint/nested-docker-git.js"

packages/lib/src/core/templates-entrypoint/dns-repair.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// INVARIANT: after execution, at least one nameserver in /etc/resolv.conf resolves external domains
1111
// COMPLEXITY: O(1) per probe attempt, O(max_attempts) worst case
1212
export const renderEntrypointDnsRepair = (): string =>
13-
`# 0) Ensure DNS resolution works; repair /etc/resolv.conf if Docker DNS is broken
13+
String.raw`# 0) Ensure DNS resolution works; repair /etc/resolv.conf if Docker DNS is broken
1414
docker_git_repair_dns() {
1515
local test_domain="github.com"
1616
local resolv="/etc/resolv.conf"
@@ -32,7 +32,7 @@ docker_git_repair_dns() {
3232
3333
if [[ "$has_external" -eq 0 ]]; then
3434
for ns in $fallback_dns; do
35-
printf "nameserver %s\\n" "$ns" >> "$resolv"
35+
printf "nameserver %s\n" "$ns" >> "$resolv"
3636
done
3737
echo "[dns-repair] appended fallback nameservers to $resolv"
3838
fi

packages/lib/src/shell/files.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import type * as FileSystem from "@effect/platform/FileSystem"
33
import type * as Path from "@effect/platform/Path"
44
import { Effect, Match } from "effect"
55

6-
import { type TemplateConfig } from "../core/domain.js"
76
import { dockerGitScriptNames } from "../core/docker-git-scripts.js"
7+
import { type TemplateConfig } from "../core/domain.js"
88
import { resolveComposeResourceLimits, withDefaultResourceLimitIntent } from "../core/resource-limits.js"
99
import { type FileSpec, planFiles } from "../core/templates.js"
1010
import { FileExistsError } from "./errors.js"

packages/lib/src/usecases/projects-apply-all.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ export const applyAllDockerGitProjects: Effect.Effect<
3737
runDockerComposeUpWithPortCheck(status.projectDir).pipe(
3838
Effect.catchTag("DockerCommandError", (error: DockerCommandError) =>
3939
Effect.logWarning(
40-
`apply failed for ${status.projectDir}: ${renderError(error)}. Check the project docker-compose config (e.g. env files for merge conflicts, port conflicts in docker-compose.yml config) and retry.`
40+
`apply failed for ${status.projectDir}: ${
41+
renderError(error)
42+
}. Check the project docker-compose config (e.g. env files for merge conflicts, port conflicts in docker-compose.yml config) and retry.`
4143
)),
4244
Effect.catchTag("ConfigNotFoundError", (error) =>
4345
Effect.logWarning(

packages/lib/src/usecases/projects.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export { applyAllDockerGitProjects } from "./projects-apply-all.js"
12
export {
23
buildSshCommand,
34
loadProjectItem,
@@ -7,7 +8,6 @@ export {
78
type ProjectLoadError,
89
type ProjectStatus
910
} from "./projects-core.js"
10-
export { applyAllDockerGitProjects } from "./projects-apply-all.js"
1111
export { deleteDockerGitProject } from "./projects-delete.js"
1212
export { downAllDockerGitProjects } from "./projects-down.js"
1313
export { listProjectItems, listProjects, listProjectSummaries, listRunningProjectItems } from "./projects-list.js"

packages/lib/src/usecases/state-repo.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,15 @@ export const autoPullState: Effect.Effect<void, never, StateRepoEnv> = Effect.ge
161161
if (!enabled) {
162162
return
163163
}
164-
yield* _(statePullInternal(root))
164+
// CHANGE: abort any in-progress rebase if pull fails to prevent conflict markers
165+
// WHY: if git pull --rebase fails (e.g. due to merge commits), git leaves the repo
166+
// in a conflicted state with conflict markers; rebase --abort restores clean state
167+
// PURITY: SHELL
168+
yield* _(
169+
statePullInternal(root).pipe(
170+
Effect.tapError(() => git(root, ["rebase", "--abort"], gitBaseEnv).pipe(Effect.orElse(() => Effect.void)))
171+
)
172+
)
165173
}).pipe(
166174
Effect.matchEffect({
167175
onFailure: (error) => Effect.logWarning(`State auto-pull failed: ${String(error)}`),
@@ -187,9 +195,21 @@ const statePullInternal = (
187195
)
188196
const originUrl = yield* _(normalizeOriginUrlIfNeeded(root, rawOriginUrl))
189197
const token = yield* _(resolveGithubToken(fs, path, root))
198+
// CHANGE: resolve current branch and pass origin <branch> explicitly
199+
// WHY: bare `git pull --rebase` can fail or pull the wrong branch in some git configurations
200+
// QUOTE(ТЗ): "Сделай что бы правильные параметры передавались"
201+
// REF: issue-181
202+
// PURITY: SHELL
203+
const branchRaw = yield* _(
204+
gitCapture(root, ["rev-parse", "--abbrev-ref", "HEAD"], gitBaseEnv).pipe(
205+
Effect.map((value) => value.trim()),
206+
Effect.orElse(() => Effect.succeed("main"))
207+
)
208+
)
209+
const branch = branchRaw === "HEAD" ? "main" : branchRaw
190210
const effect = token && token.length > 0 && isGithubHttpsRemote(originUrl)
191-
? withGithubAskpassEnv(token, (env) => git(root, ["pull", "--rebase"], env))
192-
: git(root, ["pull", "--rebase"], gitBaseEnv)
211+
? withGithubAskpassEnv(token, (env) => git(root, ["pull", "--rebase", "origin", branch], env))
212+
: git(root, ["pull", "--rebase", "origin", branch], gitBaseEnv)
193213
yield* _(effect)
194214
}).pipe(Effect.asVoid)
195215

packages/lib/src/usecases/state-repo/pull-push.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,22 @@ export const statePull: Effect.Effect<
2525
return
2626
}
2727
const auth = yield* _(resolveStateGithubContext(fs, path, root))
28+
// CHANGE: resolve current branch and pass origin <branch> explicitly
29+
// WHY: bare `git pull --rebase` can fail or pull the wrong branch in some git configurations
30+
// QUOTE(ТЗ): "Сделай что бы правильные параметры передавались"
31+
// REF: issue-181
32+
// PURITY: SHELL
33+
const branchRaw = yield* _(
34+
pipe(
35+
gitCapture(root, ["rev-parse", "--abbrev-ref", "HEAD"], gitBaseEnv),
36+
Effect.map((value) => value.trim()),
37+
Effect.orElse(() => Effect.succeed("main"))
38+
)
39+
)
40+
const branch = branchRaw === "HEAD" ? "main" : branchRaw
2841
const effect = auth.token && auth.token.length > 0 && isGithubHttpsRemote(auth.originUrl)
29-
? withGithubAskpassEnv(auth.token, (env) => git(root, ["pull", "--rebase"], env))
30-
: git(root, ["pull", "--rebase"], gitBaseEnv)
42+
? withGithubAskpassEnv(auth.token, (env) => git(root, ["pull", "--rebase", "origin", branch], env))
43+
: git(root, ["pull", "--rebase", "origin", branch], gitBaseEnv)
3144
yield* _(withGithubAuthHintOnFailure(effect, auth.authHintNeeded))
3245
}).pipe(Effect.asVoid)
3346

0 commit comments

Comments
 (0)