Git frühere Commits abmelden?

75

Ich habe mich gefragt, wie ich -sfrühere Commits, die ich in der Vergangenheit in git gemacht habe, abzeichnen kann.

camelCaseD
quelle
Überprüfen Sie schacon.github.com/git/git-commit.html
NullPoiиteя
mögliches Duplikat von stackoverflow.com/questions/1962094/…
NullPoiиteя
1
Ich frage mich, ob es nicht ironisch unsicher ist, dies zu tun. Wenn Sie mehr oder weniger unterschreiben, sagen Sie "Ich behaupte, dass die vorherigen Commits sicher sind". Wenn Sie sie jedoch geklont haben usw. und diese nicht wirklich überprüfen, geben Sie daher etwas an, das Sie nicht überprüfen können. Stellen Sie sich einen Hacker vor, der ein Commit irgendwie manipuliert. Das Signieren verhindert jedoch, dass man das Commit zu einem späteren Zeitpunkt manipuliert. Aber vielleicht sollten Sie dies der Nachricht hinzufügen?
Willem Van Onsem

Antworten:

107

Verwenden Sie die Änderungsoption, um das vorherige Commit abzumelden:

git commit --amend --signoff

Bearbeiten: Mit der Änderung wird nur das letzte Commit abgemeldet. Um mehrere Commits zu unterzeichnen, filter-branchund interpret-trailerswie vonc et al . al. sollte benutzt werden. Hier ist, was für mich funktioniert hat.

Konfigurieren Sie zunächst git so, dass das Token signdurch ersetzt wird Signed-off-by. Dies muss nur einmal durchgeführt werden und wird im nächsten Schritt benötigt.

git config trailer.sign.key "Signed-off-by"

Der Befehl git filter-branchmit dem Schalter --msg-filterwertet den Filter für jedes Commit einmal aus. Der Filter kann ein beliebiger Shell-Befehl sein, der die Festschreibungsnachricht auf stdin empfängt und auf stdout ausgibt. Sie können Ihren eigenen Filter schreiben oder einen git interpret-trailersunabhängigen Filter verwenden . Hier ist ein Beispiel, mit dem die letzten beiden Commits des aktuellen Zweigs mit dem aktuellen Benutzer und der E-Mail-Adresse abgemeldet werden:

export SIGNOFF="sign: $(git config --get user.name) <$(git config --get user.email)>"
git filter-branch -f --msg-filter \
    "git interpret-trailers --trailer \"$SIGNOFF\"" \
     HEAD~2..HEAD

Hinweis 1) Durch Ändern von Festschreibungsnachrichten wird die Festschreibungs-ID geändert. Dies bedeutet, dass das Übertragen bereits veröffentlichter Zweige entweder mit --forceoder besser erzwungen werden muss .

Hinweis 2) Wenn Sie beabsichtigen, Ihr benutzerdefiniertes Skript zu schreiben, achten Sie darauf, dass git filter-branchdas aktuelle Verzeichnis in geändert wird <repo>/.git-rewrite/t. Die Verwendung eines relativen Pfads zum Skript funktioniert normalerweise nicht. Stattdessen sollte sich das Skript in Ihrem $PATHoder als absoluter Pfad befinden.

fgiraldeau
quelle
Könnte eine erfordern git push -f.
Max
Ich habe versucht, die letzten 6 Commits zu ändern, indem ich zu 'HEAD ~ 6..HEAD' gewechselt habe, und es wurden viel mehr Commits geändert. im Grunde ein Chaos
Alex Punnen
31

Versuchen Sie dies, um alte Commits mit einem zu wiederholen -S:

git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD

Danach musst du git push -f. Aber seien Sie vorsichtig, die Commit-IDs ändern sich und andere Personen sind nicht mehr synchron.

Sebastian Mancke
quelle
1
Dadurch werden ALLE Commits abgemeldet, oder? Wie melde ich nur die letzten X-Commits ab?
Ákos Vandra
13
@ ÁkosVandra, wenn Sie noch nach einer Antwort suchen : git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD~X..HEAD, wobei X die Anzahl der letzten X-Commits ist. zB für die letzten 2 Commits:git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD~2..HEAD
Jashandeep Sohi
1
Was ist damit nur für MEINE Commits, nicht für alle?
Kerner1000
3
Ich denke, es gibt eine leichte Verwirrung, Kapital -Sist für GPG-Sign-Commit, ich denke, dass das OP niedriger bedeutete, -sum einfach eine Sign-off-byZeile am Ende der Commit-Nachricht hinzuzufügen .
Fgiraldeau
13

