Jak wygenerować łatkę git dla konkretnego zatwierdzenia?


1231

Muszę napisać skrypt, który tworzy łatki dla listy numerów zatwierdzeń SHA1.

Próbowałem użyć git format-patch <the SHA1>, ale wygenerowało to poprawkę dla każdego zatwierdzenia od czasu SHA1. Po wygenerowaniu kilkuset łatek musiałem zabić proces.

Czy istnieje sposób na wygenerowanie łatki tylko dla określonego SHA1?

Odpowiedzi:


1989

Próbować:

git format-patch -1 <sha>

lub

git format-patch -1 HEAD

Zgodnie z linkiem do dokumentacji powyżej -1flaga mówi git, ile zatwierdzeń powinno być zawartych w łatce;

- <n>

     Przygotuj łatki z najwyższych zatwierdzeń.


Zastosuj łatkę za pomocą polecenia:

git am < file.patch

210
Zastosowanie poprawki: git apply --stat file.patch# pokaż statystyki. git apply --check file.patch# sprawdź błąd przed zastosowaniem. git am < file.patch# zastosuj łatkę w końcu.
— Adrian

3
Wydaje się, że nie działa, jeśli ostatnie zatwierdzenie jest scaleniem z innej gałęzi.
— Lex Li

2
Aby zastosować poprawkę do plików przy użyciu zakończeń linii CRLF:git am --keep-cr < mypatch.patch
— Michael Schmeißer

40
Użyj, git am -3 < file.patchaby zastosować przy użyciu trójstronnego scalenia, które pozwoli ci rozwiązać konflikty przy użyciu git mergetoolpóźniejszej (lub ręcznej edycji) znalezionej tutaj .
— Matt

6
To polecenie działa również tylko dla określonych plików z zatwierdzenia: git format-patch -1 <sha> path/to/file.jsSpowoduje to utworzenie łatki zawierającej tylko pliki różnic dla pliku.js
— Kristóf Dombi

281

Do generowania poprawek z najwyższych zatwierdzeń z określonego skrótu sha1:

git format-patch -<n> <SHA1>

Ostatnie 10 łatek z głowy w jednym pliku łatki:

git format-patch -10 HEAD --stdout > 0001-last-10-commits.patch

2
czy możesz być na tyle uprzejmy, aby podać przykład pierwszego polecenia
— Kasun Siyambalapitiya,

1
git format-patch -1 HEADwygeneruje łatkę dla ostatniego zatwierdzenia
— Sriram Murali

1
wybacz mi, że pytam o to, więc kiedy jest -2generowany łaty dla ostatnich 2 zatwierdzeń, to jest jeszcze jedna rzecz do wyjaśnienia, że ​​polecenie got format-patch -2 HEADjest takie samo jak wierszgit format-patch HEAD~2
— Kasun Siyambalapitiya

85

Załóżmy, że masz zatwierdzenie id 2 po zatwierdzeniu 1, możesz uruchomić:

git diff 2 1 > mypatch.diff

gdzie 2 i 1 to skróty SHA.


Dziękuję dookehster za odpowiedź. Oznacza to, że potrzebuję skryptu, aby znaleźć zatwierdzenia poprzedzające te, które mnie interesują. Miałem nadzieję, że uda mi się tego uniknąć.
— elle

11
@elle, nie, ty nie git diff hash^ hash. „hash ^” poprzedza zatwierdzenie. (ale oczywiście odpowiedź manojldsa jest lepsza)
— J-16 SDiZ

2
git show HEAD > mypatch.diffkiedy jesteś na zatwierdzeniu, powinieneś zrobić to samo.
— andho

1
@dookehester, czy to poprawne, czy też w drugą stronę,git diff 1 2
— Kasun Siyambalapitiya,

1
Nie spowoduje to włączenia żadnych plików binarnych do pliku różnic.
— stuckj

55

To polecenie (sugerowane już przez @ Naftuli Tzvi Kay ):

git format-patch -1 HEAD

Zamień na HEADokreślony skrót lub zakres.

wygeneruje plik łatki dla ostatniego zatwierdzenia sformatowanego tak, aby przypominał format skrzynki pocztowej UNIX.

-<n> - Przygotuj łatki z najwyższych zatwierdzeń.

