Git Format-Patch, um SVN-kompatibel zu sein?

96

Gibt es eine Möglichkeit, einen mit git format-patch erstellten Patch so zu erstellen, dass er svn-kompatibel ist, damit ich ihn an ein svn-Repo senden kann?

Ich arbeite an einem SVN-Repo auf Github und möchte meine Änderungen an das Haupt-Repo zurücksenden. Ich muss dazu einen Patch erstellen, der Patch kann jedoch nicht angewendet werden, da Git-Formate anders patchen als svn. Gibt es ein Geheimnis, das ich noch nicht entdeckt habe?

UPDATE: Obwohl es derzeit kein Skript oder keine native Git-Methode gibt, habe ich es geschafft, einen Beitrag von Anfang dieses Jahres darüber zu finden, wie dies manuell erreicht werden kann. Ich habe die Anweisungen befolgt und hatte Erfolg damit, dass meine Git-Patches mit svn funktionieren.

Wenn jemand versuchen könnte, ein Skript zu schreiben, um dies zu erreichen und zum Git-Projekt beizutragen, wäre ich jeder sehr dankbar.

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

rip747
quelle
Ich kann es nicht zum Laufen bringen ... könntest du alle notwendigen Schritte posten? Vielen Dank!
Mauricio Scheffer
1
Hallo Anthony. Würden Sie erwägen, die akzeptierte Antwort auf Nicholas zu ändern?
Simon East
Ich stimme Simons Vorschlag zu, Nicholas Smiths Antwort als die akzeptierte zu haben, würde allen zugute kommen, da sie viel praktischer ist.
Albireo

Antworten:

90

Ich muss das immer googeln, aber ich habe festgestellt, dass es (für mich) perfekt funktioniert:

  • Erstellen Sie den Patch mit git diff --no-prefix master..branch > somefile.diff, der Master- und der Zweigteil sind optional, hängt davon ab, wie Sie Ihre Diffs erhalten möchten.
  • Senden Sie es überall hin und bewerben Sie sich mit patch -p0 < somefile.diff.

Es scheint immer gut für mich zu funktionieren und scheint die einfachste Methode zu sein, die mir begegnet ist.

Nicholas Smith
quelle
1
Dies ist der kanonische Weg, um einen SVN-kompatiblen Patch mit Git zu generieren. Es sollte als Antwort markiert werden.
Mloskot
--no-pagerist keine Option mehr für git diff.
naught101
Es wurde ursprünglich ohne gepostet --no-pager, ich bin nicht sicher, warum es in der Bearbeitung hinzugefügt wurde. Es hat immer gut für mich ohne funktioniert --no-pager.
Nicholas Smith
2
Nur für ein bestimmtes Commit: git diff --no-prefix 056a1ba5140 7d939289b80 >my.patchhat für mich gearbeitet (wo 056a1ba5140und 7d939289b80sind die sha-1 des vorherigen und bestimmten Commits in git).
Ed Randall
@ Lilás das ist ein Problem mit SVN. Diffs / Patches in SVN waren noch nie in der Lage, entfernte Dateien zu verarbeiten
Toofy
17

Hier ist ein Hilfsskript, um einen Unterschied zwischen dem neuesten svn-Änderungssatz und dem angegebenen Commit zu machen: http://www.mail-archive.com/[email protected]/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.*/===================================================================/"
Christoph
quelle
1
Ich habe festgestellt, dass der REV-Wert falsch ist, wenn Sie nicht mit der neuesten SVN-Version arbeiten. Ich habe es korrigiert, um es git svn infostattdessen so zu verwenden : REV=`git svn info | grep 'Last Changed Rev:' | sed -E 's/^.*: ([[:digit:]]*)/\1/'`
Sebastien Martin
1
Das ist fantastisch! Ich danke dir sehr. Ich musste eine Änderung vornehmen, damit meine Patches in Fisheyes Tiegel importiert werden konnten, und das war, um die Leerzeichen vor "(Revision" durch eine Registerkarte zu ersetzen.
Zugwalt
10

SVN kann die Ausgabe von wahrscheinlich nicht verstehen git diff -p, aber Sie können auf Brute Force zurückgreifen:

  1. Machen Sie zwei Klone aus Ihrem Repo
  2. Schauen Sie sich in einem Klon Ihre neuesten Sachen an
  3. Beim anderen Auschecken des Klons entspricht alles, was dem SVN-Upstream entspricht. Wenn Sie im Voraus geplant haben, haben Sie eine Kopie von svn upstream in einem eigenen Zweig oder Sie haben die letzte svn-Version markiert. Wenn Sie nicht im Voraus geplant haben, verwenden Sie das Datum oder den Gitk, um den Git-SHA1-Hash zu finden, der dem SVN-Status am nächsten kommt.
  4. Berechnen Sie nun einen echten Patch, indem diff -rSie die beiden Klone durchlaufen .
Norman Ramsey
quelle
12
Oder folgen Sie einfach den Ratschlägen von @ Nicholas-smith, führen Sie git diff --no-prefix > somefile.diffIhr Git-Repo aus und senden Sie es an einen beliebigen SVN-Benutzer, damit dieser den Patch patch -p0 < somefile.diffim Stammverzeichnis des Projekts anwenden kann .
DavidG
10

Subversion <1.6 unterstützt keine Patches. Es sieht so aus, als ob Subversion 1.7 das Anwenden von Patches ermöglicht und die Git / HG-Erweiterungen für Unified Diff auf unserer TODO-Liste stehen.

Bert Huijben
quelle
4

Es ist in der Tat eine Funktionsanforderung Anfang 2008

Linus Torvalds sagte damals:

Ich würde also argumentieren, dass Sie etwas Stärkeres brauchen, um zu sagen, dass Sie kein Git-Diff machen sollen, und dass dies auch die Erkennung von Umbenennungen auf ein Minimum beschränken sollte.
Ehrlich gesagt, jedes Programm, das so dumm ist, aktuelle Git-Patches (dh TortoiseSVN) nicht zu akzeptieren, sollte verdammt noch mal nicht einfach den trivialsten Teil davon deaktivieren. Wir sollten sicherstellen, dass wir keine der ziemlich wichtigen Erweiterungen
aktivieren : Selbst wenn ToirtoiseSVN sie ignorieren würde, wenn sie ignoriert werden, bedeutet dies, dass der Unterschied falsch verstanden wird, sollte dies überhaupt nicht zulässig sein.

Das mag der Grund sein

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

wurde im Mai / Juli 2008 in Git1.5.6 eingeführt (ich habe es jedoch nicht getestet)

VonC
quelle
0

Stellen Sie sicher, dass Ihre Änderungen auf Ihrem lokalen Git-Zweig festgeschrieben und neu basiert werden.

git show --pretty >> myChangesFile.patch

Ismail Hawayel
quelle
0

Die von Nicholas bereitgestellte akzeptierte Antwort funktioniert einwandfrei, außer wenn a) Binärdateien im Diff vorhanden sind oder b) Sie in Windows Git arbeiten und Verzeichnisse mit Leerzeichen haben. Um dies zu beheben, musste ich einen verschachtelten git diff-Befehl hinzufügen, um Binärdateien zu ignorieren, und einen sed-Befehl, um die Leerzeichen zu verlassen. Das Schreiben ist etwas umständlich, daher habe ich einen Alias ​​erstellt:

[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"

Wenn Sie dann Folgendes eingeben:

git svnpatch Feature123

... wird eine Patch-Datei Feature123.patch mit den Unterschieden zwischen der Zusammenführungsbasis von Zweigmaster und Zweig Feature123 erstellt.

Leandro Gomez
quelle