{"record":{"id":"d0538b161b5389ec","repo":"gitbutlerapp/gitbutler","slug":"cannot-merge-branch-name-merging-into-fetch-remote-name","errorCode":null,"errorMessage":"Cannot merge {branch_name}: merging into {fetch_remote_name}/{target_branch_name} resulted in conflicts.{detail} Rebase {branch_name} onto the target and resolve, then re-run `but merge {branch_name}`.","messagePattern":"Cannot merge (.+?): merging into (.+?)/(.+?) resulted in conflicts\\.(.+?) Rebase (.+?) onto the target and resolve, then re-run `but merge (.+?)`\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-api/src/land/merge.rs","lineNumber":102,"sourceCode":"    let mut merge = repo.merge_trees(\n        base_tree,\n        our_tree,\n        their_tree,\n        repo.default_merge_labels(),\n        merge_options,\n    )?;\n    if merge.has_unresolved_conflicts(unresolved) {\n        let paths: Vec<String> = merge\n            .conflicts\n            .iter()\n            .filter_map(|c| c.ours.location().to_str().ok().map(ToOwned::to_owned))\n            .collect();\n        let detail = if paths.is_empty() {\n            String::new()\n        } else {\n            format!(\" Conflicting paths: {}.\", paths.join(\", \"))\n        };\n        bail!(\n            \"Cannot merge {branch_name}: merging into {fetch_remote_name}/{target_branch_name} \\\n             resulted in conflicts.{detail} Rebase {branch_name} onto the target and resolve, then \\\n             re-run `but merge {branch_name}`.\"\n        );\n    }\n    let merged_tree = merge.tree.write()?.detach();\n\n    // Build the 2-parent merge commit. Parent order is `[target, feature]` so `--first-parent`\n    // mainline walks stay correct. `commit_signatures()` honors `gitbutler.gitbutlerCommitter`.\n    let (author, committer) = repo.commit_signatures()?;\n    let mut commit = gix::objs::Commit {\n        tree: merged_tree,\n        parents: [target_oid, feature_oid].into_iter().collect(),\n        author,\n        committer,\n        encoding: None,\n        message: format!(\"Merge branch '{branch_name}'\").into(),\n        extra_headers: Vec::new(),","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-api/src/land/merge.rs#L84-L120","documentation":"When landing, the library performs a trial merge of the branch into the remote target branch. If that merge produces conflicts, it cannot complete the landing automatically and refuses, listing conflicting paths and instructing the user to rebase first.","triggerScenarios":"Calling `but merge <branch>` where the branch's changes overlap/conflict with changes already on `{fetch_remote}/{target_branch}` — the internal `merge` tree operation returns conflicts with non-empty conflicting paths.","commonSituations":"A teammate merged competing changes to the same files after your branch diverged; long-lived branch that drifted far from the target; refactoring on both sides touching identical lines.","solutions":["Rebase the branch onto the latest target branch and resolve conflicts manually (`but pull --branch` / `git rebase origin/main`), then re-run `but merge <branch>`","Fetch first to make sure the conflict isn't against a stale view of the target, then retry","If conflicts are unwanted local edits, drop or rework the offending commits in the branch before landing"],"exampleFix":"# before\nbut merge feature-x\n# error: merging into origin/main resulted in conflicts. Conflicting paths: src/app.rs.\n\n# after\nbut pull --branch feature-x\ngit rebase origin/main  # resolve conflicts\nbut merge feature-x","handlingStrategy":"retry","validationCode":"// dry-run merge check\ngit fetch origin\nlet merge_ok = std::process::Command::new(\"git\")\n    .args([\"merge-tree\", &feature_oid.to_string(), &target_oid.to_string()])\n    .output()?.status.success();\nif !merge_ok { println!(\"rebase branch onto target first\"); }","typeGuard":null,"tryCatchPattern":"match land_result {\n    Err(e) if e.to_string().contains(\"resulted in conflicts\") => {\n        let detail = e.to_string();\n        rebase_and_resolve(extract_conflict_paths(detail));\n        retry_land();\n    }\n    other => other?,\n}","preventionTips":["Rebase frequently to keep branches close to the target","Fetch immediately before landing so conflicts are detected against fresh remote state","Keep branches short-lived and land them promptly to minimize drift"],"tags":["git","merge-conflict","landing","rebase"],"backgroundTag":"git-command-failed","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}