2012-05-09 3 views
36

Я пытаюсь переместить один файл (назовем его foo.txt) из одного репозитория в другой (несвязанный) репозиторий, сохраняя его историю. ebneter's question показывает, как это сделать для подкаталога. taw's question содержит несколько советов и предложений, но не пошаговую процедуру для подражания. jkeating's question выглядел многообещающим, но не работал для меня. Поисковые запросы Google оказались пустыми для данного конкретного случая использования. То, что я ищу, - это четкая последовательность команд для этого.Как перенести файл из одного хранилища git в другой при сохранении истории

Последовательность команд я начал следить была такова:

$ git clone source-repo/ source-repo-copy 
$ cd source-repo-copy 
$ git filter-branch --tree-filter 'test ! "[email protected]" = "foo.txt" && \ 
    git rm --cached --ignore-unmatch [email protected] || true' --prune-empty 

Логика моей команды фильтра является git rm все файлы, которые не foo.txt. Я добавил команду || true в команду, чтобы заставить ее иметь нулевое возвращаемое значение, чтобы удовлетворить ветви фильтра.

Мое намерение состояло в том, чтобы установить source-repo-copy в качестве удаленного для моего целевого репозитория (target-repo), и при условии, что git filter-branch отфильтровывает все, кроме foo.txt, извлекает и объединяет source-repo-copy в target-repo , К сожалению, команда git filter-branch, казалось, не имела никакого эффекта. Он работал без ошибок и, казалось, измельчался через 600+ коммитов в source-repo, но когда он закончил, git log и файлы в копии source-repo выглядели одинаково. Должны ли отсутствовать все файлы, кроме foo.txt, и все фиксации, которые не трогали его, исчезли из журнала?

На данный момент я не знаю, как действовать. Какие-либо предложения?

+2

Возможный дубликат [Как перемещать файлы из одного git-репо в другой (не клон), сохраняя историю] (http://stackoverflow.com/questions/1365541/how-to-move-files-from-one -git-repo-to-another-not-a-clone-preserve-history) – tripleee

ответ

31

Это сработало для меня, но с целым каталогом.

Как показано here

~$ cd neu 
~/neu$ git filter-branch --subdirectory-filter FooBar HEAD 
~/neu$ git reset --hard 
~/neu$ git remote rm origin 
~/neu$ rm -r .git/refs/original/ 
~/neu$ git reflog expire --expire=now --all 
~/neu$ git gc --aggressive 
~/neu$ git prune 
~/neu$ git remote add origin git://github.com/FooBar/neu.git 

EDIT: Для одного файла:

Фильтр каталога первый:

git filter-branch --prune-empty --subdirectory-filter myDirectory -- --all 

Фильтр единственный файл:

git filter-branch -f --prune-empty --index-filter "git rm --cached --ignore-unmatch $(git ls-files | grep -v 'keepthisfile.txt')" 

Есть некоторые очистки:

git reset --hard 
git gc --aggressive 
git prune 

Это должно сделать это.

+1

Да, примеры '-subdirectory-filter' кажутся простыми, но я ищу для перемещения одного файла, а не подкаталога. Есть идеи с этим? –

+0

попробуйте сначала на testrepo, новое решение работает для меня – blang

+1

Я отфильтровал каталог, как вы предложили, используя '.' вместо 'myDirectory'. Я был оставлен с нулевыми файлами в каталоге (только .git). 'git log' показал только коммиты слияния (12 из них). Затем я отфильтровал один файл.Я получил ошибки, потому что 'git rm' вызывался с пустым списком параметров. Я добавил '|| true' в конце команды, чтобы предотвратить жалобы git rm на прерывание фильтра. После этого все еще нулевые файлы и только 4 слияния совершаются в 'git log'. Я закончил с 'git reset/gc/prune', но не увидел никаких изменений. Думаю, это не сработало. :(Я рад, что попробовал это на тестовом репо. :) –

0

См. Мой ответ на аналогичный вопрос о перемещении папок, где я также отвечу, как переместить один файл. https://stackoverflow.com/a/24693985/464618

Я пробовал копировать его здесь, но кажется, что это запрещено, поскольку оно было удалено.

+3

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