Wenn jemand noch nach einer besser automatisierten Methode zum Abmelden von Commits sucht.

Versuche dies:

git rebase --exec 'git commit --amend --no-edit -n -S' -i commit-hash

Dies wird alles neu starten, bis der Commit-Hash (X Commits)

Dann git push -fist es erforderlich, die Änderung des Verlaufs auf Remote zurückzuschieben

Keshan Nageswaran
quelle
1
Führen Sie für einen detaillierteren Ansatz zunächst interaktiv aus git rebase -i HEAD~x. Dann "injizieren" x git commit -S -s --amend --no-editSie im Editor nach jedem ausgewählten Commit, mit dem Sie sich anlegen möchten. Die in dieser Antwort vorgeschlagene Lösung ist wahrscheinlich der sauberste (und am meisten git) Weg, um dieses Problem zu lösen. +1
Vexy
1
Die beste und bessere Antwort, die ich liebe als die ausgewählte. :)
tai271828
12

Wenn Sie davon ausgehen, dass Abmeldungen die Festschreibungsnachricht ändern, wird dies verwendet git filter-branch, um dies zu erreichen.

git filter-branch --msg-filter \
    "cat - && echo && echo 'Signed-off-by: Dan McGee <[email protected]>'" \
    HEAD

(Beispiel aus " git filter-branchMagie ")

Oder folgende Curt J. Sampson ‚s Vorschlag , mit git interpret-trailers:

git config trailer.sign.key "Signed-off-by"
git filter-branch --msg-filter \
    "cat - && echo && git interpret-trailers --trailer 'sign: 'Signed-off-by: Dan McGee <[email protected]>'" \
    HEAD

Einschränkung : Dadurch wird der SHA1 Ihrer vorhandenen Commits geändert, und Sie müssen möglicherweise das Ergebnis erzwingen. Dies kann problematisch sein, wenn Ihre Commits bereits von anderen geteilt werden.

vorburger fügt im Kommentar ein Beispiel hinzu:

Mit Git Version 2.20.1 musste ich " Signed-off-by" in weglassen --trailer 'sign:und es so machen:

git filter-branch --msg-filter \
  "cat - && echo && git interpret-trailers --trailer 'sign: Michael Vorburger <[email protected]>'" \
  HEAD
VonC
quelle
Erwägen Sie die Verwendung git interpret-trailersmit, git filter-branch --msg-filteranstatt die Signed-off-by:oder andere Anhänger von Hand hinzuzufügen . Auf diese Weise können Sie beispielsweise das Duplizieren von Anhängern vermeiden.
cjs
@ CurtJ.Sampson Ja! Vielen Dank. Ich habe das gestern buchstäblich dokumentiert: stackoverflow.com/a/41361273/6309 .
VonC
@ CurtJ.Sampson Ich habe die Antwort entsprechend geändert.
VonC
Mit git Version 2.20.1 musste ich "'Signed-off-by'" im --trailer 'Zeichen weglassen: und mache es so: git filter-branch --msg-filter \ "cat - && echo && git interpret-trailers --trailer 'sign: Michael Vorburger <[email protected]>'" \ HEAD
vorburger
1
Ich musste das Befehlspräfix entfernen cat - && echo &&, sonst schlägt es mit command not foundFehler fehl .
Fgiraldeau
10

Für mich nur Zeichen ändern, meine Commits auf Github nicht wirklich überprüft.

Die Lösung, die für mich funktioniert, geht zurück und unterschreibt dann jedes Commit mit -S

git commit --amend -S

Verwenden Sie diesen Befehl auch, wenn Sie überprüfen, ob Ihr Commit tatsächlich signiert ist und Ihre E-Mail-Adresse / Ihr Name einfach nicht angehängt ist

git show HEAD --show-signature

