Skip to content

Instantly share code, notes, and snippets.

@eschalkargans
Created January 3, 2024 08:59
Show Gist options
  • Save eschalkargans/318d83e58d63d83454d1f8a497786a8d to your computer and use it in GitHub Desktop.
Save eschalkargans/318d83e58d63d83454d1f8a497786a8d to your computer and use it in GitHub Desktop.
Merge two Git repositories

repository_merging.md

Merge two Git repositories

The following instructions are freely inspired from this blog article: https://ahmadatwi.me/2016/04/07/how-to-move-a-git-repository-to-subdirectory-of-another-repository/

Replace the various variable definitions commented with CHANGEME with values suited to your needs.

Bash snippets can be executed sequentially in reading direction.

Goal

Initial State

We have 2 repositories: source and target, containing various files. We want to make source a part of target, while keeping its history.

Final State

We have 1 repository, source, containing two subfolders:

  • source_folder containing the original contents of the source repo
  • target_folder containing the original contents of the target repo

The master branch is presupposed to be up-to-date and the desired state in the following instructions.

Step 0: Bash functions to move a repository's content into a subfolder

Move contents of the repository into a subfolder

Note: --almost-all or -A is similar to -a, except . and .. are not displayed. Note: the --ignore flag is used to ignore the freshly created folder, in order not to try to copy it into itself.

move_repository_contents_to_subfolder() {
    local FOLDER=$1

    mkdir ${FOLDER}
    mv $(ls --almost-all --ignore=.git --ignore=${FOLDER}) ${FOLDER}
}

prepare_repository() {
    STARTING_BRANCH_NAME=$1
    BRANCH_NAME=$2
    SUBFOLDER_NAME=$3

    git checkout ${STARTING_BRANCH_NAME}
    git checkout -b ${BRANCH_NAME}

    move_repository_contents_to_subfolder ${SUBFOLDER_NAME}

    git add .
    git commit -m "Moved repository contents into a subfolder (${SUBFOLDER_NAME})"
}

# CHANGEME
SOURCE_REPOSITORY_PATH=
# CHANGEME
TARGET_REPOSITORY_PATH=
# CHANGEME
STARTING_BRANCH_NAME=master

Step 1: Prepare the source repository

ℹ️ The following commands are performed in the source repository.

# Step 1

# CHANGME
SOURCE_BRANCH_NAME=source__prepare_repository
# CHANGME
SOURCE_SUBFOLDER_NAME=source_subfoldere_name
# CHANGME
SOURCE_STARTING_BRANCH_NAME=${STARTING_BRANCH_NAME}

cd ${SOURCE_REPOSITORY_PATH}
prepare_repository ${SOURCE_STARTING_BRANCH_NAME} ${SOURCE_BRANCH_NAME} ${SOURCE_SUBFOLDER_NAME}
git push --set-upstream origin $(git branch --show-current)

Step 2: Prepare the target repository

ℹ️ The following commands are performed in the target repository.

This step is similar to Step 1.

# Step 2

# CHANGME
TARGET_BRANCH_NAME=target__prepare_repository
# CHANGME
TARGET_SUBFOLDER_NAME=frontend
# CHANGME
TARGET_STARTING_BRANCH_NAME=${STARTING_BRANCH_NAME}

cd ${TARGET_REPOSITORY_PATH}
prepare_repository ${TARGET_STARTING_BRANCH_NAME} ${TARGET_BRANCH_NAME} ${TARGET_SUBFOLDER_NAME}
git push --set-upstream origin $(git branch --show-current)

Step 3: Merge source into target

ℹ️ The following commands are performed in the target repository.

Go on your source repo on github and copy the remote location, eg git@github.com:organization/project-name.git. The following operations will merge the source repository into the target one. This is why the Step 1 and 2 were done: the move of the contents into subfolders were performed beforehand, so that the source repo could be easily merged into the target on without further operations.

# Step 3

# CHANGME
REMOTE_LOCATION=git@github.com:organization/project-name.git

git remote add -f source_remote ${REMOTE_LOCATION}
git fetch source_remote
git merge source_remote/${SOURCE_BRANCH_NAME} --allow-unrelated-histories
git remote rm source_remote

git push

Conclusion

You can verify that the history was kept by running a git log.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment