Czy istnieje sposób na „autosign” zatwierdzanie w Git za pomocą klucza GPG?

213

Czy istnieje prosty sposób, aby Git zawsze podpisywał każdy zatwierdzony lub znacznik, który został utworzony?

Próbowałem z czymś takim jak:

alias commit = commit -S

Ale to nie pomogło.

Nie chcę instalować innego programu, aby tak się stało. Czy jest to wykonalne z łatwością?

Tylko pytanie poboczne, być może zatwierdzenia nie powinny być podpisywane, tylko tagi, których nigdy nie tworzę, ponieważ przesyłam pojedyncze zatwierdzenia dla projektu takiego jak Homebrew itp.

MindTooth
źródło
8
Powodem, dla którego twój alias działał, jest to, że nie możesz aliasu nad poleceniem, które już istnieje. (powiązane: stackoverflow.com/questions/5875275/git-commit-v-by-default stackoverflow.com/questions/2500586/... stackoverflow.com/questions/1278296/... )
Dan D.
2
Tylko dla informacji: przepisz wszystkie zatwierdzenia, które mają zostać wypchnięte, aby je podpisać: git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD@{u}..HEAD(Nie mam na myśli, że powinieneś tego użyć).
Vi.

Odpowiedzi:

275

Uwaga: jeśli nie chcesz -Scały czas dodawać, aby upewnić się, że twoje zatwierdzenia są podpisane, jest propozycja (oddział puna razie, grudzień 2013, więc nie ma gwarancji, że trafi do wydania git), aby dodać config, który zajmie się tą opcją dla Ciebie.
Aktualizacja maja 2014: jest w Git 2.0 (po ponownym wysłaniu w tej serii poprawek )

Zobacz zatwierdzenie 2af2ef3 przez Nicolasa Vigiera (boklm) :

Dodaj commit.gpgsignopcję podpisywania wszystkich zatwierdzeń

Jeśli chcesz, aby GPG podpisało wszystkie swoje zobowiązania, musisz -Scały czas dodawać tę opcję.
Opcja commit.gpgsignkonfiguracji umożliwia automatyczne podpisywanie wszystkich zatwierdzeń.

commit.gpgsign

Wartość logiczna określająca, czy wszystkie zatwierdzenia powinny być podpisane przez GPG.
Użycie tej opcji podczas wykonywania operacji takich jak rebase może spowodować podpisanie dużej liczby zatwierdzeń. Wygodne może być użycie agenta, aby uniknąć wpisywania hasła GPG kilka razy.


Ta konfiguracja jest zwykle ustawiana dla każdego repozytorium (nie musisz podpisywać prywatnych eksperymentalnych repozytoriów lokalnych):

cd /path/to/repo/needing/gpg/signature
git config commit.gpgsign true

Połączysz to z user.signingKeyustawieniem globalnym (unikalny klucz używany do wszystkich repozytoriów, w których chcesz podpisać zatwierdzenie)

git config --global user.signingkey F2C7AB29

user.signingKeyzostał wprowadzony w git 1.5.0 (styczeń 2007) z zatwierdzeniem d67778e :

Nie powinno być wymogu używania tej samej formy nazwiska w repozytorium git i kluczu gpg.
Co więcej, mogę mieć wiele kluczy w swoim breloku i mogę chcieć użyć takiego, który nie pasuje do adresu używanego w wiadomościach zatwierdzających.

Ta poprawka dodaje wpis konfiguracji „ user.signingKey”, który, jeśli jest obecny, zostanie przekazany do przełącznika „-u” dla gpg, umożliwiając zastąpienie klucza podpisywania znaczników.

To jest egzekwowane z popełnienia aba9119 (git 1.5.3.2), aby złapać sprawę gdzie Jeśli użytkownik błędnie skonfigurowany user.signingKeyw ich .git/configlub po prostu nie ma żadnych tajnych kluczy na ich kluczy.

Uwagi:

VonC
źródło
To jest naprawdę fajne. Czy istnieje prosty sposób na github zrobić coś takiego jak git opis bez konieczności pobierania repo dziury?
13
Nie musisz podpisywać prywatnych eksperymentalnych repozytoriów ... ale dlaczego nie miałbyś?
Andy Hayden
168
git config --global user.signingKey 9E08524833CB3038FDE385C54C0AFCCFED5CDE14
git config --global commit.gpgSign true

Zastąp 9E08524833CB3038FDE385C54C0AFCCFED5CDE14 swoim identyfikatorem klucza. Pamiętaj: użycie krótkiego identyfikatora nigdy nie jest dobrym pomysłem .

AKTUALIZACJA: Zgodnie z nowym edycją git wszystkie klucze konfiguracji powinny znajdować się w camelCase.

