Keywords: Git merge | Repository import | Version control
Abstract: This article provides a comprehensive guide on importing an independent Git repository into another as a subdirectory while preserving complete commit history. Through analysis of three main approaches: branch merge strategy, subtree merge strategy, and git-subtree tool, it focuses on the best practices based on branch merging. The article includes detailed step-by-step instructions, code examples, and principle analysis to help developers understand Git merging mechanisms and avoid common pitfalls.
Introduction
In modern software development, there is often a need to integrate independent code repositories into a single project. This article addresses the requirement of completely importing a Git repository named XXX into the YYY repository as a ZZZ subdirectory, providing detailed technical solutions.
Problem Analysis
The original directory structure contains two independent Git repositories:
├── XXX
│ ├── .git
│ └── (project files)
└── YYY
├── .git
└── (project files)The goal is to import the XXX repository as subdirectory ZZZ into the YYY repository while preserving all commit history, ultimately forming:
YYY
├── .git <-- Now contains XXX's change history
├── ZZZ <-- Originally XXX repository
│ └── (project files)
└── (project files)Core Solution: Branch Merge Strategy
Based on the highest-rated answer, we adopt the branch merge approach, which is straightforward and reliable.
Implementation Steps
Execute the following operations in the YYY repository:
git remote add other /path/to/XXX
git fetch other
git checkout -b ZZZ other/master
mkdir ZZZ
git mv stuff ZZZ/stuff # Repeat for each file/directory
git commit -m "Moved files to ZZZ directory"
git checkout master
git merge ZZZ --allow-unrelated-histories # Add ZZZ/ to master
git commit
git remote rm other
git branch -d ZZZ # Delete temporary branch
git push # Push if remote existsPrinciple Analysis
The core of this method lies in creating temporary branches for file reorganization:
- Add Remote Reference: Use
git remote addto add the XXX repository as a remote, establishing a connection bridge - Fetch Historical Data:
git fetchdownloads all commit records from the XXX repository without merging - Create Working Branch: Create temporary branch ZZZ based on XXX's master branch for file reorganization
- File Relocation: Use
git mvcommand to move files to target subdirectory while maintaining Git history tracking - Strategy Merge: Use
--allow-unrelated-historiesparameter to allow merging of unrelated histories
Alternative Approach Comparison
Subtree Merge Strategy
Another effective method is subtree merging:
git remote add XXX_remote <path-or-url-to-XXX-repo>
git fetch XXX_remote
git merge -s ours --no-commit --allow-unrelated-histories XXX_remote/master
git read-tree --prefix=ZZZ/ -u XXX_remote/master
git commit -m "Imported XXX as subtree"The advantage of this method is the ability to easily track upstream changes:
git pull -s subtree XXX_remote mastergit-subtree Tool
For Git version 1.7.11 and above, the official git-subtree tool can be used:
git subtree add -P ZZZ /path/to/XXX.git masterThis tool encapsulates the complexity of subtree merging, providing a more user-friendly interface.
Technical Points Analysis
History Record Handling
All methods face the same history display issue: in merged files, commit records from the original XXX repository won't show in git log ZZZ/file. Use:
git log --follow -- fileto track the complete change history of files.
Version Compatibility
For Git versions before 2.9, the git merge command doesn't require the --allow-unrelated-histories parameter. Newer versions introduced this parameter to prevent accidental merging of unrelated projects.
Best Practice Recommendations
Based on practical application experience, we recommend:
- Backup Original Repositories: Ensure complete backups before performing any merge operations
- Test Environment Validation: Verify the entire process in a non-production environment first
- Clean Temporary Resources: Promptly delete temporary branches and remote references after merge completion
- Documentation Recording: Detail the purpose and scope of merge operations in commit messages
Conclusion
Through the branch merge strategy, we can efficiently integrate independent Git repositories as subdirectories of the main project while completely preserving historical records. This method avoids the complexity of submodules and provides a more direct code management solution. Developers should choose the most suitable integration strategy based on specific requirements and technical environment.