Как переместить подкаталог из ветки в одном репозитории git в ветку в другом репозитории, сохранив историю? - PullRequest
2 голосов
/ 15 сентября 2011

У меня есть каталог, содержащий служебные библиотеки, которые были разработаны в ветке в одном git-репозитории, но оказывается, что они действительно принадлежат другому каталогу в другом проекте.Я прочитал и попытался Грег Байер Переместить файлы из одного Git-хранилища в другое, несколько раз сохраняя историю , но я не могу сохранить историю.Я пытаюсь сделать все это в ветвях, не являющихся основными, чтобы быть более безопасным, так как проект еще не готов к объединению с основным.

Вот что я делаю до сих пор:

Подготовка каталога «DirectoryName» для перемещения из ветви «SomeBranch» репозитория «Repo1»:

cd ~/Desktop
git clone git@github.com:username/Repo1.git
cd Repo1
git checkout -b SomeBranch origin/SomeBranch
git remote rm origin
git filter-branch --subdirectory-filter DirectoryName
mkdir DirectoryName
git mv *.php *.txt DirectoryName
git add DirectoryName
git commit -m "Stripped everything down to just DirectoryName."

Объединение каталога «DirectoryName» в «SomeBranch»"ветвь репозитория" Repo2 ":

cd ~/Desktop
git clone git@github.com:username/Repo2.git
cd Repo2
git checkout -b SomeBranch origin/SomeBranch
git remote rm origin
git remote add Repo1 ../Repo1/
git pull Repo1 SomeBranch
git remote rm Repo1

Когда я делаю это, я могу успешно разделить все до" DirectoryName "в Repo1 (и я также могу перетащить его в Repo2),но история потеряна.Если я сделаю git log -- DirectoryName или git log -- DirectoryName/SomeFile.php, я увижу только «Разобрать все до только DirectoryName».фиксации).Итак, очевидно, что с моей командой git filter-branch что-то не так, но я недостаточно знаком с ней, чтобы выяснить, что.

Любые предложения будут с благодарностью приняты, поскольку мы претерпеваем некоторые фундаментальные изменения в нашей базе кода., поэтому мне нужно будет делать это относительно часто некоторое время, пока все движется (но мы хотим сохранить историю).

Обновление: Как я уже упоминал git log -- DirectoryName (или git log -- DirectoryName/SomeFile.php; либо в Repo1, либо в Repo2) не отображаются никакие коммиты, кроме «Разобрать все до только DirectoryName».commit, но если я сделаю git log, я увижу правильную историю коммитов.Я просто неправильно использую git log или есть какое-то повреждение, из-за которого коммиты не отображаются корректно?

Другое обновление: git log -- DirectoryName отображает правильные коммиты в моем исходном немодифицированном Repo1, но не показывает правильные коммиты после git filter-branch (и я пробовал git filter-branch --subdirectory-filter DirectoryName -- --all, но это также сбивает с ветки "master" и нене кажется необходимым ... тот же результат).Тем не менее, история коммитов сохраняется после запуска git filter-branch, я вижу все это с git log master.., похоже, оно больше не относится к каталогу или файлам.Есть идеи?

Ответы [ 2 ]

2 голосов
/ 16 сентября 2011

Звучит так, как будто то, что вы сделали, хорошо, просто недоразумение о git log, которое вызывает проблемы.

git просто сохраняет состояние дерева при каждом коммите, а не записывает изменения, которые вывели дерево из состояния в одном коммите в следующий. Однако, если вы используете git log для поиска истории определенного файла или каталога, вы можете указать, чтобы он пытался искать переименования, когда история файла заканчивается. Вы можете сделать это с помощью:

git log --follow -- DirectoryName

Или, если это не сработает, попробуйте только один файл, например,

git log --follow -- DirectoryName/whatever.txt
0 голосов
/ 16 сентября 2011

Вот как я это сделаю:

  1. Создание патчей для всех коммитов, которые касаются файлов в подкаталоге:

    $ c=1; git log --format=%h -- subdir/*|tac|while read commit; do 
    git format-patch --stdout -1 $commit > $(printf '%04d' $c).patch
    c=$((c+1))
    done
    

    Обратите внимание, что если естьэто одиночные коммиты, которые касаются обоих файлов в поддиректории и за ее пределами, тогда патч также будет включать diff для другого файла, так что вам придется сократить эти фрагменты или выполнить ветку фильтра, чтобы удалить эти файлы, как только вы выполнили второй шагниже:

  2. Используйте git am, чтобы применить патчи к ветви в другом репо:

    $ git am *.patch
    
...