Git-Tutorial: 10 häufige Git-Probleme und wie man sie behebt

Git lernen? Dieses Git-Tutorial behandelt die 10 häufigsten Git-Tricks, die Sie kennen sollten: wie Sie Commits rückgängig machen, Commits rückgängig machen, Commit-Meldungen bearbeiten, lokale Dateien verwerfen, Merge-Konflikte lösen und mehr.


1. Lokale Dateiänderungen verwerfen

Manchmal ist der beste Weg, ein Gefühl für ein Problem zu bekommen, darin einzutauchen und mit dem Code herumzuspielen. Leider stellen sich die im Prozess vorgenommenen Änderungen manchmal als nicht optimal heraus, in diesem Fall kann das Zurücksetzen der Datei in den ursprünglichen Zustand die schnellste und einfachste Lösung sein:

git checkout -- Gemfile 
git checkout -- lib bin 

Falls Sie sich fragen, der Doppelstrich (--) ist eine gängige Methode für Befehlszeilenprogramme, um das Ende von Befehlsoptionen anzuzeigen.

2. Lokale Commits rückgängig machen

Leider dauert es manchmal etwas länger, bis wir erkennen, dass wir auf dem falschen Weg sind, und zu diesem Zeitpunkt wurden möglicherweise bereits eine oder mehrere Änderungen vor Ort vorgenommen. Das ist wenn git reset ist praktisch:

git reset HEAD~2        
git reset --hard HEAD~2 

Seien Sie vorsichtig mit der --hard Möglichkeit! Es setzt sowohl Ihren Arbeitsbaum als auch den Index zurück, sodass alle Ihre Änderungen für immer verloren gehen.

3. Entfernen Sie eine Datei aus Git, ohne sie aus Ihrem Dateisystem zu entfernen

Wenn Sie während a nicht aufpassen git add, könnten Sie am Ende Dateien hinzufügen, die Sie nicht festschreiben wollten. Jedoch, git rm wird es sowohl aus Ihrem Staging-Bereich als auch aus Ihrem Dateisystem entfernen, was möglicherweise nicht das ist, was Sie möchten. Stellen Sie in diesem Fall sicher, dass Sie nur die bereitgestellte Version entfernen und die Datei zu Ihrer hinzufügen .gitignore um den gleichen Fehler nicht ein zweites Mal zu machen:

git reset filename          
echo filename >> .gitignore 

4. Bearbeiten Sie eine Commit-Nachricht

Tippfehler passieren, aber glücklicherweise ist es im Fall von Commit-Nachrichten sehr einfach, sie zu beheben:

git commit --amend                  
git commit --amend -m "New message" 

Aber das ist nicht alles git-amend kann für Sie tun. Haben Sie vergessen, eine Datei hinzuzufügen? Fügen Sie es einfach hinzu und ändern Sie das vorherige Commit!

git add forgotten_file 
git commit --amend

Bitte denken Sie daran --amend wird tatsächlich ein neues Commit erstellen, das das vorherige ersetzt, also verwenden Sie es nicht zum Ändern von Commits, die bereits in ein zentrales Repository gepusht wurden. Eine Ausnahme von dieser Regel kann gemacht werden, wenn Sie absolut sicher sind, dass kein anderer Entwickler die vorherige Version bereits ausgecheckt und ihre eigene Arbeit darauf aufgebaut hat, in diesem Fall ein erzwungener Push (git push --force) kann noch ok sein. Das --force Option ist hier notwendig, da der Verlauf des Baums lokal geändert wurde, was bedeutet, dass der Push vom Remote-Server abgelehnt wird, da kein Fast-Forward-Merge möglich ist.

5. Bereinigen Sie lokale Commits vor dem Pushen

Während --amend ist sehr nützlich, es hilft nicht, wenn der Commit, den Sie umformulieren möchten, nicht der letzte ist. In diesem Fall ist eine interaktive Rebase praktisch:

git rebase --interactive 


git rebase --interactive origin branch

