Git
version control
repository management
software development
programming

How to import existing Git repository into another?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Importing one Git repository into another is common when consolidating projects, creating monorepos, or migrating ownership between teams. The key decision is whether you need to preserve full commit history. If yes, use git subtree or a merge with unrelated histories. If no, copy files and commit once.

This guide focuses on history-preserving approaches that are safe for collaborative repositories.

Core Sections

git subtree places another repo under a subdirectory and keeps history.

bash
1cd target-repo
2git remote add source-repo https://example.com/source.git
3git fetch source-repo
4git subtree add --prefix=external/source source-repo main --squash

Use --squash for one combined commit, or omit it to retain full granular history.

2) Merge unrelated histories directly

bash
1cd target-repo
2git remote add source-repo https://example.com/source.git
3git fetch source-repo
4git merge source-repo/main --allow-unrelated-histories

This merges roots as-is and can produce many file conflicts if directories overlap.

3) Keep imported code in dedicated path

Always import under a stable folder to avoid collisions.

bash
mkdir -p vendors/source
# then use subtree prefix vendors/source

Clear directory boundaries simplify future updates.

4) Updating imported repository later

If using subtree, pull updates from source:

bash
git subtree pull --prefix=external/source source-repo main --squash

Document this workflow in repo docs so future maintainers can repeat it.

5) Verification checklist

After import, verify:

  • build/test still passes,
  • file paths are correct,
  • LICENSE/NOTICE obligations are preserved,
  • CI and tooling include imported directory as intended.

Do this before opening merge requests.

6) Production checklist for Git repository consolidation

A technically correct snippet is only the start. Before you consider this pattern complete, define operational acceptance criteria that match real usage. Pick one reliability metric, one correctness metric, and one performance metric, then test each with representative input. For example, reliability might be failure rate under retries, correctness might be output agreement with known-good fixtures, and performance might be p95 runtime under expected load. This moves the implementation from tutorial code to maintainable production behavior.

Create a short executable checklist so future contributors can validate changes quickly. Keep the checklist in version control and run it in CI whenever possible. A typical format is: validate environment assumptions, run a minimal happy-path example, run one malformed-input case, and confirm observable logs include enough context for troubleshooting. If external systems are involved, add a dry-run mode that avoids destructive actions while still exercising integration paths.

bash
1# Example validation flow
2make test
3make lint
4./scripts/smoke_check.sh

Operational ownership should also be explicit. Decide who responds when this component fails, what alert threshold should trigger investigation, and what rollback or fallback path is acceptable. Even a simple fallback plan, such as disabling a feature flag or reverting one deployment, can reduce incident duration significantly. For data-oriented workflows, add input and output sampling logs so regressions can be diagnosed without reproducing the full workload locally.

Finally, document constraints and non-goals. Clarify what the current approach handles well and what it does not attempt to solve. This prevents accidental misuse and repeated redesign debates. A concise limitations section plus automated checks is often enough to keep a small utility pattern dependable over time, even as team members and environments change.

Common Pitfalls

  • Importing at repo root and causing path conflicts.
  • Forgetting --allow-unrelated-histories when using direct merge approach.
  • Losing attribution/history by copying files manually when history is required.
  • Failing to document update strategy for future syncs.
  • Skipping license checks for imported third-party code.

Summary

For most teams, git subtree is the cleanest way to import one repository into another while retaining manageable history. Keep imported code in a dedicated subdirectory, verify integration effects, and document update commands. This keeps consolidation work repeatable and low-risk.


Course illustration
Course illustration

All Rights Reserved.