2011-09-15 3 views
2

У меня есть каталог, содержащий библиотеки утилиты, которые были разработаны в ветке в одном репозитории git, но, оказывается, они действительно принадлежат к другому каталогу в другом проекте. Я прочитал и несколько раз пытался использовать файл Moving Files from one Git Repository to Another, Preserving History Грега Байера, но я не могу сохранить историю. Я пытаюсь сделать все это в не-мастер-филиалах, чтобы быть более безопасным, так как проект все же не готов снова объединиться.Как переместить подкаталог из ветки в один репозиторий git ветке в другом хранилище, сохраняя историю?

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

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

cd ~/Desktop 
git clone [email protected]: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 [email protected]: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, но я недостаточно хорошо разбираюсь в ней, чтобы выяснить, что.

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

Update: Как я уже говорил git log -- DirectoryName (или git log -- DirectoryName/SomeFile.php, либо в Repo1 или Repo2) не показывает какой-либо совершает другое, что «Stripped все вниз только DirectoryName.» commit, но если я это сделаю git log Я вижу правильную историю фиксации. Я просто использую git log неправильно или есть некоторая коррупция, которая заставляет коммиты не отображаться правильно?

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

ответ

2

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

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

git log --follow -- DirectoryName 

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

git log --follow -- DirectoryName/whatever.txt 
+0

Да, это был он! Мне просто не хватало того факта, что 'git log' не будет автоматически следовать переименованию и тому подобное (и использование' git filter-branch' требует переименования, поскольку файлы затем попадают в корень дерева). – morgant

0

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

  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 
    

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

  2. Использование мерзавец утра применять патчи на ветке в другой репо:

    $ git am *.patch