Git format-patch, aby był kompatybilny z svn?

96

Czy jest jakiś sposób, aby uzyskać łatkę utworzoną za pomocą git format-patch, aby była kompatybilna z svn, abym mógł przesłać ją do repozytorium svn?

Pracuję nad repozytorium svn na github i chcę przesłać zmiany z powrotem do głównego repozytorium. Aby to zrobić, muszę utworzyć łatkę, jednak łata nie może być zastosowana, ponieważ git formatuje tę łatkę inaczej niż svn. Czy jest jakiś sekret, którego jeszcze nie odkryłem?

AKTUALIZACJA: Chociaż obecnie nie istnieje żaden skrypt ani natywny sposób gita, aby to zrobić, udało mi się znaleźć post z początku tego roku o tym, jak ręcznie to zrobić. Postępowałem zgodnie z instrukcjami i udało mi się uzyskać moje poprawki git do pracy z svn.

Gdyby ktoś mógł spróbować napisać scenariusz, aby to osiągnąć i wnieść wkład w projekt git, każdy byłby bardzo doceniony.

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

rip747
źródło
Nie mogę zmusić go do pracy ... czy mógłbyś opublikować wszystkie potrzebne kroki? dzięki!
Mauricio Scheffer
1
Cześć Anthony. Czy rozważyłbyś zmianę zaakceptowanej odpowiedzi na Nicholasa?
Simon East,
Popieram sugestię Simona, mając odpowiedź Nicholasa Smitha jako akceptowaną, przyniosłaby korzyści wszystkim, ponieważ jest znacznie bardziej praktyczna.
Albireo

Odpowiedzi:

90

Zawsze muszę to Google, ale sposób, w jaki odkryłem, że działa idealnie (dla mnie), to:

  • Utwórz łatkę za pomocą git diff --no-prefix master..branch > somefile.diff, część główna i rozgałęziona są opcjonalne, w zależności od tego, jak chcesz uzyskać różnice.
  • Wyślij to gdziekolwiek i aplikuj za pomocą patch -p0 < somefile.diff.

Zawsze wydaje mi się, że działa dobrze i wydaje się być najprostszą metodą, z jaką się spotkałem.

Nicholas Smith
źródło
1
To jest kanoniczny sposób generowania łatek kompatybilnych z SVN za pomocą Git. Powinien być oznaczony jako odpowiedź.
mloskot
--no-pagernie jest już opcją dla git diff.
naught101
Pierwotnie został opublikowany bez --no-pager, nie jestem pewien, dlaczego został dodany w edycji. I tak zawsze mi się --no-pagerto udawało.
Nicholas Smith
2
Tylko dla konkretnego zatwierdzenia: git diff --no-prefix 056a1ba5140 7d939289b80 >my.patchdziałało dla mnie (gdzie 056a1ba5140i 7d939289b80są sha-1 poprzedniego i konkretnego zatwierdzenia w git).
Ed Randall
@ Lilás to jest problem z SVN. Różnice / poprawki w SVN nigdy nie były w stanie obsłużyć usuniętych plików
Toofy
17

Oto skrypt pomocniczy do tworzenia różnic z najnowszym zestawem zmian svn i podanym zatwierdzeniem: 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
źródło
1
Okazało się, że wartość REV jest niepoprawna, jeśli nie pracujesz z najnowszą wersją svn. Poprawiłem to tak, aby git svn infozamiast tego używał : REV=`git svn info | grep 'Last Changed Rev:' | sed -E 's/^.*: ([[:digit:]]*)/\1/'`
Sebastien Martin,
1
To jest niesamowite! Dziękuję bardzo. Musiałem wprowadzić jedną zmianę, aby działała podczas importowania moich poprawek do tygla Fisheye, a chodziło o zastąpienie spacji przed "(wersja" tabulatorem.
Zugwalt
10

SVN prawdopodobnie nie może zrozumieć wyniku działania git diff -p, ale możesz użyć brutalnej siły:

  1. Zrób dwa klony swojego repozytorium
  2. W jednym klonie sprawdź swoje najnowsze rzeczy
  3. W drugim checkoucie klonów cokolwiek jest równoważne z svn upstream. Jeśli planowałeś z wyprzedzeniem, masz kopię svn upstream we własnej gałęzi lub oznaczyłeś ostatnią wersję svn. Jeśli nie planowałeś z wyprzedzeniem, użyj daty lub gitk, aby znaleźć skrót git SHA1, który jest najbardziej zbliżony do stanu svn.
  4. Teraz oblicz prawdziwą łatkę, analizując diff -rdwa klony.
Norman Ramsey
źródło
12
Lub po prostu postępuj zgodnie z radą @ Nicholas-smith i uruchom git diff --no-prefix > somefile.diffw swoim repozytorium git i wyślij to do dowolnego użytkownika svn, aby zaaplikował łatkę patch -p0 < somefile.diffw katalogu głównym projektu.
DavidG
10

Subversion <1.6 nie obsługuje poprawek. Wygląda na to, że Subversion 1.7 pozwoli na stosowanie łatek, a rozszerzenia git / hg do unified diff znajdują się na naszej liście TODO.

Bert Huijben
źródło
4

To rzeczywiście propozycja funkcji na początku 2008 roku

Linus Torvalds powiedział wtedy:

Twierdziłbym więc, że potrzebujesz czegoś mocniejszego, aby powiedzieć „nie rób różnicy git”, a to powinno również co najmniej uniemożliwić wykrywanie zmiany nazwy.
Szczerze mówiąc, każdy program, który jest tak głupi, że nie akceptuje bieżących łatek git (np. TortoiseSVN), to do cholery nie powinniśmy po prostu wyłączać najbardziej trywialnej części. Powinniśmy upewnić się, że nie włączamy żadnego z dość ważnych rozszerzeń:
nawet jeśli ToirtoiseSVN zignoruje je, jeśli zignorowanie ich oznacza, że ​​źle rozumie różnicę, nie powinno być w ogóle dozwolone.

Może dlatego

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

został wprowadzony w Git1.5.6 w maju / lipcu 2008 (choć nie testowałem)

VonC
źródło
0

Upewnij się, że zmiany zostały zatwierdzone i ponownie oparte na lokalnej gałęzi git, z git bash run:

git show --pretty >> myChangesFile.patch

Ismail Hawayel
źródło
0

Zaakceptowana odpowiedź udzielona przez Nicholasa działa dobrze, z wyjątkiem sytuacji, gdy a) pliki binarne istnieją w diff lub b) pracujesz w systemie Windows Git i masz katalogi ze spacjami. Aby to rozwiązać, musiałem dodać zagnieżdżone polecenie git diff, aby zignorować pliki binarne i polecenie sed, aby uciec ze spacji. Pisanie jest trochę uciążliwe, dlatego utworzyłem 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"

Jeśli następnie wpiszesz:

git svnpatch Feature123

... zostanie utworzony plik poprawki Feature123.patch z różnicami między bazą scalania gałęzi głównej i gałęzi Feature123.

Leandro Gomez
źródło