Następnie możesz ponownie zastosować plik poprawki w formacie skrzynki pocztowej poprzez:

git am -3k 001*.patch

Zobacz: man git-format-patch.


Dzięki! Myślę, że warto zauważyć, że zastosowanie poprawki utworzy zatwierdzenie z komunikatem zatwierdzenia poprzedzonym [PATCH]. Łatwo to jednak naprawić
— Mike S

2
Fenomenalny. OP, nie zaakceptowałeś tego, ponieważ ...? @MikeS Nie, nie jest już tak, jak robi to jakakolwiek inna gitsformatowana łatka, przynajmniej jeśli użytkownik zastosuje ją we właściwy sposób.
— underscore_d

2
@MikeS Tak naprawdę nie badałem, dlaczego, ale pomijając -kflagę ( git am -3), naprawiłem ten formularz (brak PATCH[0/10]komunikatów zatwierdzania). Wersja Git 2.20.1.windows.1
— jannis

30
git format-patch commit_Id~1..commit_Id  
git apply patch-file-name

Szybkie i proste rozwiązanie.


5
Nie zapomnij też zadzwonić git apply --check patch-file-nameprzed nałożeniem łatki. Pomoże to uniknąć problemów.
— iamantony,

16

Jeśli chcesz mieć pewność, że łatka (pojedyncze zatwierdzenie) zostanie zastosowana na konkretnym zatwierdzeniu, możesz użyć nowej opcji git 2.9 (czerwiec 2016 r.) git format-patch --base

git format-patch --base=COMMIT_VALUE~ -M -C COMMIT_VALUE~..COMMIT_VALUE

# or
git format-patch --base=auto -M -C COMMIT_VALUE~..COMMIT_VALUE

# or
git config format.useAutoBase true
git format-patch -M -C COMMIT_VALUE~..COMMIT_VALUE

Zobacz zatwierdzenie bb52995 , zatwierdzenie 3de6651 , zatwierdzenie fa2ab86 , zatwierdzenie ded2c09 (26 kwietnia 2016 r.) Przez Xiaolong Ye (``) .
(Połączone przez Junio ​​C. Hamano - gitster- w zobowiązaniu 72ce3ff , 23 maja 2016 r.)

format-patch: dodaj --baseopcję „ ”, aby zapisać informacje o drzewie bazowym

Opiekunowie lub testerzy zewnętrzni mogą chcieć poznać dokładne drzewo bazowe, którego dotyczy seria poprawek. Naucz git format-patch --baseopcji ' ', aby zapisać informacje o drzewie bazowym i dołączyć je na końcu pierwszej wiadomości (listu motywacyjnego lub pierwszej poprawki w serii).

Informacje o drzewie bazowym składają się z „podstawowego zatwierdzenia”, które jest dobrze znanym zatwierdzeniem, które jest częścią stabilnej części historii projektu, nad którym wszyscy inni pracują, oraz zero lub więcej „wymaganych poprawek”, które są dobrze znane łatki w locie, które nie są jeszcze częścią „podstawowego zatwierdzenia”, które należy nałożyć na „podstawowe zatwierdzenie” w kolejności topologicznej, zanim będzie można zastosować poprawki.

„Podstawowe zatwierdzenie” jest pokazane jako „ base-commit:”, po którym następuje 40-heksadecymalna nazwa obiektu zatwierdzenia.
„Wymagana łatka” jest wyświetlana jako „ prerequisite-patch-id:”, po której następuje 40-heksadecy „identyfikator łatki”, który można uzyskać, przepuszczając łatę za pomocą git patch-id --stablepolecenia „ ”.


Git 2.23 (III kwartał 2019 r.) Poprawi to, ponieważ „ --base” opcja „ format-patch” obliczyła patch-idswstępnie wymagane łatki w niestabilny sposób, który został zaktualizowany do obliczeń w sposób zgodny z „ git patch-id --stable”.

Zobacz zatwierdzenie a8f6855 , zatwierdzenie 6f93d26 (26 kwietnia 2019 r.) Autor: Stephen Boyd ( akshayka) .
(Połączone przez Junio ​​C Hamano - gitster- w commit 8202d12 , 13 czerwca 2019)

