Git format-patch должен быть совместим с svn?

96

Есть ли способ получить патч, созданный с помощью git format-patch, чтобы он был совместим с svn, чтобы я мог отправить его в репозиторий svn?

Я работаю над репозиторием svn на github и хочу отправить свои изменения обратно в основное репо. Для этого мне нужно создать патч, однако патч нельзя применить, так как git форматирует патч иначе, чем svn. Есть какой-то секрет, который я еще не открыл?

ОБНОВЛЕНИЕ: хотя в настоящее время не существует сценария или собственного способа git для этого, мне все же удалось найти сообщение от ранее в этом году о том, как это сделать вручную. Я выполнил инструкции и мне удалось заставить мои патчи git работать с svn.

Если бы кто-то мог попытаться написать сценарий для достижения этой цели и внести свой вклад в проект git, я был бы очень признателен.

http://kerneltrap.org/mailarchive/git/2008/1/15/570308/thread#mid-570308

rip747
источник
Я не могу заставить его работать ... не могли бы вы опубликовать все необходимые шаги? Спасибо!
Маурисио Схеффер,
1
Привет, Энтони. Не могли бы вы изменить принятый ответ на ответ Николаса?
Саймон Ист
Я согласен с предложением Саймона, поскольку ответ Николаса Смита как принятый принесет пользу всем, поскольку он гораздо более практичен.
Albireo

Ответы:

90

Мне всегда приходится гуглить, но, как я обнаружил, отлично работает (для меня):

  • Создайте патч с помощью git diff --no-prefix master..branch > somefile.diff, основная часть и часть ветки не являются обязательными, зависит от того, как вы хотите получить свои различия.
  • Отправьте его куда угодно и примените с patch -p0 < somefile.diff.

Мне кажется, что это всегда хорошо работает и кажется самым простым методом, который я встречал.

Николас Смит
источник
1
Это канонический способ создания SVN-совместимого патча с помощью Git. Его следует отметить как ответ.
mloskot
--no-pagerбольше не вариант для git diff.
naught101 01
Первоначально он был опубликован без --no-pager, я не уверен, почему он был добавлен в редактирование. У меня это всегда нормально работало и без этого --no-pager.
Николас Смит
2
Только для конкретной фиксации: git diff --no-prefix 056a1ba5140 7d939289b80 >my.patchу меня сработало (где 056a1ba5140и 7d939289b80- это sha-1 предыдущей и конкретной фиксации в git).
Эд Рэндалл
@ Lilás, это проблема с SVN. Различия / патчи в SVN никогда не
позволяли
17

Вот вспомогательный сценарий для создания сравнения с последним набором изменений svn и заданным коммитом: http://www.mail-archive.com/dev@trafficserver.apache.org/msg00864.html

#!/bin/sh
#
# git-svn-diff
# Generate an SVN-compatible diff against the tip of the tracking branch
TRACKING_BRANCH=`git config --get svn-remote.svn.fetch | sed -e 's/.*:refs\/remotes\///'`
REV=`git svn find-rev $(git rev-list --date-order --max-count=1 $TRACKING_BRANCH)`
git diff --no-prefix $(git rev-list --date-order --max-count=1 $TRACKING_BRANCH) $* |
sed -e "s/^+++ .*/&    (working copy)/" -e "s/^--- .*/&    (revision $REV)/" \
-e "s/^diff --git [^[:space:]]*/Index:/" \
-e "s/^index.*/===================================================================/"
Кристоф
источник
1
Я обнаружил, что значение REV неверно, если вы не работаете с последней версией svn. Я исправил это, чтобы использовать git svn infoвместо этого: REV=`git svn info | grep 'Last Changed Rev:' | sed -E 's/^.*: ([[:digit:]]*)/\1/'`
Себастьян Мартин
1
Это круто! Огромное спасибо. Мне пришлось внести одно изменение, чтобы он работал для импорта моих патчей в тигель Fisheye, и это заключалось в замене пробелов перед «(ревизия» на вкладку вместо этого.
Zugwalt
10

SVN, вероятно, не может понять вывод git diff -p, но вы можете прибегнуть к грубой силе:

  1. Сделайте два клона вашего репо
  2. В одном клоне проверьте свои последние разработки
  3. В другом клонировании все, что эквивалентно svn upstream. Если вы заранее спланировали, у вас есть копия svn upstream в отдельной ветке, или вы отметили последнюю версию svn. Если вы не планировали заранее, используйте дату или gitk, чтобы найти хеш git SHA1, который наиболее точно соответствует состоянию svn.
  4. Теперь вычислите настоящий патч, пробежав diff -rдва клона.
Норман Рэмси
источник
12
Или просто следуйте совету @Nicholas-smith, запустите его git diff --no-prefix > somefile.diffв своем репозитории git и отправьте его любому пользователю svn, чтобы они применили патч patch -p0 < somefile.diffв корне проекта.
DavidG 06
10

Subversion <1.6 не поддерживает патчи. Похоже, что Subversion 1.7 позволит применять патчи, а расширения git / hg для унифицированного сравнения находятся в нашем списке TODO.

Берт Хейбен
источник
4

Это действительно запрос функции начале 2008 г.

Линус Торвальдс сказал тогда:

Поэтому я бы сказал, что вам нужно что-то более сильное, чтобы сказать «не делайте git diff», и это также должно как минимум запретить обнаружение переименования.
Откровенно говоря, любая программа, которая настолько глупа, что не принимает текущие исправления git (например, TortoiseSVN), то, черт возьми, не должна просто отключать самую тривиальную ее часть. Мы должны убедиться, что мы не включаем какие-либо из довольно важных расширений:
даже если ToirtoiseSVN проигнорирует их, если игнорирование их означает, что он неправильно понимает разницу, это не должно быть разрешено вообще.

Может быть поэтому

 git-format-patch: add --no-binary to omit binary changes in the patch.

был представлен в Git1.5.6 в мае / июле 2008 г. (хотя я его не тестировал)

VonC
источник
0

Убедитесь, что ваши изменения зафиксированы и переустановлены поверх вашей локальной ветки git, из git bash run:

git show --pretty >> myChangesFile.patch

Исмаил Хавайел
источник
0

Принятый ответ, предоставленный Николасом, работает нормально, за исключением случаев, когда а) двоичные файлы существуют в diff или б) вы работаете в Windows Git и имеете каталоги с пробелами. Чтобы решить эту проблему, мне пришлось добавить вложенную команду git diff, чтобы игнорировать двоичные файлы, и команду sed, чтобы избежать пробелов. Это немного громоздко писать, поэтому я создал псевдоним:

[alias]
svnpatch = "!f() { git diff --name-only --no-prefix master...$1 | grep -Ev \"\\.sdf|\\.Doc|\\.dll|\\.zip|\\.exe\" | sed 's_\\s_\\\\\\\\ _g'  | xargs git diff --no-prefix master...$1 > $1.patch; echo "Created $1.patch"; }; f"

Если вы затем наберете:

git svnpatch Feature123

... будет создан файл патча Feature123.patch с учетом различий между базой слияния мастера ветки и Feature123.

Леандро Гомес
источник