Git format-patch per essere compatibile con svn?


96

Esiste un modo per ottenere una patch creata con git format-patch per essere compatibile con svn in modo da poterla inviare a un repository svn?

Sto lavorando a un repository svn su GitHub e desidero inviare le mie modifiche al repository principale. Devo creare una patch per fare ciò, tuttavia la patch non può essere applicata poiché git formatta quella patch in modo diverso da svn. C'è qualche segreto che non ho ancora scoperto?

AGGIORNAMENTO: Sebbene attualmente non esista uno script o un metodo git nativo per farlo, sono riuscito a trovare un post all'inizio di quest'anno su come farlo manualmente. Ho seguito le istruzioni e ho avuto successo nel far funzionare le mie patch git con svn.

Se qualcuno potesse provare a scrivere una sceneggiatura per ottenere questo risultato e contribuire al progetto git, sono tutti molto apprezzati.

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


Non riesco a farlo funzionare ... potresti pubblicare tutti i passaggi necessari? Grazie!
Mauricio Scheffer

1
Ciao Anthony. Prenderesti in considerazione di cambiare la risposta accettata con quella di Nicholas?
Simon East

Accetto il suggerimento di Simon, avere la risposta di Nicholas Smith come quella accettata gioverebbe a tutti in quanto è molto più pratico.
Albireo

Risposte:


90

Devo sempre cercarlo su Google, ma il modo in cui ho scoperto che funziona perfettamente (per me) è:

  • Crea la patch con git diff --no-prefix master..branch > somefile.diff, la parte master e branch sono opzionali, dipende da come vuoi ottenere le tue differenze.
  • Invialo ovunque e fai domanda con patch -p0 < somefile.diff.

Sembra sempre funzionare bene per me e sembra essere il metodo più semplice che abbia mai incontrato.


1
Questo è il modo canonico per generare patch compatibili con SVN con Git. Dovrebbe essere contrassegnato come risposta.
mloskot

--no-pagernon è più un'opzione per git diff.
nought101

Originariamente era stato pubblicato senza --no-pager, non sono sicuro del motivo per cui è stato aggiunto nella modifica. --no-pagerComunque ha sempre funzionato bene per me senza .
Nicholas Smith

2
Solo per un commit particolare: ha git diff --no-prefix 056a1ba5140 7d939289b80 >my.patchfunzionato per me (dove 056a1ba5140e 7d939289b80sono gli sha-1 del commit precedente e particolare in git).
Ed Randall

@ Lilás questo è un problema con SVN. Le differenze / patch in SVN non sono mai state in grado di gestire i file rimossi
Toofy


17

Ecco uno script di supporto per creare una differenza contro l'ultimo changeset svn e il commit dato: 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
Ho scoperto che il valore REV non è corretto se non stai lavorando con l'ultima revisione svn. L'ho corretto per usarlo in git svn infoquesto modo: REV=`git svn info | grep 'Last Changed Rev:' | sed -E 's/^.*: ([[:digit:]]*)/\1/'`
Sebastien Martin

1
Questo e spettacolare! Grazie mille. Ho dovuto fare una modifica perché funzionasse per importare le mie patch nel crogiolo di Fisheye, e cioè sostituire gli spazi prima di "(revisione" con una tabulazione.
Zugwalt

10

Probabilmente SVN non può comprendere l'output di git diff -p, ma puoi ricorrere alla forza bruta:

  1. Crea due cloni del tuo repo
  2. In un clone controlla le tue ultime cose
  3. Nell'altra verifica del clone, qualsiasi cosa sia equivalente all'upstream di svn. Se hai pianificato in anticipo, hai una copia di svn a monte sul suo ramo o hai taggato l'ultima versione di svn. Se non hai pianificato in anticipo, usa la data o gitk per trovare l'hash git SHA1 che più si avvicina allo stato svn.
  4. Ora calcola una vera patch eseguendo diff -ri due cloni.

12
Oppure segui i consigli di @ Nicholas-smith ed esegui git diff --no-prefix > somefile.diffnel tuo repository git e invialo a qualsiasi utente svn affinché applichi la patch patch -p0 < somefile.diffnella root del progetto.
DavidG

10

Subversion <1.6 non ha il supporto per le patch. Sembra che Subversion 1.7 consentirà di applicare patch e le estensioni git / hg al diff unificato siano nella nostra lista TODO.


4

È davvero una richiesta di funzionalità all'inizio del 2008

Linus Torvalds disse all'epoca:

Quindi direi che hai bisogno di qualcosa di più forte per dire "non fare un git diff", e questo dovrebbe anche disabilitare il rilevamento della ridenominazione come minimo.
Francamente, qualsiasi programma che sia così stupido da non accettare le attuali patch di git (cioè TortoiseSVN), allora dannatamente bene non dovrebbe disabilitarne solo la parte più banale. Dovremmo assicurarci di non abilitare nessuna delle estensioni piuttosto importanti:
anche se ToirtoiseSVN le ignorasse, se ignorarle significa che capisce male il diff, non dovrebbe essere consentito affatto.

Questo potrebbe essere il motivo

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

è stato introdotto in Git1.5.6 a maggio / luglio 2008 (non l'ho testato però)


0

Assicurati che le tue modifiche siano salvate e ribasate sopra il tuo ramo git locale, da git bash run:

git show --pretty >> myChangesFile.patch


0

La risposta accettata fornita da Nicholas funziona bene, tranne quando a) esistono file binari nel diff ob) stai lavorando in Windows Git e hai directory con spazi. Per risolverlo ho dovuto aggiungere un comando git diff annidato per ignorare i binari e il comando sed per sfuggire agli spazi. È un po 'complicato scrivere, quindi ho creato un alias:

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

Se poi digiti:

git svnpatch Feature123

... verrà creato un file patch Feature123.patch con le differenze tra la base di unione del master del ramo e il Feature123 del ramo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.