gitbutlerapp/gitbutler · error
Could not find commit
Error message
Could not find commit {commit_id} What it means
This is the fallback branch of the same commit lookup: when the iterator over indexed stack commits yields no match for the requested `commit_id`, the resolver reports that the commit cannot be found in the current workspace state.
Solutions
- Run `but status` (or the log TUI) to list currently managed commit ids and use one of those.
- If the commit should be managed, apply/assign its branch to the workspace so it is indexed, then retry.
- Verify the id is correct (copy the full or abbreviated hash from the intended commit) and refresh workspace state before retrying.
Defensive patterns
Strategy: try-catch
Validate before calling
// before resolving, confirm the id is among managed commits
if !managed_commit_ids().contains(&commit_id) {
eprintln!("{} is not managed by the workspace", commit_id);
} Try / catch
match workspace.find_commit(commit_id) {
Err(e) if e.to_string().contains("Could not find commit") => {
eprintln!("Run `but status` for managed ids; apply the branch if needed");
}
other => other?,
} Prevention
- Copy commit ids from `but status` / the GitButler log, not raw `git log`.
- Ensure the owning branch is applied to the workspace before referencing its commits.
- Use full or sufficiently long hashes to avoid abbreviation ambiguity.
When it happens
Trigger: Resolving a commit id that exists in the repository's object database but not in any indexed stack — e.g., referencing an already-pushed-and-removed commit, a commit on an unassigned branch, a typo'd/short id, or querying before the workspace index was refreshed.
Common situations: Using a commit id from `git log` that GitButler no longer manages; referring to a commit whose branch was unapplied; stale CLI state after another process changed the workspace; abbreviated hash that doesn't correspond to a managed commit.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Branch ' ' not found
- Branch ' ' not found when checking for conflicts
- Branch " " has no conflicted commits.
- Cannot apply non-existing branch
- Cannot unapply non-existing branch
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/f8fcc37c19bb8e60.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but/src/id/mod.rs:1804
pub fn stacks(&self) -> &Vec<StackWithId> {
self.indexed_stacks.borrow_owner()
}
/// Get a distinct commit by ID.
///
/// Errors if the commit cannot be found or if there are multiple matches.
pub fn get_commit_by_id(&self, commit_id: gix::ObjectId) -> anyhow::Result<CommitWithId<'_>> {
let mut matches = self
.commits()
.filter(|commit_with_id| match commit_with_id {
CommitWithId::Local(commit) => commit.commit_id() == commit_id,
CommitWithId::Remote(commit) => commit.commit_id() == commit_id,
});
match (matches.next(), matches.next()) {
(Some(commit), None) => Ok(commit),
(Some(_), Some(_)) => Err(anyhow::anyhow!("Found multiple matches for {commit_id}")),
_ => Err(anyhow::anyhow!("Could not find commit {commit_id}")),
}
}
fn commits(&self) -> impl Iterator<Item = CommitWithId<'_>> {
let stack_commits = self.indexed_stacks.borrow_owner().iter().flat_map(|stack| {
stack.segments.iter().flat_map(|segment| {
segment
.workspace_commits
.iter()
.map(CommitWithId::Local)
.chain(segment.remote_commits.iter().map(CommitWithId::Remote))
})
});
stack_commits.chain(
// Commits owned by a linked worktree resolve exactly like workspace commits - they
// just live outside the stacks.
self.worktreesView on GitHub (pinned to 58e5313667)