2011-01-06 7 views
123

Robię coś bardzo prostego. Próbuję przygotować zwykły plik poprawki, więc mogę ponownie zastosować kilka zmian:Czy mogę uzyskać zgodne z łatką wyjście z git-diff?

$ git diff > before 
$ git diff something_here > save.patch 
$ git checkout . 
$ patch < save.patch 
$ git diff > after 
$ diff before after 
$ 

Z something_herepuste prawie działa, ale nazwy plików nie są w porządku. Myślę, że po prostu brakuje mi jakiejś opcji.

W prawdziwym życiu zamierzam zrobić scalenie po kasie, więc łatka może tam zawieść, ale widzisz, do czego zmierzam.

Edytuj Moja wina tutaj za zadanie niewłaściwego pytania. Właściwe pytanie brzmi: chcę zapisać moje zmiany, scalić, a następnie ponownie zastosować zmiany, jeśli to możliwe? Zapytałem go w niewłaściwy sposób, ponieważ jestem używany do używania łaty do rozwiązywania tego rodzaju problemów i git diff wyglądało tak, jak tego chciał.

Komentarz od Charlesa Baileya: miał właściwą odpowiedź. Dla mnie prawidłowe jest git-apply (git-stash wygląda na bardziej ciężki niż potrzebuję, a rebasing i bundles zdecydowanie wykracza poza mój obecny poziom umiejętności.) Przyjmuję odpowiedź, którą dał mi Charles (ponieważ nie można zaakceptować komentarza). Dzięki za wszystkie sugestie.

Edit, 6 lat później Jak każdego, kto zna temat wie, że zawyżona trudności git stash. Prawie codziennie lub tak, użyję następującą sekwencję:

$ git stash 
$ git merge 
$ git stash pop 
+7

Czy jest jakiś powód, dla którego chcesz użyć specjalnie 'patch' zamiast' git apply'? –

+2

A nawet czy naprawdę potrzebujesz łatek, a nie czegoś w rodzaju 'git stash' lub innych narzędzi git? –

+2

Po edycji, myślę, że 'git stash' jest najłatwiejszym rozwiązaniem dla tego, co próbujesz zrobić, ale istnieje wiele podejść, które działają. –

Odpowiedz

104

Jeśli chcesz użyć patcha trzeba usunąć a/b/ przedrostki git używa domyślnie. Można to zrobić za pomocą opcji --no-prefix (można też zrobić to z -p opcji plastra):

git diff --no-prefix [<other git-diff arguments>] 

Zazwyczaj jednak, że jest łatwiejszy w użyciu prostej git diff a następnie użyć wyjścia do paszy do git apply.

W większości przypadków staram się unikać używania łatek tekstowych. Zwykle łatwiejsze jest zarządzanie jednym lub kilkoma tymczasowymi zobowiązaniami w połączeniu z rebase, git stash i pakietami.

W Twoim przypadku użycia uważam, że najbardziej odpowiednie jest ustawienie stash.

# save uncommitted changes 
git stash 

# do a merge or some other operation 
git merge some-branch 

# re-apply changes, removing stash if successful 
# (you may be asked to resolve conflicts). 
git stash pop 
+3

'git diff --no-prefix master> diff.patch' a następnie' git checkout master' 'patch -p0 Natim

+0

@Natim Dla maksymalnego bezpieczeństwa polecam używanie' łatki --dry-run

+1

@ ᴠɪɴᴄᴇɴᴛ jakie byłyby korzyści z tego? Skoro używamy gita, to chyba nic nie stracimy, prawda? – Natim

15

Dyski git mają dodatkowy segment ścieżki poprzedzony ścieżkami plików.Można rozebrać ten wpis w ścieżce określając -P1 z patchem, tak:

patch -p1 < save.patch 
175

Wystarczy użyć -p1: trzeba będzie użyć -p0 w przypadku --no-prefix tak, więc można po prostu pominąć --no-prefix i używać -p1:

$ git diff > save.patch 
$ patch -p1 < save.patch 

$ git diff --no-prefix > save.patch 
$ patch -p0 < save.patch 
+0

Jeśli zastanawiasz się, dlaczego [man docs] (http://www.gnu.org/software/diffutils/manual/diffutils.html#patch-Directories) podsumowuje to ładnie - [źródło] (http://unix.stackexchange.com/a/26502/17836). – tutuDajuju

7

przydatny trik, aby uniknąć tworzenia tymczasowych plików patch:

git diff | załatać -P1 -d [DST-dir]

+0

Dokładnie to, co chciałem. Działa również doskonale ze schowkami! 'git stash show -p stash @ {3} | łatka-p1 -d [dst-dir] ' – dtmland

7
  1. zapisać diff bieżącego katalogu (łącznie z plikami niezaangażowane) wobec obecnego szefa.
  2. Następnie można przetransportować plik save.patch do dowolnego miejsca (łącznie z plikami binarnymi).
  3. Na komputerze docelowym, należy zastosować poprawkę przy użyciu git apply <file>

Uwaga: diff jest obecnie wystawił pliki.

$ git diff --binary --staged HEAD > save.patch 
$ git reset --hard 
$ <transport it> 
$ git apply save.patch 
+0

Hahaha. Zabawne. Zadałem to pytanie prawie cztery lata temu i sposób, w jaki to robię ewoluował, ale gdybyś zapytał mnie wczoraj, jak to zrobić, podałbym twoją odpowiedź i powiedziałem, że dostałem to z odpowiedzi na to pytanie. (Właściwie prawdopodobnie użyłbym gołego 'git diff> save.patch' oraz' git checkout .' zamiast resetowania, ale tak ... – Malvolio

+0

Och, nie zauważyłem jego 4-latka: P. Btw, reset jest tylko po to, żeby pokazać, że działa ...Nie widzę też nikogo, kto używa 'git apply' lub uczynił różnicę stosowną do twojego stanu i wskaźnika do ostatniego dostępnego zatwierdzenia. Robienie właśnie 'git diff' w ogóle nic nie zrobiło –

+0

Tak, teraz zastanawiam się jak dowiedziałem się o 'git apply'. Rzecz z 'git diff' jest (jak sądzę) z używania' git reset' - relacje między repo, indeksem i obszarem roboczym są problemem. – Malvolio

Powiązane problemy