Skip to content

[codex] add write-side core operations#43

Merged
hartsock merged 4 commits into
mainfrom
codex/issue-21-write-core
Jun 7, 2026
Merged

[codex] add write-side core operations#43
hartsock merged 4 commits into
mainfrom
codex/issue-21-write-core

Conversation

@hartsock

@hartsock hartsock commented Jun 6, 2026

Copy link
Copy Markdown
Owner

What changed

  • Added Rust core write-side operations for pull, push, add, and commit.
  • Registered the new modules from src/repo/mod.rs without adding PyO3 bindings.
  • Added parity-style tests against temporary repositories and the real git CLI.
  • Treated clean git commit / nothing-to-commit as success without moving HEAD.
  • Moved fetch_result onto the shared run_git helper so fetch and write-side shell-outs share git env isolation and LC_ALL=C locale normalization.

Why

This starts the M2 write-side Rust core while keeping Python exposure deferred to #23.

Note: these Rust core functions intentionally follow the existing fetch_result pattern of returning (bool, String) for success plus stderr/reason text, rather than the literal issue-spec spelling for every method signature.

Closes #21

Validation

  • Initial red run: cargo test --no-default-features failed on unresolved pull/push/add/commit functions before implementation.
  • cargo test --no-default-features repo::fetch (2 passed)
  • cargo test --no-default-features repo::commit (2 passed)
  • cargo test --no-default-features (55 passed, 0 failed)
  • cargo fmt --all --check
  • git diff --check
  • cargo clippy --no-default-features --all-targets -- -D warnings
  • cargo clippy --features extension-module -- -D warnings
  • cargo build --features extension-module

Refs #21

Co-authored-by: Codex <codex@openai.com>

@hartsock hartsock left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: Drake (drake-interactive, Claude Opus 4.7 / 1M context), on behalf of @hartsock.

Solid parts

  • Per-method file layout (pull.rs, push.rs, add.rs, commit.rs) matches issue #21.
  • Tests use the existing fixtures module pattern from fetch.rs.
  • "nothing to commit" → success contract is honored.
  • New shared run_git helper carries the same env-stripping shape as fetch.rs (GIT_DIR, GIT_WORK_TREE, GIT_INDEX_FILE removed).

Issues to address before un-drafting

1. run_git introduced but fetch.rs doesn't adopt it

Two patterns now coexist: fetch.rs has its own inline Command::new("git")... returning (ok, stderr); the new write ops use super::run_git returning (ok, stderr, stdout). Drift risk: future hardening (e.g., adding GIT_TERMINAL_PROMPT=0 to disable credential prompts) would need to touch both. Either include the refactor here (~20 lines, mechanical) or open a follow-up issue and link it.

I'd push for the refactor in this PR — the codebase is already adopting the helper for everything new, so leaving fetch.rs as the outlier creates exactly the kind of subtle inconsistency that bites later.

2. commit's "nothing to commit" detection is locale-fragile

The match output.contains("nothing to commit") is case-folded (good) but English-only. Under LANG=fr_FR.UTF-8, git prints "rien à valider" and the heuristic misses. Set LC_ALL=C once, inside run_git, to stabilize stderr parsing for every future caller:

let out = Command::new("git")
    .arg("-C")
    .arg(path)
    .args(args)
    .env("LC_ALL", "C")
    .env_remove("GIT_DIR")
    .env_remove("GIT_WORK_TREE")
    .env_remove("GIT_INDEX_FILE")
    .output();

One line, covers everything. (And folds neatly into the refactor in §1.)

3. Signature mismatch with issue #21 spec

Issue #21 says Result<(bool, String)> but this PR returns (bool, String). The PR matches the codebase pattern (fetch_result is (bool, String), not Result<...>), so the issue spec looks like a documentation error. Worth a one-line acknowledgement in the PR description so a reviewer doesn't get tripped up against the literal issue text.

4. commit_nothing_to_commit_counts_as_success test is weak

It asserts ok but doesn't verify that no commit was created. A "nothing to commit" code path that silently created a commit would still pass. Strengthen with a HEAD-unchanged invariant:

#[test]
fn commit_nothing_to_commit_counts_as_success() {
    let repo = fixtures::repo();
    let before = fixtures::git(repo.path(), &["rev-list", "--count", "HEAD"]);

    let (ok, stderr) = super::commit(repo.path(), "noop");

    let after = fixtures::git(repo.path(), &["rev-list", "--count", "HEAD"]);
    assert!(ok, "{stderr}");
    assert_eq!(before, after, "no commit should have been created");
}

5. Test isolation asymmetry — comment, not a blocker

fixtures::git neutralizes host config (GIT_CONFIG_GLOBAL=/dev/null, sets identity); super::run_git does NOT — by design, for production (per fetch.rs's docstring). Net: tests exercising run_git still pick up the host's ~/.gitconfig. Tests pass on a vanilla host today; could break on a host with init.defaultBranch = master, core.hooksPath set, or commit.gpgsign = true.

Not a blocker — but a // NOTE: these tests assume a vanilla host git config near the test module(s) would save a future debugger an hour.

Recommended pre-merge checklist

  • Refactor fetch.rs onto run_git here, or open a follow-up issue and link it.
  • Add .env("LC_ALL", "C") in run_git to stabilize "nothing to commit" detection.
  • Strengthen the commit_nothing_to_commit test with a HEAD-unchanged assertion (snippet above).
  • Note in PR body that signatures match the fetch_result pattern, not the literal issue spec.

Note on cross-PR ordering

This PR's Rust additions aren't yet callable from Python — that needs a follow-up PyO3-binding PR. PR #42's PUBLIC_EXTENSION_NAMES lists pull, push, etc. as aspirational entries that will become real after the binding lands. No action needed here, just flagging the dependency so the order of merges is clear: write-side Rust (this PR) → bindings → write-side Python tests.

hartsock and others added 3 commits June 6, 2026 17:21
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
@hartsock hartsock marked this pull request as ready for review June 7, 2026 00:28
@hartsock hartsock merged commit c38c57f into main Jun 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

M2-W1: Write-side Rust core — pull, push, add, commit

1 participant