Как я могу изменить путь к файлу в наборе патчей Git? - PullRequest
13 голосов
/ 30 июля 2010

Я работаю над репозиторием Git, который был извлечен из репозитория SVN с использованием git svn. Много месяцев назад репозиторий SVN был создан из исходного архива исходного (вышестоящего) проекта. Исходный проект имел файловую структуру, подобную следующей:

/
  COPYING
  README
  src/
      ...many source files...

Однако при создании репозитория SVN файлы README и т. Д. Были удалены, а приложение было создано с src/ в качестве корневого каталога, поэтому репозиторий теперь выглядит просто так:

/
  ...many source files

Я недавно преобразовал это репозиторий SVN в репозиторий Git. Исходный проект также находится в репозитории Git, и я хотел бы начать отслеживать изменения в основной ветке разработки, чтобы я мог легко увидеть, какие пользовательские изменения были внесены (и, если применимо, отправить исправления обратно в исходный проект). Я обнаружил коммит в репозитории верхнего уровня, из которого было создано наше репо SVN, так что теперь я хотел бы применить наши изменения к этому коммиту (в ветке). Я могу легко создать набор патчей, используя git format-patch, и применить их к клонированному репозиторию upstream ... за исключением того, что файловые структуры отличаются, поэтому патчи больше не указывают на правильные файлы. Есть ли способ применить исправления из git format-patch в каталог src/ в клонированном репо? (Обратите внимание, что патчи Git также содержат необходимую информацию, такую ​​как имя автора, адрес электронной почты и дата, которые я также хотел бы применить, и не нужно делать это вручную, т. Е. Возиться с GIT_AUTHOR_EMAIL и т. Д. )

Ответы [ 3 ]

6 голосов
/ 30 июля 2010

Мне кажется, что вы должны иметь возможность использовать git filter-branch для изменения путей в репозитории ранее клонированных из SVN.Затем, после того как все пути к файлам были обновлены, теперь вы можете просто использовать git format-patch для создания патчей, которые будут применяться к репозиторию вновь клонированных из восходящего потока.

Попробуйте:

git filter-branch --tree-filter 'mkdir src; git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files src'

3 голосов
/ 29 мая 2015

У меня недавно была похожая проблема.Мое решение состояло в том, чтобы создать новый целевой репозиторий с подкаталогом src, затем я создал набор исправлений в исходном хранилище:

/data/source-repository$ git format-patch -k --root

, затем эти исправления были применены к каталогу src вцелевой репозиторий:

/data/target-repository$ git am -k --committer-date-is-author-date --directory src ../source-repository/*.patch

Все патчи из исходного репозитория заканчиваются на src в целевом репозитории, т.е. все пути были соответствующим образом настроены.

Оттуда вы можете снова создавать патчи и импортироватьте в верхнем хранилище внутри ветви.

2 голосов
/ 30 июля 2010

Мне приходилось делать что-то очень похожее, некрасиво, но это было управляемо. Я закончил тем, что сделал:

git format-patch <commitish> --stdout > patches-for-upstream.mbox
$EDITOR patches-for-upstream.mbox

Внутри редактора я посмотрел, какие биты были общими и нужными были изменены, чтобы заставить "git am" делать то, что я хотел. Это оказалось три строки на файл, зафиксированный в каждом коммите:

  • строка, начинающаяся с diff --git a/path/to/file b/path/to/file
  • строка, начинающаяся с --- a/path/to/file
  • строка, начинающаяся с +++ b/path/to/file

На этом этапе редактору необходимо пройти через такие строки и внести необходимые изменения, чтобы все патчи применились к другому репозиторию Git.

Я сделал это в Vim, используя три быстро набираемых макроса, YMMV. Что-то вроде:

  • перейти к следующей строке, начиная с diff --git a/
  • перейти к этому слешу после a
  • измените путь так, как вам нужно, чтобы он был
  • перейти к слешу после b/ (перейти к следующему пробелу из файла a, затем /)
  • изменить путь так же, как
  • следующая строка (---)
  • перейти к a/
  • изменить путь
  • следующая строка (+++)
  • перейти к b/
  • изменить путь

Повторяйте, пока файл не будет готов. В Vim речь шла о том, чтобы один раз вставить его в макрос (qq<long string of commands>q), попробовать один раз (@q), а затем сделать это для всего файла (999@q).

Сохраните файл, зайдите в другой репозиторий Git и попробуйте git am его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...