nikivdev/code · error
Unmerged files detected. Resolve them before syncing.
Error message
Unmerged files detected. Resolve them before syncing.
What it means
This error is thrown at the start of the sync flow in src/sync.rs when the repository contains unmerged files (git conflict entries in the index). Before syncing, the tool runs `git diff --name-only --diff-filter=U` and bails if any paths are unresolved, because a sync/fetch-merge cannot proceed with a dirty, conflicted index. It guards against corrupting the working state mid-conflict.
Source
Thrown at src/sync.rs:3249
}
}
}
}
}
fn run_jj_sync(
repo_root: &Path,
cmd: &SyncRunOptions,
auto_fix: bool,
recorder: &mut SyncRecorder,
) -> Result<()> {
// Avoid git operations in progress.
if is_rebase_in_progress() || is_merge_in_progress() {
bail!("Git operation in progress. Run `f git-repair` first.");
}
let unmerged = git_capture(&["diff", "--name-only", "--diff-filter=U"]).unwrap_or_default();
if !unmerged.trim().is_empty() {
bail!("Unmerged files detected. Resolve them before syncing.");
}
let head_ref = git_capture_in(repo_root, &["rev-parse", "--abbrev-ref", "HEAD"])
.unwrap_or_else(|_| "HEAD".to_string());
let head_ref = head_ref.trim();
let default_branch = jj_default_branch(repo_root);
let current_bookmarks = jj_local_bookmarks_at_rev(repo_root, "@");
let current_branch = select_jj_sync_branch(head_ref, ¤t_bookmarks, &default_branch);
if head_ref == "HEAD" || head_ref.is_empty() {
recorder.record(
"jj",
format!("detached head (using jj branch {})", current_branch),
);
} else if current_branch != head_ref {
recorder.record(
"jj",
format!(
"using current jj bookmark {} instead of git HEAD {}",View on GitHub (pinned to a747e741ae)
Solutions
- Resolve the conflicts: run `git diff --name-only --diff-filter=U` to list files, edit each to remove conflict markers.
- Stage resolved files with `git add <file>` (or `git add .`) and commit the merge.
- Run `f git-repair` as suggested by related sync errors if the repo state seems inconsistent.
- If you truly want to abandon the conflicted state, `git merge --abort` (or `git rebase --abort`) then re-run sync.
Example fix
// before (sync fails) f sync // error: Unmerged files detected. Resolve them before syncing. // after git diff --name-only --diff-filter=U # list conflicted files git add src/main.rs # resolve + stage git commit # finish merge f sync # now succeeds
Defensive patterns
Strategy: validation
Validate before calling
let unmerged = git_capture(&["diff", "name-only", "--diff-filter=U"]).unwrap_or_default();
if !unmerged.trim().is_empty() {
eprintln!("Resolve conflicts first: {}", unmerged);
std::process::exit(1);
} Type guard
fn has_unmerged_files(unmerged_output: &str) -> bool {
!unmerged_output.trim().is_empty()
} Try / catch
match sync::run(&repo_root, &cmd) {
Err(e) if e.to_string().contains("Unmerged files detected") => {
eprintln!("Conflicts pending. Run: git diff --name-only --diff-filter=U");
}
Err(e) => return Err(e),
Ok(v) => Ok(v),
} Prevention
- Always resolve and `git add` conflicts immediately after a conflicted merge; don't leave the repo half-resolved.
- Check `git status` for 'Unmerged paths' before running sync.
- Use `git merge --abort` when you don't intend to complete a conflicted merge.
- Add a pre-sync script that fails fast on unmerged entries.
When it happens
Trigger: Running `f sync` (the sync command) while the index holds unmerged (conflicted) entries — i.e., after `git diff --name-only --diff-filter=U` returns non-empty output. Note: an in-progress rebase/merge is caught earlier by a separate check ('Git operation in progress'), so this fires for lingering conflicted index entries.
Common situations: A previous pull/merge left conflicts the user resolved in the working tree but never `git add`-ed; the user aborted a merge uncleanly; a teammate-sync tool conflicted and the user retried sync instead of finishing the resolution.
Related errors
- Rebase conflict - manual resolution required
- Sync auto-fix cleared raw conflicts for {} but validation an
- Sync auto-fix cleared raw conflicts for {} but the merge is
- Sync auto-fix cleared raw conflicts for {} but the merge is
- Sync agent cleared raw conflicts for {} but validation and m
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/df365ae09e8ffc03.
Report an issue: GitHub.