Felipe
źródło
Czy właśnie skopiowałeś i wkleiłeś to z odpowiedzi VonC ?
Robbie Averill
19
Nie. Jak widać w historii wydania, ktoś dodał mój przykład w swojej odpowiedzi. ED5CDE14 to mój własny klucz osobisty. Ale nie ma problemu.
Felipe
7
Dziwaczny. Cofnę zmianę jutro, ponieważ wygląda to źle dla ciebie
Robbie Averill
Jak znaleźć swój identyfikator podpisu klucza? też, czy posiadanie tylko 1 klucza GPG dla wszystkich moich repozytoriów git jest złe? ponieważ wolałbym nie mieć do czynienia z 4 kluczami różnicowymi w dość połączonych projektach.
MarcusJ
1
Może to pomóc użytkownikom Linuksa: Aby czasami działało (na przykład w Vimie, używając klucza zapisanego na karcie inteligentnej, który wymaga wprowadzenia kodu PIN) musiałem edytować ~/.gnupg/gpg-agent.confi dodawać pinentry-program /usr/bin/pinentry-gtk-2(postępując zgodnie z tym przewodnikiem wiki.archlinux.org/ index.php / GnuPG # pinentry )
iakovos Gurulian
49

Edit: Począwszy od wersji 1.7.9 Git, to jest możliwe do podpisania zobowiązuje Git ( git commit -S). Lekko aktualizuję odpowiedź, aby to odzwierciedlić.

Tytuł pytania to:

Czy istnieje sposób na „autosign” zatwierdzanie w Git za pomocą klucza GPG?

Krótka odpowiedź: tak, ale nie rób tego.

Adresowanie literówki w pytaniu: git commit -snie podpisuje zatwierdzenia. Zamiast tego ze man git-commitstrony:

-s, --signoff
Dodaj wiersz Signed-off-by przez komisarz na końcu komunikatu dziennika zatwierdzeń.

Daje to wynik dziennika podobny do następującego:


± $ git log                                                                                 [0:43:31]
commit 155deeaef1896c63519320c7cbaf4691355143f5
Author: User Name 
Date:   Mon Apr 16 00:43:27 2012 +0200

    Added .gitignore

    Signed-off-by: User Name 

Zwróć uwagę na bit „Signed-off-by: ...”; wygenerowany przez -sflagę na stronie git-commit.

Cytując e-maila z ogłoszeniem o wydaniu :

  • „git commit” nauczył się „-S”, aby GPG podpisał zatwierdzenie; można to pokazać za pomocą opcji „--show-Signature” do „git log”.

Więc tak, możesz podpisywać zatwierdzenia. Jednak osobiście wzywam do ostrożności z tą opcją; automatyczne podpisywanie zatwierdzeń jest bezcelowe, patrz poniżej:

Tylko pytanie poboczne, być może zatwierdzenia nie powinny być podpisywane, tylko tagi, których nigdy nie tworzę, ponieważ przesyłam pojedyncze zatwierdzenia.

To jest poprawne. Zobowiązania nie są podpisane; tagi są. Powód tego można znaleźć w tym przesłaniu Linusa Torvaldsa , którego ostatni akapit mówi:

Podpisywanie każdego zatwierdzenia jest całkowicie głupie. Oznacza to po prostu, że zautomatyzujesz go i sprawisz, że podpis będzie mniej wart. To również nie wnosi żadnej realnej wartości, ponieważ sposób, w jaki łańcuch git DAG w pracy SHA1, potrzebujesz tylko jednego podpisu, aby wszystkie zatwierdzenia dostępne z tego były skutecznie pokryte przez to. Więc podpisywanie każdego zatwierdzenia po prostu nie ma sensu.

Zachęcam do przeglądania połączonej wiadomości, która wyjaśnia, dlaczego automatyczne podpisywanie zatwierdzeń nie jest dobrym pomysłem w znacznie lepszy sposób niż ja.

Jednakże , jeśli chcesz automatycznie podpisać znacznik , będzie można to zrobić poprzez owinięcie git-tag -[s|u]w alias; jeśli masz zamiar to zrobić, prawdopodobnie chcesz ustawić swój identyfikator klucza ~/.gitconfiglub .git/configplik specyficzny dla projektu . Więcej informacji na temat tego procesu można znaleźć w książce społeczności git . Podpisywanie tagów jest nieskończenie bardziej przydatne niż podpisywanie każdego dokonanego zatwierdzenia.

simont
źródło
74
„Podpisywanie każdego zatwierdzenia jest całkowicie głupie”. -> Jaki jest lepszy sposób zabezpieczenia zatwierdzeń, gdy istnieje programista „szczur”, który lubi popychać zatwierdzenia za pomocą sfałszowanego autora i autora? O ile na serwerze nie ma magii hakowej, może skierować go git blamedo kogo chce.
Vi.
11
0. artykuł , 1. „wystarczy podpisać je wszystkie” -> Jak powiedzieć „Twierdzę, że to naprawdę mój diff (ale nie jestem pewien co do wcześniejszych i dalszych zobowiązań). Chcę podpisać swoje zatwierdzenie bez stwierdzania niczego o zatwierdzeniach, które wyciągnąłem z serwera centralnego itp. 2. W niezaufanym środowisku nadal powinno istnieć niezawodne narzędzie, aby dowiedzieć się, kto jest winny. Jeśli serwer sprawdzi, czy wszystkie zatwierdzenia są podpisane kluczem wiadomości e-mail zlecającego, jest to trudne do sfałszowania zatwierdzenia (jeśli dobrze zabezpieczysz komputer)
Vi.
9
Podpisanie jednego zatwierdzenia jest wystarczające, jeśli kod nigdy się nie zmienia. Gdy dodasz więcej zatwierdzeń, będziesz potrzebować więcej podpisów. Podpisanie tagu oznacza wszystko STARSZE niż to zatwierdzenie. Jeśli potrzebujesz dokładniejszej weryfikacji, gdy nadchodzą zatwierdzenia, warto podpisać każde zatwierdzenie. W przeciwnym razie będziesz musiał użyć wielu tagów, które po prostu zagracą repozytorium. Na uwierzytelnionych zdalnych repozytoriach git musisz podać hasło lub klucz ssh za każdym razem, gdy wypychasz zatwierdzenie, nie tylko kiedy wypychasz tagi. To podobna sytuacja.
Hans-Christoph Steiner,
22
Wydaje mi się, że Linusowi w pewnym sensie brakuje sensu. Wydaje się, że ma on zupełnie inny przypadek użycia podpisanych zobowiązań niż OP w tym wątku. (Weryfikacja integralności całego projektu, a weryfikacja autorstwa pojedynczego zatwierdzenia.)
Ajedi32
9
-1 dla „Tak, ale nie rób tego”. Odpowiedź powinna brzmieć „TAK”. Podpisywanie zatwierdzeń dowodzi autora, o czym inaczej można by kłamać w zatwierdzeniu.
Urda
6

Aby automatyczne podpisywanie działało przed wersją 2.0, musisz dodać alias git do zatwierdzenia.

# git config --global alias.commit commit -S
[alias]
    commit = commit -S
Shubham Chaudhary
źródło
0

Musisz wyjaśnić, że jeśli podpiszesz zatwierdzenie lub tag, nie oznacza to, że zatwierdzasz całą historię. W przypadku zatwierdzeń podpisujesz tylko pod ręką zmianę, aw przypadku tagu, cóż ... musisz zdefiniować, co masz na myśli. Być może wyciągnąłeś zmianę, która twierdzi, że jest od ciebie, ale nie była (ponieważ ktoś inny pchnął ją do twojego pilota). Lub jest to zmiana, w której nie chcesz być, ale właśnie podpisałeś tag.

W typowych projektach OSS może to być mniej powszechne, ale w scenariuszu korporacyjnym, w którym od czasu do czasu dotykasz kodu i nie czytasz całej historii, może to zostać niezauważone.

Podpisywanie zobowiązań jest problemem, jeśli zostaną one ponownie ustawione lub wybrane przez innych rodziców. Byłoby dobrze, gdyby zmodyfikowane zatwierdzenie mogło wskazywać na „oryginalne” zatwierdzenie, które faktycznie weryfikuje.

eckes
źródło
3
Rebasing jest jak kłamstwo. Należy go stosować wyjątkowo oszczędnie. Inną sprawą jest to, że podpisywanie jest kodem „wypisywania się”, więc upewnij się, że to a) nie jest anty-CYA i b) nie marnuje wysiłku.
11
@Barry „Rebasing jest jak kłamstwo. Należy go używać wyjątkowo oszczędnie ”- to po prostu nieprawda. Przepływy pracy oparte na Rebase są tak samo ważne jak przepływy pracy oparte na scalaniu. Rebasing jest zdecydowanie zbyt potężny, aby można go było stosować oszczędnie.
Lukas Juhrich
1
Gdy używasz tego wyłącznie z GitHub, to nie jest problem, zatwierdzenia scalania nie zostaną podpisane przez ciebie, ponieważ GitHub tego nie obsługuje. Zaletą podpisywania każdego zatwierdzenia (bez scalania) w tym środowisku jest to, że jest bardzo oczywiste, gdy nieuczciwe zatwierdzenie zostało dodane za pośrednictwem PR, ponieważ nie zostanie podpisane za pomocą klucza GPG.
Arran Cudbard-Bell
3
„Jest niebezpieczne, jeśli podpiszesz zatwierdzenie lub tag (oba podpiszą całą historię), że mógłbyś wyciągnąć zmianę, która twierdzi, że to od ciebie”. Jeśli podpisujesz tylko zatwierdzenie, nie zinterpretowałbym tego jako poparcie każdego zatwierdzenia dostępnego od twojego. Niekoniecznie stwierdzasz, że te poprzednie zmiany są ważne lub zatwierdzone przez ciebie, tylko że stworzyłeś zatwierdzenie na podstawie tych zmian. (Chociaż tagiem, zgadzam się, że rzeczywiście
wypisujesz
1
@ ArranCudbard-Bell Podobnie jak w przypadku aktualizacji, zatwierdzenia korespondencji seryjnej są podpisywane przez Ciebie, jeśli ustawisz wartość commit.gpgsigntrue zgodnie z sugestią @VonC
Jay