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?

elle
źródło

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
manojlds
źródło
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
Sriram Murali
źródło
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.

brandon
źródło
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.

Kenorb
źródło
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.

zdrsoft
źródło
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.

VonC
źródło
8

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

git format-patch -M -C COMMIT_VALUE~1..COMMIT_VALUE
Makah
źródło
4

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

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

Jiahut
źródło
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.

alls0rts
źródło
-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).

Ankush
źródło
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