format-patch: --base patch-idstabilne wyjście

Nie opróżnialiśmy kontekstu za każdym razem, gdy przetwarzaliśmy przystojniak w patch-idkodzie generacyjnym diff.c, ale robiliśmy to, kiedy generowaliśmy „stabilne” łatki za pomocą patch-idnarzędzia „ ”.

Przenieśmy tę podobną logikę patch-id.cdo diff.c, abyśmy mogli uzyskać ten sam skrót, gdy generujemy patch-id dla format-patch --base=typów wywołań poleceń.


Przed Git 2.24 (IV kwartał 2019 r.) „ git format-patch -o <outdir>” Zrobił odpowiednik „ mkdir <outdir>” nie „ mkdir -p <outdir>”, co jest poprawiane.

Zobacz commit edefc31 (11 października 2019) autor: Bert Wesarg ( bertwesarg) .
(Połączone przez Junio ​​C Hamano - gitster- w commit f1afbb0 , 18 października 2019)

format-patch: tworzenie wiodących komponentów katalogu wyjściowego

Podpisano: Bert Wesarg

„git format-patch -o” zrobił odpowiednik „mkdir”, a nie „mkdir -p”, co jest poprawiane.

Unikaj używania „ adjust_shared_perm” w wiodących katalogach, które mogą mieć wpływ na bezpieczeństwo. Osiągnięte przez tymczasowe wyłączenie config.sharedRepository„takich jak git init” robi.


W przypadku Git 2.25 (Q1 2020) „ git rebase” nie działał dobrze, gdy format.useAutoBaseustawiono zmienną konfiguracyjną, co zostało poprawione.

Zobacz zatwierdzenie cae0bc0 , zatwierdzenie 945dc55 , zatwierdzenie 700e006 , zatwierdzenie a749d01 , zatwierdzenie 0c47e06 (04 grudnia 2019) przez Denton Liu ( Denton-L) .
(Połączone przez Junio ​​C Hamano - gitster- w commit 71a7de7 , 16 grudnia 2019)

rebase: naprawić format.useAutoBasezepsucie

Zgłoszony przez: Christian Biesinger
Podpisany przez: Denton Liu

Dzięki format.useAutoBase = true, działa rebase spowodowało błędu:

fatal: failed to get upstream, if you want to record base commit automatically,
please use git branch --set-upstream-to to track a remote branch.
Or you could specify base commit by --base=<base-commit-id> manually
error:
git encountered an error while preparing the patches to replay
these revisions:

ede2467cdedc63784887b587a61c36b7850ebfac..d8f581194799ae29bf5fa72a98cbae98a1198b12

As a result, git cannot rebase them.

Napraw to, zawsze przekazując --no-basełatkę formatu z bazy, tak aby efekt format.useAutoBasebył negowany.


8

Aby wygenerować ścieżkę z określonego zatwierdzenia (nie ostatniego zatwierdzenia):

git format-patch -M -C COMMIT_VALUE~1..COMMIT_VALUE

4

jeśli chcesz różnicować określony plik, możesz:

git diff master 766eceb - połączenia /> 000-mysql-connector.patch


0

Z moim pochodzeniem rtęciowym zamierzałem użyć:

git log --patch -1 $ID > $file

Ale rozważam użycie git format-patch -1 $IDteraz.


-5

Jaki jest sposób wygenerowania łatki tylko dla określonego SHA1?

To dość proste:

Opcja 1. git show commitID > myFile.patch

Opcja 2. git commitID~1..commitID > myFile.patch

Uwaga: Zamień na commitIDrzeczywisty identyfikator zatwierdzenia (kod zatwierdzenia SHA1).


3
Opcja 1 jest całkowicie błędna i nie ma związku z pytaniem.
— Anshuman Manral

3
Opcja 2 to także nieprawidłowe polecenie. Pojawi się błąd, taki jak: git a5f4bcaeb7fa7de27ae79d9522332e872889bbf0 ~ 1..a5f4bcaeb7fa7de27ae79d9522332e872889bbf0 git: 'a5f4bcaeb7fa7de27ae79d9522332e872889bbf0e7. Zobacz „git --help”. Sprawdzanie zarzutów przed opublikowaniem odpowiedzi
— Anshuman Manral
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.