Gibt es eine Möglichkeit, Commits in Git mit einem GPG-Schlüssel automatisch zu signieren?

213

Gibt es eine einfache Möglichkeit, Git dazu zu bringen, jedes erstellte Commit oder Tag immer zu signieren?

Ich habe es mit so etwas versucht:

Alias ​​Commit = Commit -S

Aber das hat den Trick nicht getan.

Ich möchte kein anderes Programm installieren, um dies zu ermöglichen. Ist es mit Leichtigkeit machbar?

Nur eine Nebenfrage, vielleicht sollten Commits nicht signiert werden, nur Tags, die ich nie erstelle, da ich einzelne Commits für ein Projekt wie Homebrew usw. einreiche.

MindTooth
quelle
8
Der Grund, warum Ihr Alias ​​funktioniert hat, ist, dass Sie keinen Alias ​​für einen bereits vorhandenen Befehl erstellen können. (verwandt: stackoverflow.com/questions/5875275/git-commit-v-by-default stackoverflow.com/questions/2500586/… stackoverflow.com/questions/1278296/… )
Dan D.
2
Nur zur Information: Schreiben Sie alle Commits neu, die gedrückt werden müssen, um sie zu unterschreiben: git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD@{u}..HEAD(Ich meine nicht, dass Sie dies verwenden sollten).
Vi.

Antworten:

275

Hinweis: Wenn Sie nicht die -Sganze Zeit hinzufügen möchten, um sicherzustellen, dass Ihre Commits signiert sind, gibt es einen Vorschlag (Zweig ' pu' für den Moment , Dezember 2013, daher keine Garantie, dass es zu einer Git-Version kommt), einen hinzuzufügen Konfiguration, die diese Option für Sie erledigt.
Update Mai 2014: Es ist in Git 2.0 (nachdem es in dieser Patch-Serie erneut gesendet wurde )

Siehe Commit 2af2ef3 von Nicolas Vigier (boklm) :

Fügen Sie die commit.gpgsignOption zum Signieren aller Commits hinzu

Wenn Sie alle Ihre Commits von GPG signieren möchten, müssen Sie die -SOption jederzeit hinzufügen .
Mit der commit.gpgsignKonfigurationsoption können alle Commits automatisch signiert werden.

commit.gpgsign

Ein Boolescher Wert, der angibt, ob alle Commits mit GPG signiert werden sollen.
Die Verwendung dieser Option bei Vorgängen wie Rebase kann dazu führen, dass eine große Anzahl von Commits signiert wird. Es kann zweckmäßig sein, einen Agenten zu verwenden, um zu vermeiden, dass Sie Ihre GPG-Passphrase mehrmals eingeben.


Diese Konfiguration wird normalerweise pro Repo festgelegt (Sie müssen Ihre privaten experimentellen lokalen Repos nicht signieren):

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

Sie würden dies mit einer user.signingKeyals globale Einstellung verwendeten kombinieren (eindeutiger Schlüssel, der für alle Repos verwendet wird, für die Sie ein Commit signieren möchten).

git config --global user.signingkey F2C7AB29

user.signingKeywurde in git 1.5.0 (Jan. 2007) mit commit d67778e eingeführt :

Es sollte nicht erforderlich sein, dass ich in meinem Git-Repository und meinem GPG-Schlüssel dieselbe Form meines Namens verwende.
Außerdem habe ich möglicherweise mehrere Schlüssel in meinem Schlüsselbund und möchte möglicherweise einen verwenden, der nicht mit der Adresse übereinstimmt, die ich in Festschreibungsnachrichten verwende.

Dieser Patch fügt einen Konfigurationseintrag " user.signingKey" hinzu, der, falls vorhanden, an den Schalter "-u" für gpg übergeben wird, sodass der Tag-Signaturschlüssel überschrieben werden kann.

Dies wird mit erzwungen begehen aba9119 (git 1.5.3.2), um den Fall zu fangen , wo Wenn der Benutzer falsch konfiguriert hat user.signingKeyin ihrem .git/configoder hat keinen geheimen Schlüssel auf ihrem Schlüsselbund.

Anmerkungen:

VonC
quelle
Das ist wirklich cool. Gibt es eine einfache Möglichkeit, mit github so etwas wie git zu beschreiben, ohne das Hole Repo herunterladen zu müssen?
13
Sie müssen Ihre privaten experimentellen Repos nicht unterschreiben ... aber warum nicht?
Andy Hayden
168
git config --global user.signingKey 9E08524833CB3038FDE385C54C0AFCCFED5CDE14
git config --global commit.gpgSign true

Ersetzen Sie 9E08524833CB3038FDE385C54C0AFCCFED5CDE14 durch Ihre Schlüssel-ID. Denken Sie daran: Es ist niemals eine gute Idee, die kurze ID zu verwenden .

UPDATE: Pro ein neues git Edikt , alle Konfigurationsschlüssel in camelcase sein sollte.

