Merging Git Repositories
Quick Start
Bash# Clone the primary (destination) repo git clone https://github.com/Jakeschincariol/replica-skill.git cd replica-skill # Add the second repo as a remote git remote add ecc https://github.com/affaan-m/ECC.git git fetch ecc --tags # Merge its history into a subdirectory to avoid collisions git merge ecc/main --allow-unrelated-histories --no-commit mkdir -p ecc git mv <conflicting-or-all-files> ecc/ 2>/dev/null || true git commit -m "Merge affaan-m/ECC into replica-skill under /ecc" # Clean up remote if no longer needed git remote remove ecc
Workflow
Progress:
- Step 1: Inspect both repos (default branches, structure, licenses)
- Step 2: Decide merge strategy (subdirectory merge vs. flat merge vs. subtree)
- Step 3: Clone destination repo and add source as remote
- Step 4: Fetch source history with tags
- Step 5: Merge with
--allow-unrelated-histories - Step 6: Resolve file path collisions (move into subdirectory if needed)
- Step 7: Resolve merge conflicts in overlapping files (README, LICENSE, CI configs)
- Step 8: Commit merge, verify build/tests pass
- Step 9: Push merged branch, open PR for review
- Step 10: Remove temporary remote, update docs referencing old repo locations
Step 1 — Inspect both repos
Bashgit ls-remote https://github.com/Jakeschincariol/replica-skill.git HEAD git ls-remote https://github.com/affaan-m/ECC.git HEAD
Check default branch names (main vs master) — mismatches need explicit branch refs in merge commands.
Step 2 — Choose a strategy
- Subdirectory merge (recommended default): preserves both histories, avoids file collisions, keeps provenance clear. Use
git subtreeor manualgit mvafter merge. - Flat merge: only safe if directory structures don't overlap and project intent is to fully unify as one codebase.
- Subtree merge (alternative to manual steps):
Bashgit subtree add --prefix=ecc ecc main --squash
Use --squash to avoid importing full history if it's not needed; omit it to preserve full commit history.
Step 5-6 — Merge and resolve collisions
--allow-unrelated-histories is required since the two repos share no common ancestor. If both repos have files at the same path (e.g. README.md, .gitignore), git will flag conflicts — resolve by renaming/moving one set of files into a subdirectory before committing.
Step 8 — Verify
Run the test suite / build of both original projects post-merge to confirm nothing broke from path changes or dependency conflicts (e.g. duplicate package.json, conflicting .github/workflows).
Examples
Example 1: Subtree merge preserving full history
Input: Two unrelated repos, destination wants ECC fully embedded under /ecc
Output:
Bashgit remote add ecc https://github.com/affaan-m/ECC.git git fetch ecc git merge -s ours --no-commit --allow-unrelated-histories ecc/main git read-tree --prefix=ecc/ -u ecc/main git commit -m "Merge ECC repo history under ecc/ prefix"
Result: replica-skill repo now contains ecc/ directory with ECC's full commit history attributed correctly in git log --follow.
Example 2: Simple unification (no subdirectory) Input: Both repos are skill definitions meant to become one flat skill library, no path overlaps Output:
Bashgit remote add ecc https://github.com/affaan-m/ECC.git git fetch ecc git merge ecc/main --allow-unrelated-histories # resolve any conflicts in shared files like README.md, LICENSE git commit
Result: Single flat repo with combined file trees and interleaved commit history.
Best Practices
- Always fetch
--tagsso release tags from the source repo aren't lost. - Prefer
git subtreeor manualread-tree --prefixwhen the two codebases are logically distinct — keeps blame/history traceable per original repo. - Back up both repos (or work on a new branch) before merging —
--allow-unrelated-historiesmerges are hard to cleanly undo once pushed. - Check LICENSE compatibility before merging — don't combine codebases with incompatible licenses without resolving that first.
- Update CI/CD configs (
.github/workflows,.gitlab-ci.yml) after merge since paths/triggers will change. - If unsure which strategy fits, default to subdirectory merge — it's the safest, most reversible option.
Common Pitfalls
- Forgetting
--allow-unrelated-histories— merge will fail with "refusing to merge unrelated histories." - Merging directly into
main/masterwithout a feature branch — do the merge on a branch, review, then merge via PR. - Ignoring file path collisions — silently overwriting one repo's
README.md,LICENSE, or config files with the other's. - Using
--squashon subtree merge when full commit history/attribution needs to be preserved. - Not verifying build/test suites post-merge — duplicate dependency files or conflicting configs often break CI silently.
- Leaving the temporary remote (
ecc) in the repo config indefinitely — clean it up after merge completes.