2

Our application is for legacy reasons spread over around 200 git repositories, and it's becoming a nightmare to handle, as each development always impacts several repositories, we loose a lot of time during integration on pull requests.

Hence we would like to migrate to one single git repository.

However, since several users are doing active development on those repositories, we don't want to loose any on-going development (branch) during the migration to one repository.

Since everything is clearer with a diagram, we would like to go from this flat structure:

 - ProjectA (branch master, dev1, fix1) 
 - ProjectB (branch master, dev1) 
 - ProjectC (branch master, dev2, fix1)

to this hierarchical structure, with only one main git repository:

Project (branch master, dev1, dev2, fix1)
 |- projectA
 |- projectB
 |- projectC

Git subtree merge seems like the way to go at first, we can easily import the Project A, B and C but only on one branch, master for instance. If I try to branch Project and import another branch like dev1, git read-tree rejects me because the files are already there...

How can I achieve this?

EDIT: this looks like a duplicate of this question, but keeping the branches is not discussed.

Community
  • 1
  • 1
foch
  • 1,039
  • 10
  • 21

1 Answers1

0

I've got a project with some little scripts facilitating git (and Redmine) usage. One of these adds a git subtree from a remote URL. The remote's name becomes the same as the subtree-merged project's. You can simply git fetch <remote> from there and you get all the branches of the subproject.

The project is on Github: https://github.com/subogero/redgit

The git-addsubtree script:

#!/bin/sh
url=$1
if [ -z "$url" ]; then
    echo Please specify subtree URL
    exit 1
fi
remote=$(echo $url | sed -r -e 's|^.+[:/]([^:/]+)$|\1|' -e 's/\.git$//')
echo Remote: $remote
branch=$2
[ -z "$branch" ] && branch=master
echo Branch: $branch
root=$(git rev-parse --show-toplevel)
prefix=$(pwd | sed -r -e "s:$root::" -e 's:^/(.+)$:\1/:')
subtree=${prefix}${remote}
echo Subtree: $subtree

git remote add -f $remote $url
[ $? = 0 ] || exit 0

git merge -s ours --no-commit $remote/$branch
if [ $? != 0 ]; then
    git remote rm $remote
    exit 2
fi

git read-tree --prefix=$subtree/ -u $remote/$branch
git commit -m "Add subtree $subtree from $url"

The project's Makefile copies it into /usr/lib/git-core so you can use it like git addsubtree <URL>. There is also a git-pullsubtree script, which allows you to pull from any branch of the subproject.

SzG
  • 12,333
  • 4
  • 28
  • 41
  • Thanks, but this leaves me with a hierarchy based on subtree, doesn't it? I'd like to have a simple git hierarchy at the end, without the need to know about subtree to use... Maybe I'm wrong, I'm merely learning about subtrees for this problem. – foch Nov 18 '14 at 17:59
  • You're only confronted with the subtree stuff when adding it or pulling from it. Otherwise it just behaves like a single repo. Submodules on the other hand are a real PITA. :-) – SzG Nov 18 '14 at 18:50