Felipe
quelle
Haben Sie dies gerade aus VonCs Antwort kopiert und eingefügt ?
Robbie Averill
19
Wie Sie in der Editionshistorie sehen können, hat jemand mein Beispiel in seine Antwort aufgenommen. ED5CDE14 ist mein persönlicher Schlüssel. Aber kein Problem.
Felipe
7
Bizarr. Ich werde die Änderung morgen zurücksetzen, da es für Sie schlecht aussieht
Robbie Averill
Wie finden Sie Ihre Schlüsselsignatur-ID? Ist es auch schlecht, nur 1 GPG-Schlüssel für alle meine Git-Repos zu haben? weil ich es vorziehen würde, nicht mit 4 Diff-Schlüsseln in ziemlich verbundenen Projekten umgehen zu müssen.
MarcusJ
1
Dies könnte Linux-Benutzern helfen: Damit es in einigen Fällen funktioniert (z. B. unter Vim mit einem Schlüssel, der auf einer Smartcard gespeichert ist, für die eine PIN-Eingabe erforderlich ist), musste ich bearbeiten ~/.gnupg/gpg-agent.confund hinzufügen pinentry-program /usr/bin/pinentry-gtk-2( gemäß diesem Handbuch wiki.archlinux.org/). index.php / GnuPG # pinentry )
iakovos Gurulian
49

Edit: Wie von Git Version 1.7.9, es ist möglich , Git Commits zu unterzeichnen ( git commit -S). Aktualisieren Sie die Antwort leicht, um dies widerzuspiegeln.

Der Fragentitel lautet:

Gibt es eine Möglichkeit, Commits in Git mit einem GPG-Schlüssel automatisch zu signieren?

Kurze Antwort: Ja, aber tu es nicht.

Adressierung des Tippfehlers in der Frage: git commit -sUnterzeichnet das Commit nicht. Eher von der man git-commitSeite:

-s, --signoff
Add Sign-off-by-Zeile vom Committer am Ende der Commit-Protokollnachricht.

Dies ergibt eine Protokollausgabe ähnlich der folgenden:


± $ 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 

Beachten Sie das Bit "Abgemeldet von: ...". das wurde durch die -sFlagge auf der generiert git-commit.

Zitieren der Release-Ankündigungs-E-Mail :

  • "git commit" lernte "-S", um das Commit zu GPG-signieren; Dies kann mit der Option "--show-Signatur" für "Git-Protokoll" angezeigt werden.

Also ja, Sie können Commits unterschreiben. Ich persönlich rufe jedoch bei dieser Option zur Vorsicht auf. Das automatische Signieren von Commits ist nahezu sinnlos, siehe unten:

Nur eine Nebenfrage, vielleicht sollten Commits nicht signiert werden, nur Tags, die ich nie erstelle, wenn ich einzelne Commits einreiche.

Das ist richtig. Commits werden nicht unterzeichnet. Tags sind. Der Grund dafür ist in dieser Nachricht von Linus Torvalds zu finden , deren letzter Absatz besagt:

Jedes Commit zu unterschreiben ist total dumm. Es bedeutet nur, dass Sie es automatisieren und die Signatur weniger wert ist. Es bringt auch keinen wirklichen Mehrwert, da die Art und Weise, wie die Git-DAG-Kette von SHA1 funktioniert, Sie immer nur eine Signatur benötigen , damit alle von dieser erreichbaren Commits effektiv von dieser abgedeckt werden. Das Unterschreiben jedes Commits geht also einfach daneben.

Ich würde dazu ermutigen, die verknüpfte Nachricht zu durchsuchen, um zu verdeutlichen, warum das automatische Signieren von Commits keine weitaus bessere Idee ist als ich.

Allerdings , wenn Sie möchten , um automatisch ein Zeichen Tag , würden Sie in der Lage sein , das zu tun , indem die Verpackung git-tag -[s|u]in einem Alias; Wenn Sie dies tun, möchten Sie wahrscheinlich Ihre Schlüssel-ID ~/.gitconfigoder die projektspezifische .git/configDatei einrichten. Weitere Informationen zu diesem Prozess finden Sie im Git-Community-Buch . Das Signieren von Tags ist unendlich nützlicher als das Signieren jedes von Ihnen vorgenommenen Commits.

