Подтвердить что ты не робот

Как объединить два несвязанных репозитория git, сохраняя историю

Я не знаю git очень хорошо.: -/

Фон

У меня есть два несвязанных репозитория документа на основе git, которые я хотел бы объединить в один репозиторий. Я хотел бы сохранить исходные временные метки (начиная с 2005 года) и отдельные истории файлов. В двух репозиториях нет ветвей, нет папок и нет совпадений с именами файлов.

В ASCII-стране это выглядит так:

REPO A    |-------------------------|
REPO B                    |===============|

Если перекрытие обозначает время.

Цель

Моя цель - "застегнуть молнию" на перекрывающиеся временные метки, чтобы два репозитория выглядели как одна непрерывная история:

REPO A+B  |-------------------==--=---============|

Что я пробовал

Опять же, я не очень хорошо знаю git, поэтому я мог что-то прикрутить.

Сначала я попытался добавить новое, меньшее репо в качестве удаленного для более крупного, более старого репо, извлечь изменения и зафиксировать результат. Я закончил все новые изменения репо, сложенные вместе в ветке после более старого репо:

MERGE  |-------------------------                 -|
                                 \===============/

Далее я попытался перезагрузить (с --committer-date-is-author-date), который, как я думал, будет работать, но вместо этого я получаю одну длинную историю фиксации, которая просто складывает два репозитория друг на друга.

REBASE |-------------------------===============|

Я не смог найти способ "переиграть" объединенную историю. Я действительно надеялся, что ответ будет ответом.

Ответы, которые я просмотрел

4b9b3361

Ответ 1

Хотя ответ @codeWizard был полезен, этот подход не сохранил временные метки так, как я хотел. Это привело меня к кроличьей дыре, которая помогла мне найти решение, хотя...

  • Создайте новый, пустой репозиторий

    git init
    
  • Добавьте и извлеките старые репозитории в качестве пультов

    git remote add -f oldRepoA ../oldRepoA
    git remote add -f oldRepoB ../oldRepoB
    
  • Экспортировать объединенную историю фиксации по меткам времени и хешу, вывести вывод на sort, отбросить временные метки через cut, а затем передать список хронологически отсортированных хэшей в xargs, который запускает оболочку script, чтобы экспортировать патч для каждого отдельного хеша, а затем немедленно применить патч к новому репо.

    git log --all --oneline --format="%at %H" | sort | cut -c12- | 
        xargs -I {} sh -c 
            'git format-patch -1 {} --stdout | 
             git am --committer-date-is-author-date'
    

--committer-date-is-author-date - ключ к сохранению исходных временных меток. Там может быть лучший способ сделать это, но это работает достаточно хорошо для моего использования!

Ответ 2

Вам нужно будет написать script, который сделает это.

Как это сделать

  • получить список всех ваших фиксаций временных меток на каждую ветку

    # print out the commits time stamp & sha-1 of each commit
    # do it for all your branches
    git log --oneline --format="%at %H"
    

    введите описание изображения здесь

  • Объедините 2 списка вместе и отсортируйте их по метке времени с помощью любого инструмента сортировки (возвышенного, unix-типа и т.д.)

  • Оформить новую ветку, начинающую первую фиксацию, имеющуюся в ваших файлах

    git checkout <first commit id>
    

    введите описание изображения здесь

  • Создайте новую ветку, начиная с этой фиксации

    git checkout -b <new_branch_name>
    
  • Переверните все остальные коммиты и используйте вишневый диск, чтобы привести их в свою ветку (script)

    git cherry-pick <next commit id>