Zusätzlicher Tipp: Wenn Sie Ihre Commits bereits ändern, möchten Sie möglicherweise Ihren richtigen Namen darin (siehe Verwenden git log). Möglicherweise verwenden Sie den Namen Ihres Github-Handles, der nicht benötigt wird. Es wird nur die richtige E-Mail-Adresse benötigt. Im Feld Benutzername sollten Sie Ihren vollständigen Namen verwenden. Github verfolgt ihn dann korrekt mit dem Namen Ihres Github-Handles. Um Ihren Benutzernamen zu korrigieren und das letzte Commit zu signieren, verwenden Sie:

git commit --amend --author="FULL NAME <email>" -S

und setzen Sie in Zukunft auch den vollständigen Namen für den Benutzernamen durch

git config --global user.name "FULL NAME"
Varun Garg
quelle
6

Ich hatte ein ähnliches Problem. Hier ist dank Robin Johnson von Gentoo Linux ein Trick, um die Signatur zu allen meinen vorherigen nicht gepushten Commits hinzuzufügen:

$ git pull && git rebase --gpg-sign --force-rebase origin/master && git push --signed
Already up-to-date.
Current branch master is up to date, rebase forced.
First, rewinding head to replay your work on top of it...
Applying: sci-biology/KING: new package
Applying: dev-lang/yaggo: version bump, fix install procedure
Applying: sci-libs/htslib: version bump
Applying: sci-biology/bcftools: version bump
Applying: sci-biology/samtools: version bump
Applying: sci-biology/libBigWig: new release with io.h renamed to bigWigIO.h
Applying: sci-biology/MaSuRCA: add more URLs to HOMEPAGE
Applying: sci-biology/SPAdes: update comments on bundled dev-libs/boost
Applying: sci-biology/khmer: added a comment how to proceed with src_compile()
Applying: sci-biology/picard: version bump
Applying: sci-biology/ruffus: pint EGIT_REPO_URI to the archive URL of code.google.com
Applying: sci-biology/vcftools: the 0.1.15_pre release was just renamed to 0.1.15 by upstream
Applying: sci-biology/nanopolish: new package
Applying: sci-biology/libBigWig: version bump
Counting objects: 75, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (75/75), done.
Writing objects: 100% (75/75), 14.51 KiB | 0 bytes/s, done.
Total 75 (delta 55), reused 0 (delta 0)
remote: To github.com:gentoo/sci.git
remote:    29c5e3f5d..b37457700  master -> master
To git+ssh://git.gentoo.org/proj/sci.git
   29c5e3f5d..b37457700  master -> master
$
Martin
quelle
4

Eine interaktive Rebase mit dem -SFlag erledigt den Job.

Angenommen, Sie müssen die letzten n Commits abmelden (stellen Sie sicher, dass Sie die neuesten dieser n Commits auschecken).

Lauf:

$ git rebase -S -i HEAD~n

# The `-S` flag is important.
# It tells Git to sign the following commits.

Dies gibt eine Liste der letzten nCommits.

Ändern Sie picknun das edit Präfix für alle Commits, die Sie signieren möchten.

Schließen Sie anschließend den Editor. Ein neuer Editor wird mit allen Informationen zum Commit geöffnet.

Da im Commit nichts geändert werden muss, speichern Sie die Datei und beenden Sie den Editor. Sie können die Festschreibungsnachricht auch ändern, während Sie gerade dabei sind.

Wiederholen Sie diesen Vorgang für andere Commits.

Um die neueste Geschichte zu pushen , git push remote branch -f.

Warnung

Es gibt ein Problem - es kann Ihre Commits umschreiben.

Wenn Sie ein 4 Monate altes Commit unterschreiben, wird möglicherweise das Datum überschrieben und es sieht so aus, als wäre es heute erstellt worden. Daher nicht empfohlen, wenn Sie Ihren Commit-Verlauf beibehalten möchten.

Roshnet
quelle
2

Heutzutage (beginnend mit Git 2.13 ) können Sie im Allgemeinen so etwas tun

git rebase --signoff HEAD~2

Hinzufügen von Signed-off-byFußzeilen zu den letzten 2 Commits (in diesem Beispiel).

sschuberth
quelle