I have already written how useful a tool git filter-repo is for cleaning repositories. I made some extensive use of the newfound knowledge since to undo some previous bad decisions in my private repositories.
Here's a list of commands for merging project-a
into project-b
for a
reference.
Optional: Revert git LFS
Depending on the complexity of the project, you might optionally consider
reverting the LFS status of the files in the project-a
repository:
git lfs migrate export --include="*" --everything
Check if there are really no files in with the Large File Storage (LFS) status:
git lfs ls-files
It might be even safe now to remove any mention of the .gitattribute
file, which is used to store information about which files should LFS
track:
git filter-repo --path .gitattributes --invert-paths
You can migrate import LFS files back later.
Preparation: Directory structure
Start by moving a project-a
one level deeper in the directory structure
while preserving git history using a
path shortcut:
cd path/to/project-a
git-filter-repo --to-subdirectory-filter $(basename "$PWD")
Confirm by running ls
. Only project-a
directory should pop up.
Merge
Now the project-a
is ready to be integrated into the project-b
:
cd /path/to/project-b
git remote add project-a /path/to/project-a
git fetch project-a --tags
git merge --allow-unrelated-histories project-a/master
git remote remove project-a
After confirming a merge commit, the project-a
directory should now be
contained inside a project-b
. To get rid of the merge commit, rebase
interactively:
git rebase --interactive HEAD~
Confirming a git rebase dialog without editing anything (every line should
start with a pick
keyword) should be sufficient.
Optional: Re-sign every commit
If you want to publish the cleaned repository publicly, it might be
worthwhile to add your GPG signature to the commits, as changing history
with a rebase or directly via a git-filter-repo
tool can mess with
signatures.
Note: before proceeding with this step, make sure that you are the sole contributor to the repository. Also, if the repository is very old, the email address associated with the commit might need updating, for instance using with
git-filter-repo --use-mailmap
command.
I have written about re-signing previous commits, so check it out. In short:
git rebase --exec 'git commit --amend --no-edit --no-verify -S' -i --root
git rebase --committer-date-is-author-date -i --root
The merged repository should be ready to be pushed to it's shiny place!