Как переместить файл из одного репозитория git в другой с сохранением истории


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

Последовательность команд, которой я начал следовать, была такой:
$ git clone source-repo/ source-repo-copy
$ cd source-repo-copy
$ git filter-branch --tree-filter 'test ! "$@" = "foo.txt" && 
  git rm --cached --ignore-unmatch $@ || true' --prune-empty

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

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

2 ответа:

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

Как показано здесь

~$ 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

Редактировать: для одного файла:

Сначала отфильтруйте каталог:

 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

Этого должно хватить.

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

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