2013-05-24 3 views
3

По историческим причинам, которые я в настоящее время имеют следующую структуру проекта:Как объединить Git репозиториев с родственными ветвями

  • part0:

    • мастер
    • branch0
    • branch1
  • part1:

    • мастер
    • branch0
    • branch1

двоичные файлы проекта построены проверяя фиксаций на ту же дату из двух хранилищ, так что мне нужно например part0 - master (01.04.2013) и part1 - мастер (01.04.2013). Проверка деталей с разных дат не будет работать.

теперь я хочу, чтобы объединить эти два хранилища в одно целое, со структурой

  • гребень:
    • мастер
    • branch0
    • branch1

где фиксируется в мастер по дате фиксации от part0 - master и part1 - master.

Если я использую описанные схемы слияния, которые я нашел, я буду получать историю

part0 - мастер (все,) + часть1 - мастер (всё) потом

Так выписка из любая фиксация не будет работать, потому что либо я получаю только part0 (до слияния part1), либо я получаю новейшую part0-master с устаревшим part1-master.

+0

Не могли бы вы показать, какие «схемы слияния» вы использовали специально? –

+0

Я прочитал те, которые были найдены на http://stackoverflow.com/questions/1425892/how-do-you-merge-two-git-repositories – AlphaOne

+0

Я нашел этот пост для «объединения» двух ветвей, не имеющих общих файлов , в основном это относится и ко мне: http://stackoverflow.com/questions/5410742/how-can-two-branches-be-combined-into-a-single-branch-based-on-the-date- of-each Единственное, что осталось - это перемещение содержимого ветвей в отдельные каталоги, чтобы получить макет, который я упомянул в сообщении. – AlphaOne

ответ

2

Я, наконец, озадачил решение из ссылок, которые я разместил выше. Первая проблема в картинках:

 
repo0: A -- B -- C -- D -- E 
      \ 
       F -- G -- H 

repo1: A' -- B' -- C' -- D' -- E' 
       \ 
       F' -- G' -- H' 

Где фиксации А и А «соответствуют и получить проект в запущенном виде, вам необходимо оформить A и A» одновременно в соответствующие каталоги, скажет proj0 и proj1.

В репозиториях файлы и каталоги помещаются в /.

Мишени репозиторий должен выглядеть следующим образом:

 
A -- A' -- B -- B' -- C -- C' -- D -- D' -- E -- E' 
       \ 
        F -- F' -- G -- G' -- H -- H' 

Так я первый сделал шаг всего содержимого хранилищ совершает в заключительные каталоги с этим (конечно, в копии):

 
git clone --mirror path/repo0 repo0 
git filter-branch --tree-filter "(mkdir -p proj0 ; find * -maxdepth 0 ! -iname proj0 -exec mv {} proj0/ \;)" -- --all 

git clone --mirror path/repo1 repo1 
git filter-branch --tree-filter "(mkdir -p proj1 ; find * -maxdepth 0 ! -iname proj1 -exec mv {} proj1/ \;)" -- --all 

Теперь я мог слить два, первый ли я создать новое хранилище со старыми, как пульты дистанционного управления:

 
git init new 
git remote add proj0 path/repo0 
git remote add proj1 path/repo1 

git fetch --all 

Затем я объединяю ветвь по ветви, я просто назову их BranchE и BranchH. Поскольку они существуют с самого начала проекта, я должен был получить самый первый коммит, это делается с помощью фиктивной ветви:

 
git checkout -b dummy remotes/proj0/BranchE 
git checkout -b start `git log --topo-order --reverse | head -n 1 | sed s/"commit \(.*\)"/"\1"/` 
git checkout -b merge start 

git merge -m "merge" remotes/proj1/BranchE 
git rebase --onto start start merge 

git branch -D start 
git branch -D dummy 
git branch -m merge BranchE 

Я сделал то же самое для BranchH. Недостаток до сих пор есть, что histroy теперь выглядит так:

 
A -- A' -- B -- B' -- C -- C' -- D -- D' -- E -- E' 
\ 
    \ 
    \ 
    A' -- B -- B' -- F -- F' -- G -- G' -- H -- H' 

Последнее, что нужно сделать, это собрать воедино подобные части истории, это делается с помощью следующей команды:

 
git checkout BranchE 
git rebase `git log --oneline | grep "commit comment of last common commit B'" | sed -r s/"(^[a-f0-9]+) .*"/"\1"/` BranchH 

Et voilá, вы получите желаемый результат.