Dies öffnet Ihren konfigurierten Editor und präsentiert Ihnen das folgende Menü:

pick 8a20121 Upgrade Ruby version to 2.1.3 
pick 22dcc45 Add some fancy library 
















Oben sehen Sie eine Liste lokaler Commits, gefolgt von einer Erklärung der verfügbaren Befehle. Wählen Sie einfach die Commit(s) aus, die Sie aktualisieren oder ändern möchten pick zu reword (oder r kurz), und Sie gelangen in eine neue Ansicht, in der Sie die Nachricht bearbeiten können.

Wie jedoch aus der obigen Auflistung ersichtlich ist, bieten interaktive Rebases viel mehr als die einfache Bearbeitung von Commit-Nachrichten: Sie können Commits vollständig entfernen, indem Sie sie aus der Liste löschen, sowie sie bearbeiten, neu anordnen und quetschen. Squashing ermöglicht es Ihnen, mehrere Commits zu einem zusammenzuführen, was ich gerne bei Feature-Branches mache, bevor ich sie auf die Fernbedienung pushe. Keine „Vergessene Datei hinzufügen“- und „Tippfehler beheben“-Commits mehr, die für die Ewigkeit aufgezeichnet werden!

6. Zurücksetzen von gepushten Commits

Trotz der in den vorherigen Tipps aufgezeigten Korrekturen gelangen gelegentlich fehlerhafte Commits in das zentrale Repository. Doch das ist kein Grund zur Verzweiflung, denn git bietet eine einfache Möglichkeit, einzelne oder mehrere Commits rückgängig zu machen:

 git revert c761f5c              
 git revert HEAD^                
 git revert develop~4..develop~2 

Falls Sie keine zusätzlichen Revert-Commits erstellen, sondern nur die notwendigen Änderungen auf Ihren Arbeitsbaum anwenden möchten, können Sie die verwenden --no-commit/-n Möglichkeit.


git revert -n HEAD

Die Handbuchseite unter man 1 git-revert listet weitere Optionen auf und gibt einige zusätzliche Beispiele.

7. Vermeiden Sie wiederholte Zusammenführungskonflikte

Wie jeder Entwickler weiß, kann das Beheben von Zusammenführungskonflikten mühsam sein, aber das wiederholte Lösen genau desselben Konflikts (z. B. in lang andauernden Feature-Zweigen) ist geradezu lästig. Wenn Sie in der Vergangenheit darunter gelitten haben, werden Sie sich freuen, etwas über die zu wenig genutzte Funktion zur Wiederverwendung der aufgezeichneten Auflösung zu erfahren. Fügen Sie es Ihrer globalen Konfiguration hinzu, um es für alle Projekte zu aktivieren:

git config --global rerere.enabled true

Alternativ können Sie es auf Projektbasis aktivieren, indem Sie das Verzeichnis manuell erstellen .git/rr-cache.

Dies ist sicherlich kein Feature für jedermann, aber für Leute, die es brauchen, kann es wirklich Zeit sparen. Stellen Sie sich vor, Ihr Team arbeitet gleichzeitig an verschiedenen Feature-Branches. Jetzt möchten Sie alle zu einem testbaren Vorabveröffentlichungszweig zusammenführen. Wie erwartet gibt es mehrere Zusammenführungskonflikte, die Sie lösen. Leider stellt sich heraus, dass einer der Zweige noch nicht ganz da ist, also beschließen Sie, die Zusammenführung wieder aufzuheben. Einige Tage (oder Wochen) später, wenn der Zweig endlich bereit ist, führen Sie ihn erneut zusammen, aber dank der aufgezeichneten Lösungen müssen Sie dieselben Zusammenführungskonflikte nicht erneut lösen.

Die Manpage (man git-rerere) enthält weitere Informationen zu weiteren Anwendungsfällen und Befehlen (git rerere status, git rerere diffetc).

8. Finden Sie den Commit, der nach einer Zusammenführung etwas kaputt gemacht hat

