Skip to content

laptop-autocommit: no merge/cherry-pick-in-progress guard — the every-minute sweep finalizes a live merge as an 'autocommit:' commit and pushes it #1807

Closed

Description

@dezren39

laptop-autocommit: no merge/cherry-pick-in-progress guard — the every-minute sweep finalizes a live merge (or cherry-pick) as an "autocommit:" commit and pushes it

Evidence

nixos/home/laptop-autocommit.sh (29 lines, sha256 e58fea91… on main e91098f1) is run every minute per repo by the timers in nixos/home/laptop-autocommit.nix (OnCalendar = "*-*-* *:*:00", repos: ~/.openclaw, ~/hatch, ~/hatch-personal).

Its only in-progress guard is the index lock:

  • :11 — [ -e "$d/.git/index.lock" ] && exit 0 — the only busy check.
  • :14-15 — it then requires only that the current branch is the default branch. During a merge or cherry-pick on main, the branch is main.
  • :16-22 — git add -u, and if the index differs, a bare git commit -q -m "autocommit: …".
  • :24-28 — the result is then pushed to origin <default-branch>.

There is no check for MERGE_HEAD, CHERRY_PICK_HEAD, REVERT_HEAD, rebase-merge/rebase-apply, or .git/sequencer anywhere in the script. The sibling keeper script learned exactly this lesson in #1771 and now guards on all of them (nixos/home/laptop-repo-keeper.sh:65, using the absolute git dir since a worktree's .git is a file). The autocommit script, added the same day (#1723), never got the guard.

Probe (laptop, verbatim script from the laptop primary clone, sha-identical to main)

Probe dir: ~/git/fleet/probe-2026-10-28-laneB-autocommit/ (throwaway repos with a local bare origin):

  • Control — ordinary tracked change on main, no operation in progress: committed as autocommit: … and pushed. PASS (intended behaviour).
  • Merge in progress — conflicting merge of feature into main started (MERGE_HEAD present), conflict resolved and staged by hand, not yet committed (no index.lock at that moment): one run of the script produced a two-parent merge commit with subject autocommit: merge1 2026-10-28 15:26, cleared MERGE_HEAD, and pushed it to origin main (ls-remote = the new merge HEAD). The user's unfinished merge — which they might still have wanted to test, amend, or abort with git merge --abort — was finalized and published within a minute of staging the resolution.
  • Cherry-pick in progress — conflicting cherry-pick stopped (CHERRY_PICK_HEAD present), conflict resolved and staged: one run committed it as autocommit: cp1 … (the picked commit's own subject/message lost), cleared CHERRY_PICK_HEAD, and pushed it.

Why it matters

The repos this sweeps are personal working repos where merges and cherry-picks on the default branch are routine. Any conflict resolution that takes more than a minute while staged — i.e. essentially all of them, since the timer fires every 60 s — is silently committed under a meaningless autocommit: message and pushed to origin, with no chance to abort, squash, write a real message, or run a check first. For a merge, --abort becomes impossible once pushed; recovering means a revert or a history rewrite of a published branch.

Acceptance criteria

  • laptop-autocommit.sh exits 0 without staging, committing, or pushing when a merge, cherry-pick, revert, or rebase is in progress in the target repo (state detected via the absolute git dir, per the laptop-repo-keeper: BUSY check never sees a merge/rebase in progress — rev-parse --git-dir is relative, so the keeper sealed a live merge as a 'snapshot' commit #1771 keeper fix — a worktree's .git is a file, and .git may also be a submodule pointer).
  • The sequencer state (.git/sequencer, e.g. a multi-commit cherry-pick/revert sequence paused between picks) is also treated as busy, or the issue's triage comment explicitly pins why the per-operation HEAD files suffice.
  • A test (shell test beside the script, in the style of nixos/home/openclaw-backup.test.sh) covers: merge-in-progress → no commit, MERGE_HEAD intact; cherry-pick-in-progress → no commit; ordinary tracked change → still committed and pushed (control).
  • No behaviour change for the clean-tree, detached-HEAD, off-default-branch, and index-locked cases.

Related: #1771 (same guard, keeper), #1751 (sibling sweep script committing more than its mandate — different script, different mechanism).

Activity

  1. developing-today commented on Oct 28, 2026

    @developing-today
    Contributor
  2. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    source/creatorFiled by the new-issue-creator job
    priority/highImportant and time-sensitive
    queue/queuedHas a queued task in the Supabase agent queue
    app/agent-backupPackage/app: agent-backup (pkgs/ or apps/ in this repo)
    area/nixosNixOS modules and machine configuration
    effort/xsTrivial: expected under 30 minutes of work
    on Oct 28, 2026
  3. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

  4. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  5. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    task 2690 (repo-health-code-pilot, lane code-b): triage CONFIRMED on fresh main. nixos/home/laptop-autocommit.sh line 15 still checks only index.lock before add -u + commit (lines 19-25); the MERGE_HEAD mention at line 41 is post-pull conflict reporting, not a pre-commit guard, and no CHERRY_PICK_HEAD/REVERT_HEAD/rebase/sequencer check precedes the commit path. Mirror source verified fresh: laptop-repo-keeper.sh:76 BUSY guard (index.lock + MERGE_HEAD + rebase-merge + rebase-apply via absolute git dir). Existing laptop-autocommit-merge-abort.test.sh covers the pull-conflict abort, not this guard. Fix routed as task 6668 (small_fix, acceptance intact).

  6. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 3, 2026
  7. added a commit that references this issue on Nov 3, 2026
  8. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    task 6668 (repo-health-code-pilot, lane code-b): done. PR #4693 merged (merge commit 058bf72) — laptop-autocommit.sh now exits 0 untouched when MERGE_HEAD, CHERRY_PICK_HEAD, REVERT_HEAD, rebase-merge, rebase-apply, or sequencer state exists (absolute git dir, mirroring the keeper guard from #1771). New laptop-autocommit-in-progress.test.sh passes (merge + cherry-pick untouched, ordinary change still committed/pushed); existing merge-abort test passes; Codex review on head c63840b reported no findings. Basic guard check was pending fleet-wide at merge; merged under standing merge authority.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/agent-backupPackage/app: agent-backup (pkgs/ or apps/ in this repo)area/nixosNixOS modules and machine configurationeffort/xsTrivial: expected under 30 minutes of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/highImportant and time-sensitivesource/creatorFiled by the new-issue-creator jobtask/small-fixQueue packet kind: bounded fix with reproduction and targeted tests

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions