Подтвердить что ты не робот

Как изменить путь к файлу в наборе патчей Git?

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

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

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

/
  ...many source files

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

4b9b3361

Ответ 1

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

Try:

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

Ответ 2

У меня недавно была аналогичная проблема. Моим решением было создать новый целевой репозиторий с подкаталогом 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 в целевом репозитории, т.е. все пути были соответствующим образом изменены.

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

Ответ 3

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

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), а затем выполнив его для всего файла ([email protected]).

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