Did you know? An AI agent can write a correct code change and still damage a project by placing it on the wrong branch, overwriting a colleague’s edit, resolving a merge conflict incorrectly, or reporting that a pull request is merged when only its local branch changed. Safe agent-assisted software editing is not just code generation. It is a chain of verified repository identity, clean ownership boundaries, explicit parent commits, independently checked integration, and a recorded result from the hosting service.
This guide explains a specific engineering job: how to let an existing AI coding agent propose, test and merge changes without treating a successful shell command as permission to change shared history. The short answer is to start from an identified repository and commit, inspect dirty worktrees before writing, isolate the change on an authorised branch, verify the exact diff and test result, use protected pull-request review where required, and re-read the remote commit after integration. A changed remote is evidence to reconcile, not an invitation to force-push.
These practices apply to today’s coding assistants and CI-backed services. Artificial superintelligence remains hypothetical; this series title does not assert that ASI exists. The examples below are invented teaching cases. They illustrate how to avoid real class-of-error failures without pretending that a model has run a repository, passed a test or deployed a service when it has not.
Contents
- Why a repository has several states, not one answer
- Verify the repository, remote and authorised branch
- A dirty worktree is not an empty canvas
- Commit ancestry explains what a merge will actually include
- Conflicts must be resolved as questions about meaning
- Worked case: two branches, one wrong assumption and 84 checks
- Protected branches are part of the specification
- How to verify tests without pretending to have run them
- Recovering safely from uncertain push or merge responses
- Secrets, untrusted repositories and tool boundaries
- Ten merge failures and their concrete repair paths
- Changed-context exercise: the same patch on a release branch
- What Git can prove, and what it cannot
- Frequently asked questions
- Reader pathways and primary sources
Why a repository has several states, not one answer
A Git repository includes stored commits, references naming commits, an index describing the staged snapshot, and a working tree containing visible files. A remote hosting service adds its own branch references, pull requests, checks, review policies and deployment machinery. A coding agent must not flatten all these into a single variable called current code. It can edit a working file without staging it, stage a file without committing it, commit locally without pushing it, push a feature branch without merging it, and merge remotely without deploying the result.
The first safety question is therefore what changed, in which state, and relative to what reference. A prompt such as ‘fix the parser’ is not a complete write authority. The agent needs the repository identity, allowed paths, expected base branch, allowed write actions, review policy, test budget and definition of completion. If the owner authorises only a pull request, a direct push to the protected release branch is out of scope even if the command is technically possible.
The official git status manual distinguishes working-tree state from index state and describes machine-readable porcelain formats. A reliable automation consumes an unambiguous status representation rather than parsing decorative human output. It must also recognise untracked files, renamed paths, staged deletions, submodules and files that are ignored for good reason. A clean-looking editor tab is not an audit of repository state.
The agent should record the original HEAD object identifier and the intended upstream comparison. This makes a later review reproducible. If the base changes while the agent is reasoning, it can decide whether to rebase, merge, restart or ask for review under the project’s rules. Merely displaying a branch name does not fix its content: branch labels move as new commits arrive.
This workflow differs from general concurrent document editing. A code repository has a directed commit graph, staging layer, histories and checks that can make exact ancestry inspectable. The special reader job is preserving that graph and the humans responsible for its shared branches.
Verify the repository, remote and authorised branch
A coding assistant may have multiple directories open, a monorepo with nested packages, a worktree attached to a different branch, or a fork with the same project name. The directory name cannot be trusted as a unique identity. Before doing anything consequential, inspect the repository root and remotes, verify the expected project path, and compare the current base commit with the owner’s declared reference. A screenshot of a repository page is not a durable repository identifier.
Repository origin matters because a remote named origin is conventional, not magical. It can point to an old fork or a testing mirror. Automated commands should use a documented remote and repository identity derived from trusted configuration, not a remote address discovered in an untrusted issue body. A README, chat message or generated source file may contain proposed commands, but those are task data, not authority to change destinations.
Branch names also carry meaning. Main, release and feature branches can have different allowed actors and review gates. Determine whether the agent may create a new branch, update its own branch, edit a release branch, or only generate a patch for someone else. If the authorisation is vague, the safe output is a proposed diff and the outstanding decision, not an invented entitlement to integrate it.
Git commit identifiers are content-related object IDs, but the agent still needs to know which repository and desired branch they belong to. A commit from the correct hash on the wrong fork is not a production release. An approved pull request against yesterday’s release branch is not necessarily approved against today’s changed dependency tree. Tie the change record to the exact base, head, repository and approval context.
For anyone setting up a coding agent, a useful contract has fields for repository owner, canonical host, accepted remotes, base branch, allowed paths, excluded secrets, required checks, reviewer responsibility and final evidence. Keep those fields separate from the model’s prose. That makes later permission checks deterministic and makes an accidental write to the wrong repository easier to stop.
A dirty worktree is not an empty canvas
Consider an agent asked to adjust one parser function. Its working tree already contains an uncommitted CSS change, a new test fixture and a modified configuration file left by a developer. If the agent uses a blanket add-and-commit command, the commit may absorb other people’s work. That is not a harmless formatting issue. It changes ownership, review scope, potential secrets exposure and the assumptions behind the generated patch.
The safe response is to inspect working-tree and index status before editing. If unexpected changes are present, either use an explicitly authorised separate worktree or create a fresh clean checkout at a verified commit. Do not automatically discard, reset or stash somebody’s files without understanding and permission. A stash changes where work is stored and can itself conflict on restore. A clean isolated environment simplifies both rollback and the audit of what the agent actually authored.
The command git status –porcelain is useful for parsing machine results. A status code can indicate a staged change, an unstaged change, an untracked file or combinations. Your validator should understand the documented porcelain version, not assume every line begins with one ordinary filename. Filenames may contain whitespace and unusual characters; machine-safe formats help avoid errors caused by simplistic splitting.
After the agent edits files, compare both staged and unstaged changes with the original inventory. Confirm the staged paths are a subset of the approved target files, and inspect whether generated binaries, credentials or lockfiles were changed. A library dependency update may legitimately modify its lockfile, but that should be an explicit part of review rather than an accidental side effect.
A separate worktree is a boundary, not a complete sandbox. It can still access the same repository objects, credentials and external tools. The responsible workflow uses operating-system permissions and network restrictions suited to the task, and it reviews any tool whose effect extends beyond source files. A code agent must not infer that an isolated branch grants independent authority to run destructive production commands.
Commit ancestry explains what a merge will actually include
Git histories form a directed graph, not a sequence of documents each labelled ‘the latest’. Suppose main points to commit A when the agent begins. The agent adds commit B on feature/repair. While it works, a colleague adds commit C to main. The agent’s branch contains A then B; the latest main contains A then C. Merging B into current main means reconciling changes from both histories, not simply declaring B to be the new main.
If the changed files do not conflict, an automatic merge may succeed. That still does not prove semantic compatibility. B may change an API parameter while C changes the caller in a different file. Git’s content-based merge can construct a syntactically valid tree in which tests fail. A green merge result is only evidence that Git’s chosen merge strategy produced an integration result without unresolved textual conflicts.
Use the merge base to identify the common ancestor and review changes relative to that base. Check whether the feature branch is behind the target and whether required tests were run against the latest merged tree. The exact commit checked by a test matters. GitHub’s status checks documentation explains that automated checks are attached to particular commits and may be required by branch protection.
A force push is especially consequential because it can rewrite the remote branch reference to exclude work not present in the local history. Git normally rejects non-fast-forward pushes that would lose commits. The official git push manual documents force-with-lease as a safer guarded form when history rewriting is intentionally authorised, and also explains important caveats about relying on automatically updated tracking references. It is not a routine repair for a failed push.
The proper default for a shared protected branch is no force push. If the remote moved, fetch and compare the new state, re-run integration checks and seek the authorised review path. Do not translate ‘make the command pass’ into ‘override repository safeguards’. The working definition of success is that the intended change was integrated without losing unseen history or breaking a required policy.
Conflicts must be resolved as questions about meaning
When both branches edit the same lines, Git may mark a conflict. Conflict markers show alternatives from two histories. They do not tell the agent which version preserves product behaviour. Choosing the last version seen, dropping one side, or removing markers until a parser accepts the file can silently throw away features. A conflict is a request for interpretation against requirements and tests.
Review the base version, the current target-branch version and the proposed branch version. Git exposes stages for the ancestor and sides of a conflict, as described in the merge documentation. Identify the invariant each side intended to preserve. If one change introduces a new validation rule and the other adds a previously unsupported input, the merged code may need a third implementation, not a simple selection of either side.
Keep conflict-resolution scope narrow. Record which paths conflicted, what was resolved, which tests cover the interaction and whether an external owner must approve the result. If the conflict touches security configuration, database migrations or user-facing policy, a human review gate is particularly important. A model’s confidence in its chosen text is not evidence of the requested semantics.
Git merge –abort is documented as a way to back out of an in-progress merge, but it is not a guarantee that all prior uncommitted work will be perfectly reconstructed. The manual cautions that pre-existing changes can complicate recovery. That is another reason to begin in a clean isolated worktree and preserve an original commit checkpoint before starting merge experiments.
After resolving a conflict, validate syntax, run the relevant unit and integration tests, inspect the new diff from the merge base, and have the owner review any materially changed behaviour. Tests passing cannot certify every real-world requirement, but they are meaningful evidence when matched to the risk and version being merged.
Worked case: two branches, one wrong assumption and 84 checks
Here is a fictional engineering case with complete counts. At 09:00, the shared branch points to commit A. An AI agent makes one parser change and two tests in commit B on a separate branch. Meanwhile the team changes the request schema in commit C on main. The agent has three changed files, the colleague has two changed files, and one source file appears in both sets. Counting naive file changes gives three plus two equals five mentions, but the union contains only four distinct changed paths because one path overlaps.
The agent attempts integration after main advances to C. Git identifies one text conflict in the shared source file and cleanly combines the other three paths. The agent resolves the overlap by preserving both the new parser condition and the colleague’s renamed request field. This is only a proposed resolution until it is tested and reviewed. It records the base A, agent B, colleague C and resulting merge commit M, all represented here as placeholders rather than invented real object IDs.
The test suite has 84 applicable checks. Before the merge, 84 pass on B alone. After integrating with C, 81 pass and three fail because a fixture uses the old field name. The pass rate on the integrated candidate is 81/84 ≈ 96.43%, while the failing proportion is 3/84 ≈ 3.57%. Reporting that ‘all tests passed’ because B passed earlier would hide the only result that matters to the new combined code. The integrated candidate is not ready under a policy requiring every relevant check to pass.
The agent repairs the fixture in the authorised branch, runs the same 84 checks against the new integration commit and obtains 84/84 passed. Review also confirms the four distinct paths match scope. The protected-branch service accepts the pull request after the required checks and reviewer approval. Only then does the agent fetch the target branch, verify it contains the intended integrated commit under the repository’s merge strategy and record the actual pull-request and commit reference.
Even that verified merge is not the same as a production deployment. A deployment system may build, sign and release another artifact, or queue the change for later. The agent should report ‘merged to protected branch’ and any observed deployment status separately. By naming stages precisely, it avoids the common mistake of converting a local successful command into a fictional real-world release.
If a check fails again after a last-minute upstream change, the same evidence rule applies. Re-evaluate the current merge candidate rather than presenting older green results. The denominator of 84 checks describes this invented test suite only; it cannot be used as a universal measure of software quality or as a guarantee that untested paths are safe.
Protected branches are part of the specification
Repositories often require pull requests, review approvals, passing status checks, signed commits or limits on force pushes. Those policies define who may change shared history. They are not obstacles a coding agent should sidestep because the user wants speed. GitHub explains branch protections in its official protected branch documentation.
An agent should discover and obey the relevant rules through authorised repository interfaces. It may propose the right branch and prepare a pull request, but it should not forge a reviewer identity, disable a rule or create a parallel remote to evade checks. If no reviewer is available, the honest outcome is a ready-for-review change, not a completed merge.
Automated checks can be sensitive to exact commit identity. A check that passed on B may not satisfy a rule after the pull request incorporates C. Required checks can be pending, missing, failed or attached to a merge test commit. The GitHub troubleshooting guide describes several ways checks fail to attach as expected. Diagnosis should distinguish an actual failed test from a workflow configuration issue.
Separation of duties helps. The agent can author and explain a patch, an independent reviewer can consider risks and intent, and the hosting platform can enforce integration conditions. When one user holds several roles, document the real authorisation rather than pretending the model independently supplied human approval. In high-impact systems, repository access should be scoped to the smallest set of branches and operations that can complete the task.
This is a concrete instance of agent change control, but code integration adds graph ancestry, staging and branch-specific rules. Treat source control as a safety boundary where evidence survives the conversational context of the agent.
How to verify tests without pretending to have run them
A model can explain a testing strategy without executing the test suite. These are separate products. A claim such as ‘all checks passed’ needs an actual test runner result tied to the exact candidate commit, environment and command. A copied sentence from an issue comment, a stale CI status or an imagined log is not proof. Keep the executed-check receipt apart from the natural-language description.
Before testing, identify the intended contract. A parser change may require unit tests for boundary inputs, integration tests for callers and migration checks if a field name changes. Tests that only exercise the old happy path can pass while the new requirement fails. The agent should map a small number of acceptance claims to their relevant tests rather than treating an undifferentiated green badge as an explanation.
Record exact exit status, checked commit, test command, environment version, relevant logs and any skipped tests. A skipped check is not equivalent to a passed assertion. GitHub’s documentation describes the sometimes surprising state of skipped workflows and required checks; the release decision should use the platform’s actual reported semantics, not invent additional guarantees.
On test failure, examine the first meaningful failure rather than repeatedly rerunning a stochastic suite until it turns green. If failures are flaky, gather evidence of nondeterminism and its risk. Repeating a failing test until one attempt passes is not an adequate substitute for a reproducible reason that the patch is safe.
A good final report tells the maintainer which acceptance behaviours were checked, what remains untested, what changed since earlier checks and whether integration was actually performed. This keeps code-generation capability from being mistaken for verification capability. The principle extends naturally to documents, databases and other agent-created artifacts.
Recovering safely from uncertain push or merge responses
An API call can time out after the remote accepted a push or merge. Retrying blindly may create a second pull request, duplicate comments or unexpected state transitions. The repair begins with reconciliation: query the current remote branch and pull-request status, compare the expected commit identity, and inspect whether the intended action already occurred. Retry only an operation that remains valid under the current state.
Suppose an agent requests merge of pull request 42 and the connection drops. It should not submit a new pull request or force-push its local branch. Instead, fetch pull request 42 and the target branch through authorised APIs. If the request is already merged, verify the merge commit or the platform’s squash/rebase result. If it is still open with failed checks, explain that state. If the response is genuinely unknown, keep it uncertain until a reliable reconciliation is possible.
GitHub repositories support different merge methods. A squash merge may produce a new commit ID rather than preserve the exact feature branch tip as a main-branch ancestor. A rebase merge can likewise rewrite commits. The safe check follows the platform’s recorded merge outcome and expected change content, not a brittle assumption that the original B hash must always appear unchanged in main.
If the remote branch moved, use a fresh snapshot rather than trying to make the previous update pass at all costs. In multi-writer environments a queued merge can become stale between read and write. Guard against lost updates with permitted compare-and-swap or branch protection semantics where the platform provides them. Limit retries and surface a human escalation route for complex conflicts.
The general principle matches idempotency and recovery after uncertain tool calls. Git adds precise lineage and merge-method complications; the agent must reconcile against the same source of truth that owns the shared code rather than local assumptions.
Secrets, untrusted repositories and tool boundaries
Source code is untrusted task content from the agent’s perspective. It can contain a README instructing the assistant to reveal credentials, a test script that contacts an unrelated host, or a package install hook with side effects. Nothing about the text being inside a repository grants it authority over the assistant’s tools. The human’s approved scope and the environment’s safety controls remain authoritative.
Dependency scripts, build tools and continuous integration credentials introduce supply-chain risk. Running tests on a branch contributed by an untrusted actor may execute code with the permissions available in the runner. Protect secrets, restrict network and filesystem access, and use the repository’s established isolation strategy. The tool supply-chain guide covers provenance and admission controls more broadly.
The agent should not silently upgrade dependencies, rewrite lockfiles, change workflow privileges or amend deployment secrets while fixing an unrelated parser. Such changes can be appropriate in an authorised maintenance task, but they deserve separate explanations and checks. A narrow diff is easier to review and limits damage if an assumption is wrong.
Do not paste private CI tokens, SSH keys or full secret-bearing logs into public pull-request comments. Logs needed for diagnosis should be redacted while preserving enough provenance to establish the observed failure. A remote URL or submodule pointer supplied by repository content must be validated before downloading from or pushing to a new host.
A safe environment also protects against accidental commands. Do not make a generic ‘cleanup’ step that deletes untracked work or resets every branch. Require human approval for destructive or history-rewriting actions where they might affect other owners. Consistent limits are more useful than trusting a model to infer every consequence of a shell command from a conversational prompt.
Ten merge failures and their concrete repair paths
Failure one is creating a branch from the wrong repository or base commit. Repair it by checking repository identity, configured remote and initial commit before writing. Failure two is committing other people’s dirty working-tree changes. Repair it with a clean isolated checkout and a reviewed staging diff. Failure three is pushing to the wrong branch. Repair it with an explicit allowed branch policy and a verified remote reference.
Failure four is resolving a text conflict by deleting one side without understanding it. Repair it by inspecting ancestor and both sides, restating the requirements and adding relevant integration tests. Failure five is claiming local test success after main moved. Repair it by testing the integrated candidate against the latest required base.
Failure six is force-pushing to defeat a non-fast-forward rejection. Repair it by preserving upstream work, reconciling graph ancestry and using the approved review path. Failure seven is treating a pull request marked ‘open’ as merged. Repair it by checking the hosting service’s actual merged state and recorded integration result.
Failure eight is treating a merge as a deployment. Repair it by reporting those separately and following the release system’s receipts when deployment is part of the authorised job. Failure nine is accepting a prompt inside an untrusted repository as permission to run privileged commands. Repair it with tool restrictions and a trusted operation contract. Failure ten is duplicating operations after a network timeout. Repair it by reading the original pull request and commit state before a bounded retry.
Notice the underlying pattern: the wrong statement is often about the evidence, not the code. A system that changes three correct lines but lies about which branch received them has not completed its job. A system that pauses and truthfully reports an unresolved conflict may be much more reliable than one that asserts success without verified ancestry.
For each incident, record the exact last trustworthy state and the uncertainty. Do not rewrite the history of the incident to make the automated workflow appear smoother. Software teams learn from honest failure boundaries: repository identity, authorisation, staging, integration, review, merge, build and deployment.
Changed-context exercise: the same patch on a release branch
Try transferring the method to a hotfix. A production issue requires a one-line configuration correction. The main development branch contains six new features that are not approved for release. An agent prepares the fix on main and proposes merging main wholesale into the release branch. The source change may be correct, but the merge plan is not: it would import unrelated features. The required reader job is to isolate exactly the authorised change.
Assume the release branch is at R and main has progressed through commits F1 to F6. The hotfix H is based on main’s tip. A direct merge can make the release branch include F1 through F6 as well as H, depending on graph ancestry. The safe workflow is to prepare an isolated change based on R, or use an approved cherry-pick or patch strategy with explicit consideration of dependencies. No automated tool can assume the single changed line stands independently of all adjacent code.
Imagine that two of the six features modify configuration formats consumed by the hotfix. An isolated cherry-pick may fail to apply or pass only superficial tests. The agent must inspect that dependency, adapt the patch where authorised and test against the release branch’s actual environment. If a proper repair cannot be made without importing a broader migration, escalate the release decision rather than smuggling in unsupported changes.
Now run a hypothetical twelve-check release-specific suite. All twelve checks pass on the hotfix candidate, and the independent reviewer approves it. The branch protection service records a merge, but deployment has not yet started. The truthful output is ‘hotfix merged and release checks passed; deployment not verified.’ The denominator twelve describes only this release-specific suite, not all possible test coverage.
Finally change one condition: the release branch is updated by another emergency patch while the agent waits. The same merge safety steps repeat against the newly observed release commit. The exact ancestor and compatibility assumptions changed. This is what transfer looks like: the principles survive the new branch while the earlier command sequence is no longer automatically valid.
What Git can prove, and what it cannot
A commit identifier can identify content and parentage within Git’s object model; it does not certify that a change is correct, useful, authorised or secure. A clean merge is evidence about integration mechanics, not full behavioural compatibility. A passing suite is evidence about selected tests under a particular environment. An approved review is evidence that named reviewers approved under a particular workflow, not that every future condition has been analysed.
Similarly, a protected branch is a valuable guard but not a guarantee against every human error or administrator action. A privileged actor may be authorised to bypass some rules; the policy may be misconfigured; or a malicious dependency may pass tests. Build a layered control system rather than treating any one gate as absolute.
Agent performance should be evaluated on completed engineering outcomes: correct scope, preserved collaborator work, integrated tested behaviour, policy compliance and honest final reporting. Counting commands issued, files modified or pull requests opened rewards activity rather than successful maintenance. A slower reviewable patch can be better than a fast untraceable one.
This section is intentionally about current software engineering rather than speculative superintelligence. Future AI systems would still need an accountable boundary between proposing code and altering shared infrastructure. Tool permission, external evidence and human responsibility cannot be replaced by a persuasive explanation of the code.
Frequently asked questions
Why isn’t a successful git merge command sufficient? It says Git produced a merged state under its chosen strategy. It does not prove semantic compatibility, required test outcomes, reviewer approval, remote integration or deployment.
What is the difference between the index and the working tree? The index is Git’s staged snapshot for the next commit, while the working tree contains files you are editing. They can differ, so an agent must examine both before claiming what it committed.
Is a clean worktree always safe? No. It reduces accidental inclusion of unrelated edits, but the remote target can move, tests can be weak, and commands can still affect other systems. Cleanliness is one precondition among several.
Should an AI agent automatically resolve merge conflicts? Only within explicitly authorised scope and with the required verification. Some conflicts require semantic judgement or a human owner; removing conflict markers alone is not evidence of repair.
May the agent ever use force-with-lease? Only when a history rewrite is intentionally authorised and the exact expected remote state and policy are understood. It must not be a default fix for a rejected push or a means to bypass branch protections.
How can a merge succeed yet tests fail? Two branches can edit different lines while their changes are incompatible as a system. Textual merging does not execute the program or check all assumptions.
What if a merge API call times out? Query the same pull request and remote branch before trying again. The first call may already have succeeded; blind retries create uncertainty and can change state again.
Can the model claim a release is live after a pull request merges? No. Deployment and user-visible verification are separate stages. Report only the status actually established by the release platform.
How should parents or students think about this topic? It illustrates a transferable skill: identify the original state, follow changes through stages, check the resulting state and never treat confident narration as proof of an external outcome.
Reader pathways and primary sources
If you build coding agents, begin with a repository-scope manifest, clean-checkout policy, exact commit identity, staged-diff gate, integration tests and a remote-state reconciliation procedure. The change-control guide explains why model or policy changes themselves also need safe rollouts.
If you maintain a shared repository, clarify which branches an agent may update, what reviews are mandatory and which actions require human approval. Record merge method and final target commit rather than simply storing an ‘approved’ checkbox. The workflow-migration guide is useful when releases also change durable application state.
If you are learning software engineering, practise with a toy repository where two branches edit the same function in different ways. Compare base, ours and theirs; write the acceptance condition before resolving; test the merged result; and explain what the commit graph does and does not prove. Do not run destructive cleanup steps on another person’s repository for practice.
Primary manuals: Git status, Git merge, Git push, and Git diff. Hosting platform references: GitHub protected branches, status checks, and required-check troubleshooting. These are the proper authorities for Git and GitHub-specific behaviour; implementations should recheck the version and repository policy.
The examples and figures here are illustrative. No repository, CI workflow or release was actually executed as part of this explanation. For the wider system view, visit How Super Intelligence Works and education that transfers into life.