Das Aufspüren des Commit, das einen Fehler nach einer großen Zusammenführung verursacht hat, kann ziemlich zeitaufwändig sein. Glücklicherweise git bietet eine großartige binäre Suchfunktion in Form von git-bisect. Zuerst müssen Sie die Ersteinrichtung durchführen:

 git bisect start         
 git bisect bad           
 git bisect good revision 

Danach checkt Git automatisch eine Revision aus, die auf halbem Weg zwischen den bekannten „guten“ und „schlechten“ Versionen liegt. Sie können Ihre Spezifikationen jetzt erneut ausführen und den Commit entsprechend als „gut“ oder „schlecht“ markieren.

git bisect good 

Dieser Prozess wird fortgesetzt, bis Sie zu dem Commit gelangen, das den Fehler eingeführt hat.

9. Vermeiden Sie häufige Fehler mit Git-Hooks

Einige Fehler treten wiederholt auf, lassen sich jedoch leicht vermeiden, indem bestimmte Überprüfungen oder Bereinigungsaufgaben in einer definierten Phase des ausgeführt werden git Arbeitsablauf. Das ist genau das Szenario, für das Hooks entwickelt wurden. Um einen neuen Hook zu erstellen, fügen Sie eine ausführbare Datei hinzu .git/hooks. Der Name des Skripts muss einem der verfügbaren Hooks entsprechen, von denen eine vollständige Liste auf der Handbuchseite verfügbar ist (man githooks). Sie können auch globale Hooks zur Verwendung in all Ihren Projekten definieren, indem Sie ein Vorlagenverzeichnis erstellen, das git beim Initialisieren eines neuen Repositorys verwendet (weitere Informationen finden Sie unter man git-init). Hier ist, wie der relevante Eintrag in ~/.gitconfig und ein Beispiel-Vorlagenverzeichnis sieht so aus:

[init]
    templatedir = ~/.git_template
  
  → tree .git_template
  .git_template
  └── hooks
      └── pre-commit

Wenn Sie ein neues Repository initialisieren, werden Dateien im Vorlagenverzeichnis an den entsprechenden Speicherort in Ihrem Projekt kopiert .git Verzeichnis.

Was folgt, ist ein leicht konstruiertes Beispiel commit-msg Hook, der sicherstellt, dass jede Commit-Nachricht auf eine Ticketnummer wie „#123“.

ruby
  
  message = File.read(ARGV[0])

  unless message =~ /\s*#\d+/
    puts "[POLICY] Your message did not reference a ticket."
    exit 1
  end

10. Wenn alles andere fehlschlägt

Bisher haben wir ziemlich viel darüber behandelt, wie man häufige Fehler bei der Arbeit mit beheben kann git. Die meisten von ihnen haben ziemlich einfache Lösungen, aber es gibt Zeiten, in denen man die großen Geschütze herausholen und die Geschichte einer ganzen Branche neu schreiben muss. Ein häufiger Anwendungsfall dafür ist das Entfernen sensibler Daten (z. B. Anmeldeinformationen für Produktionssysteme), die an ein öffentliches Repository übergeben wurden:

git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch secrets.txt' \
--prune-empty --tag-name-filter cat -- --all

Dadurch wird die Datei entfernt secrets.txt von jedem Zweig und Tag. Außerdem werden alle Commits entfernt, die als Ergebnis der obigen Operation leer wären. Denken Sie daran, dass dadurch der gesamte Verlauf Ihres Projekts neu geschrieben wird, was in einem verteilten Arbeitsablauf sehr störend sein kann. Auch wenn die fragliche Datei jetzt entfernt wurde, sollten die darin enthaltenen Anmeldeinformationen immer noch als kompromittiert betrachtet werden!

GitHub hat eine Sehr gutes Tutorial zum Entfernen sensibler Daten und man git-filter-branch enthält alle Details zu den verschiedenen verfügbaren Filtern und ihren Optionen.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *