Conflicted merge after a directory rename on a shared feature branch
A team of five is two days from a release. feature/payments was cut from main six weeks ago and now has 11 commits. During that time main gained 40 commits, including one that moved src/billing/ to src/payments/ and updated imports, and another that edited src/billing/invoice.rb. The feature branch also edits src/billing/invoice.rb and adds src/billing/retry.rb. A developer runs git merge main and gets four conflicts: two modify/delete conflicts for files under src/billing/, one content conflict in invoice.rb, and one in a spec file. The feature branch is shared by two developers, and main requires a merge commit for audit purposes. The release manager wants the conflicts resolved without resurrecting the old directory or dropping the feature's retry logic. The repository has no rerere cache enabled.
1. Explain why Git reports modify/delete conflicts here even though the feature branch never deleted those files, and give the commands you would use to confirm which old paths map to which new paths before resolving anything.
Read the worked answer
Git does not track renames; it infers them at diff and merge time. The feature branch edited paths under src/billing/, while main deleted those paths and added src/payments/. If similarity is below the rename threshold, or there are several candidate paths, Git reports delete on one side and modify on the other: a modify/delete conflict. Do not resolve by blindly keeping the feature side, because that recreates the old directory.
Inspect the index stages and rename candidates before completing the merge:
git merge --no-commit main
git status
git ls-files -u
git diff --name-status -M main...HEAD
git diff --name-status -M main..HEAD
git log --follow --oneline -- src/payments/invoice.rb
git ls-files -u shows stages 1, 2 and 3 for conflicted paths. -M makes rename detection explicit. Map old to new with git log --follow and by comparing git show main:src/payments/invoice.rb with the feature version. Then decide per file: merge the content into src/payments/invoice.rb, add retry.rb at src/payments/retry.rb, and remove the old paths with git rm -r src/billing. Before committing, run git diff --cached --stat and git diff --cached -M to confirm no old paths remain. This preserves both the feature logic and the directory move.
2. The team debates rebasing `feature/payments` onto `main` instead of merging. Given the shared branch, the audit requirement, and the rename, recommend an approach and describe how you would validate the final tree before committing the merge.
Read the worked answer
Recommend merging main into feature/payments, not rebasing. The branch is shared by two developers, so a rebase rewrites commits they may have based work on and requires a coordinated force-push. main also requires a merge commit for audit. A rebase would produce linear feature history but would not satisfy that audit rule and would make the conflict resolution harder to review as a distinct event.
Use the merge:
git switch feature/payments
git merge main
# resolve modify/delete by adding new paths and removing old ones
git add src/payments/invoice.rb src/payments/retry.rb
git rm -r src/billing
git diff --check
git commit
Avoid -X ours or -X theirs: ours would drop all main changes to conflicting files, and theirs would drop the feature's edits. Resolve content manually. Validate the tree against both parents:
git diff main...HEAD -- src/payments
git ls-tree -r --name-only HEAD | grep src/billing
git log --graph --oneline --decorate -8
The grep should return nothing. Run the payment tests from the merged tree, then push the merge commit. If review later finds the retry logic missing, fix it in a follow-up commit rather than amending a pushed merge.
3. After resolving, a file from the old `src/billing` directory reappears in the merge commit. What is the likely cause and how do you correct it without redoing the merge?
Read the worked answer
If a src/billing file reappears, the deletion was not staged in the merge index, or a path was reintroduced by an automatic rename resolution and then committed. Check:
git ls-files src/billing
git status --short
git show --stat --summary HEAD
If the merge is not pushed, correct it in place:
git rm -r src/billing
git commit --amend --no-edit
--amend rewrites the merge commit, so it is acceptable only on the unpushed feature branch. The audit requirement concerns main, not preserving every intermediate feature-branch SHA. If the merge was already pushed and others have fetched it, do not amend. Add a corrective commit that removes the old paths and records why. In either case, verify with git ls-tree -r --name-only HEAD | grep '^src/billing/' and run the tests. Also check that src/payments/retry.rb exists; a common mistake is deleting the old directory but forgetting to add the feature's new file at the renamed path.