I was reading Reddit threads about Git annoyances — not big architecture debates, just the little things that waste time. One kept coming up: merge conflicts that are only import lines at the top of a Python file.
Someone on one branch adds import os. Someone else adds import math. Same file, same place. Git treats it like a real conflict, and you end up deleting conflict markers by hand even though you just want both imports.
The cover image is a quick sketch I made in Excalidraw while figuring out the flow: conflict in → one command → clean imports out.
What I looked at
Before writing anything, I checked how this is usually handled:
- GitHub's official guide walks you through opening the file and fixing markers by hand. That is the right approach for real logic conflicts. It is just slow when the conflict is only imports.
- Common Stack Overflow answers push
git checkout --oursor--theirs. That keeps one side and throws away the other — so you can delete an import your teammate still needs. - Formatters like isort, ruff, and Black help keep imports tidy, but they fail while conflict markers are still in the file.
- There are heavier tools too (structural merge drivers, LLM helpers) if you want that trade-off.
I could not find a small local command that only handles this case, so I wrote one.
The tool
pip install import-resolve-cli
import-resolve-cli
Before (Git still conflicted):
import json
<<<<<<< HEAD
import os
=======
import math
>>>>>>> feature
print(json.dumps({"ok": True}))
After (both imports kept, markers gone):
import json
import math
import os
print(json.dumps({"ok": True}))
If you run it with no file paths, it asks Git for conflicted .py files. There is also --dry-run, --check, and an optional --install-hook that registers a merge driver for this repo only (not your global Git config).
Limits
It only rewrites a conflict block when every non-blank line on both sides is a single-line import / from or a comment. Anything else is skipped with a reason — including multiline imports, indented imports, and logic mixed into the same block. Conflicts further down the file stay for you.
That is intentional. I wanted help with the mechanical part, not a tool that tries to merge real code for me.
| Out of scope | Why |
|---|---|
| Business-logic conflicts | Needs human intervention |
| Multiline import blocks | Too easy to corrupt; skipped with a warning |
| Full isort/ruff style | Run your formatter after; sorting here is simple |
| JS/TS imports | Possible later |
| Config files | No config by design |
Links
import-resolve-cli
Resolve Git merge conflicts that only touch Python import lines.
$ git merge feature-branch
CONFLICT (content): Merge conflict in app.py
$ import-resolve-cli
[ok] app.py: resolved 1 import conflict
Install
pip install import-resolve-cli
Python 3.9+, no runtime dependencies.
Example
Two branches each added an import. Git left this:
import json
<<<<<<< HEAD
import os
=======
import math
>>>>>>> feature-a
print(json.dumps({'ok': True}))
After import-resolve-cli:
import json
import math
import os
print(json.dumps({'ok': True}))
Same example as files in docs/examples/.
Usage
import-resolve-cli # every conflicted .py file reported by git
import-resolve-cli app.py utils.py # specific files
import-resolve-cli --dry-run # print the diff, write nothing
import-resolve-cli --check # exit 1 if conflict markers remain
Exit codes: 0 done, 1 conflicts left for you, 2 usage…
Python 3.9+, no runtime dependencies. If you try it on a real conflict and something looks off, I would be glad to hear about it in an issue.
If this saves you a few minutes, a star on the repo helps others find it!
Top comments (0)