GitoxideLabs/gitoxide · error
git stash push did not create a new stash
Error message
git stash push did not create a new stash
What it means
After running `git stash push`, `refs/stash` still points to the same commit it had before, meaning the stash operation silently did not create a new stash entry. The library detects this by comparing the pre-push `refs/stash` id with the post-push id and bails. This protects against editing the named state reference to point at a stale/unchanged stash commit.
Solutions
- Verify the working tree actually has uncommitted changes before saving.
- Inspect `git stash list` and `git rev-parse refs/stash` to see why the ref did not move.
- If the changes were already stashed, skip save or resume from the existing state instead.
Defensive patterns
Strategy: validation
Validate before calling
// Only save when there is something to stash
let dirty = !repo.status(gix::status::platform::prepare::Options::default())?.is_empty();
if !dirty { return Ok(()); } // nothing to stash; skip save Try / catch
match result {
Err(e) if e.to_string().contains("did not create a new stash") => {
// treat as no-op: working tree was clean
}
other => other?,
} Prevention
- Check for uncommitted changes before invoking stash-based save.
- Do not manually reset refs/stash while the flow is running.
- Log `git rev-parse refs/stash` before and after to detect no-op pushes.
When it happens
Trigger: Calling save/save_manual when `git stash push` exits 0 but does not actually stash anything new (e.g. nothing to stash behavior, or the stash ref was manually reset), so `previous == Some(id)`.
Common situations: A clean working tree where git reports 'No local changes to save' yet exits successfully; hooks or config altering stash behavior; a previous stash push having already consumed the changes.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- tix stash reference does not use a canonical full commit ID
- cannot drop stashed commit
- stashes at and would converge on
- rewritten commit already has saved worktree state
- changes can only be stashed at the current HEAD
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/4c508a2a0d2e1acc.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/stash.rs:230
let output = Command::new("git")
.arg("-C")
.arg(workdir)
.args(["stash", "push", "--include-untracked", "--quiet", "--message"])
.arg(message)
.output()
.context("could not launch git stash push")?;
if !output.status.success() {
anyhow::bail!("git stash push failed: {}", output.stderr.trim().to_str_lossy());
}
let repo = open_repository(repository_path, bare, false).context("could not reopen repository after stashing")?;
let mut stash = repo
.try_find_reference("refs/stash")?
.context("git stash push did not create refs/stash")?;
let id = stash.peel_to_id()?.detach();
if previous == Some(id) {
anyhow::bail!("git stash push did not create a new stash");
}
let target = Target::Object(id);
if let Err(err) = repo.edit_references([RefEdit::update(
name.clone(),
target.clone(),
PreviousValue::MustNotExist,
reflog_message,
)]) {
drop(repo);
let restore = Command::new("git")
.arg("-C")
.arg(workdir)
.args(["stash", "pop", "--index", "--quiet"])
.output();
return Err(anyhow::anyhow!(err)).context(match restore {
Ok(output) if output.status.success() => {
format!("could not retain {state_label}; original state was restored")
}View on GitHub (pinned to e73179060b)