simont
quelle
74
"Jedes Commit zu unterschreiben ist total dumm." -> Was ist ein besserer Weg, um Commits zu sichern, wenn es einen "Ratten" -Entwickler gibt, der gerne Commits mit gefälschten Autoren und Committern pusht? Sofern sich auf dem Server keine Hook-Magie befindet, kann er git blamean jeden weiterleiten , den er möchte.
Vi.
11
0. ein Artikel , 1. "reicht aus, um alle zu unterschreiben" -> Wie man sagt "Ich behaupte, dass dies wirklich mein Unterschied ist (aber ich bin mir nicht sicher über vorherige und weitere Festschreibungen). Ich möchte eine Unterschrift auf meine Festschreibung setzen Ohne etwas über Commits zu behaupten, die ich vom zentralen Server abgerufen habe / was auch immer. 2. In einer nicht vertrauenswürdigen Umgebung sollte es immer noch ein zuverlässiges Tool geben, um herauszufinden, wer schuldig ist. Wenn der Server überprüft, ob alle Commits mit dem Schlüssel der E-Mail des Committers signiert sind, ist dies der Fall Es ist schwer, ein Commit vorzutäuschen (wenn Sie Ihren Computer gut sichern).
Vi.
9
Das Signieren eines Commits ist ausreichend, wenn sich der Code nie ändert. Sobald Sie weitere Commits hinzufügen, benötigen Sie weitere Signaturen. Das Signieren eines Tags markiert alles ÄLTER als dieses Commit. Wenn Sie während der bevorstehenden Commits eine detaillierte Überprüfung benötigen, ist es sinnvoll, jedes Commit zu unterschreiben. Andernfalls müssten Sie viele Tags verwenden, die das Repo nur überladen würden. Bei authentifizierten Remote-Git-Repos müssen Sie jedes Mal, wenn Sie ein Commit drücken, Ihr Passwort oder Ihren SSH-Schlüssel angeben, nicht nur, wenn Sie Tags drücken. Dies ist eine ähnliche Situation.
Hans-Christoph Steiner
22
Ich habe das Gefühl, dass Linus den Punkt irgendwie verfehlt. Er scheint einen ganz anderen Anwendungsfall für signierte Commits im Auge zu haben als das OP in diesem Thread. (Überprüfung der Integrität des gesamten Projekts im Vergleich zur Überprüfung der Urheberschaft eines einzelnen Commits.)
Ajedi32
9
-1 für "Ja, aber tu es nicht." Die Antwort sollte nur ein klares "JA" sein. Das Unterzeichnen von Commits beweist den Autor, worüber sonst im Commit gelogen werden kann.
Urda
6

Damit die automatische Signatur vor Git Version 2.0 funktioniert, müssen Sie einen Git-Alias ​​für das Commit hinzufügen.

# git config --global alias.commit commit -S
[alias]
    commit = commit -S
Shubham Chaudhary
quelle
0

Sie müssen klarstellen, dass Sie beim Unterzeichnen eines Commits oder Tags nicht bedeuten, dass Sie den gesamten Verlauf genehmigen. Im Falle von Commits unterschreiben Sie nur die vorliegende Änderung, und im Falle eines Tags müssen Sie definieren, was Sie damit meinen. Möglicherweise haben Sie eine Änderung vorgenommen, die behauptet, sie stamme von Ihnen, war es aber nicht (weil jemand anderes sie auf Ihre Fernbedienung übertragen hat). Oder es ist eine Änderung, an der Sie nicht teilnehmen möchten, aber Sie haben gerade das Tag signiert.

In typischen OSS-Projekten ist dies möglicherweise weniger häufig, aber in einem Unternehmensszenario, in dem Sie nur ab und zu Code berühren und nicht den gesamten Verlauf lesen, wird dies möglicherweise unbemerkt.

Das Unterzeichnen von Commits ist ein Problem, wenn sie an andere Eltern weitergegeben werden. Es wäre jedoch gut, wenn ein geändertes Commit auf das "ursprüngliche" Commit verweisen könnte, das tatsächlich überprüft wird.

eckes
quelle
3
Wiederherstellen ist wie Lügen. Es sollte äußerst sparsam eingesetzt werden. Die andere Sache ist, dass das Festschreiben mit einer Signatur das "Abmelden" von Code bedeutet. Stellen Sie also doppelt sicher, dass es a) kein Anti-CYA-Code und b) kein verschwendeter Aufwand ist.
11
@Barry “Rebasing ist wie Lügen. Es sollte äußerst sparsam eingesetzt werden “- das ist einfach nicht wahr. Rebase-basierte Workflows sind genauso gültig wie Merge-basierte Workflows. Rebasing ist viel zu mächtig, um sparsam eingesetzt zu werden.
Lukas Juhrich
1
Wenn Sie dies ausschließlich mit GitHub verwenden, was kein Problem ist, werden die Merge-Commits nicht von Ihnen signiert, da GitHub dies nicht unterstützt. Der Vorteil des Signierens jedes (nicht zusammengeführten) Commits in dieser Umgebung besteht darin, dass es sehr offensichtlich ist, wann ein Rogue-Commit über einen PR hinzugefügt wurde, da es nicht mit Ihrem GPG-Schlüssel signiert wird.
Arran Cudbard-Bell
3
"Es ist gefährlich, wenn Sie ein Commit oder Tag unterschreiben (beide unterschreiben den gesamten Verlauf), dass Sie möglicherweise eine Änderung vorgenommen haben, die behauptet, dass sie von Ihnen stammt." Wenn Sie nur ein Commit unterschreiben, würde ich das nicht als interpretieren Bestätigung jedes von Ihnen erreichbaren Commits. Sie geben nicht unbedingt an, dass diese früheren Änderungen von Ihnen gültig oder gebilligt sind, sondern nur, dass Sie basierend auf diesen Änderungen ein Commit erstellt haben. (Obwohl mit einem Tag, stimme ich zu, dass Sie tatsächlich alle Commits abmelden, die mit dem Tag erreichbar sind.)
Ajedi32
1
@ ArranCudbard-Bell Nur als Update werden Merge-Commits von Ihnen signiert, wenn Sie commit.gpgsignauf true setzen , wie von @VonC
Jay