Last active
February 22, 2024 17:23
-
-
Save npryce/4380394 to your computer and use it in GitHub Desktop.
Merge history from one Git repository as the history of a subdirectory of another Git repository
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Usage: merge-to-subdir source-repo destination-repo subdir | |
# | |
# Merges the history of source-repo into destination-repo as the | |
# history of the subdirectory subdir. | |
# | |
# source-repo can be local or remote. | |
# destination-repo must be local to the machine. | |
# subdir can be a relative path, in which case intermediate | |
# directories are created as necessary. | |
# | |
# WARNING: I've only tested it when subdir has not existed within destination-repo. | |
set -e | |
function abspath() { | |
(cd $(dirname $1) && echo $PWD/$(basename $1)) | |
} | |
from=${1:?from repo not given} | |
to=$(abspath ${2:?to repo not given}) | |
subdir=${3:?subdir not given} | |
scratch=$(abspath $(basename $from .git)-scratch) | |
# Use the name of the subdirectory as the name of the remote when merging | |
remote=tmp-$subdir | |
# Create a copy of $from with contents moved to $subdir | |
rm -rf $scratch | |
git clone $from $scratch | |
cd $scratch | |
git filter-branch -f --prune-empty --tree-filter " | |
mkdir -p .tmp | |
mv * .tmp | |
if [ -f .gitignore ]; then mv .gitignore .tmp; fi | |
mkdir -p $(dirname $subdir) | |
mv .tmp $subdir | |
" -- --all | |
git gc --aggressive | |
cd .. | |
# Merge the copy of $from into $to | |
cd $to | |
git remote add $remote $scratch | |
git fetch $remote | |
git merge $remote/master | |
git remote rm $remote | |
git gc --aggressive | |
cd .. | |
# Clean up | |
rm -rf $scratch |
Usage: merge-to-subdir source-repo destination-repo subdir
Merges the history of source-repo into destination-repo as the history of the subdirectory subdir.
source-repo can be local or remote.
destination-repo must be local to the machine.
subdir can be a relative path, in which case intermediate directories are created as necessary.
I've only tested it when subdir has not existed within destination-repo.
I cant edit or raise a PR. can you add:
# assumes trunk is named master. change to main as required
and change the merge line to ->
git merge $remote/main --allow-unrelated-histories
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice, man! It would be even neater if you put some comments on how to use it, though :-)