Skip to content

Latest commit

 

History

History
222 lines (161 loc) · 6.83 KB

008-oh-shit-git.md

File metadata and controls

222 lines (161 loc) · 6.83 KB

Oh Shit, Git?! - Wie korrigiere ich Änderungen?

File versehentlich schon in der Staging-Area, nochmal raus damit!

Wenn man ein File versehentlich in die Staging-Area geschoben hat, das man aber gar nicht committen will. Kann man es mit git restore --staged <file> wieder unstagen. Dieser Befehl wird auch in git status schön angezeigt.

$ touch vielleicht
$ git add vielleicht
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   vielleicht
$ git restore --staged vielleicht
$ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        vielleicht

Damit uns das File in den nächsten Schritten nicht stört, löschen wir es jetzt:

$ rm vielleicht

Ich hab Änderungen in einem File im Working-Directory gemacht, die will ich rückgängig machen

Der Befehl git status zeigt gottseidank schon den Befehl an, den man dafür benötigt:

$ echo "ein bloedsinn" >> neues-file.txt
$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   neues-file.txt
$ git restore neues-file.txt
$ git status
On branch main
nothing to commit, working tree clean

Damit ist der Stand des Files wieder der von der Staging-Area (entspricht auch dem Stand vom letzten Commit).

Ein File im Working-Directory auf den Stand von einem früheren Commit bringen

Um da File neues-file.txt auf den Stand von der Commit-ID 4fd6d3456zu bringen:

$ git restore --source=4fd6d3456 neues-file.txt

Das File ist somit verändert worden und muss wieder neu committed werden:

$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   file3

$ git commit -a -m "neuer Commit mit dem Stand eines Files von einem alten Commit"
$ git status

Noch Kleinigkeiten beim letzten Commit ergänzen (amend .. abändern)

Man hat gerade committiert und kommt drauf dass man entweder ein File vergessen hat zu "stagen", ein kleiner Typo den man noch korrigieren möchte o.ä. Dann kann man nach den "fehlerhaften" Commit nochmal wiefolgt korrigieren.

$ echo "das ist falsc" > neues-file.txt

$ git diff
warning: in the working copy of 'neues-file.txt', LF will be replaced by CRLF the next time Git touches it
diff --git a/neues-file.txt b/neues-file.txt
index df7df0c..dc18990 100644
--- a/neues-file.txt
+++ b/neues-file.txt
@@ -1,2 +1 @@
-hallo ich bin da
-noch eine änderung
+das ist falsc

$ git commit -a -m "das schaut ja gut ausss"

Ich komm erst jetzt drauf dass bei "falsc" noch das "h" fehlt ...:

$ echo "das ist falsch" > neues-file.txt

$ git diff
warning: in the working copy of 'neues-file.txt', LF will be replaced by CRLF the next time Git touches it
diff --git a/neues-file.txt b/neues-file.txt
index dc18990..c2d1ca7 100644
--- a/neues-file.txt
+++ b/neues-file.txt
@@ -1 +1 @@
-das ist falsc
+das ist falsch

$ git commit -a --amend --no-edit

Die letzte Commit-Message austauschen mit "amend"

Jetzt erst sehe ich dass ja die Commit-Message auch noch fehlerhaft ist (wohl nicht so mein Tag), also nochmal:

$ git commit --amend -m "das schaut ja gut aus"

Files wurden jetzt keine geändert, sondern nur die Commit-Message.

Den letzten Commit rückgängig machen, aber die Änderungen im Working-Directory behalten

Der letzte Commit war ein kompletter Topfen - ich will ihn so nicht mehr in der Commit-History haben. Aber die Änderungen sollen im Working-Directory noch bestehen bleiben, vielleicht will ich an den Files noch weiterarbeiten.

$ git reset main~
Unstaged changes after reset:
M       neues-file.txt

$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   neues-file.txt

no changes added to commit (use "git add" and/or "git commit -a")

$ git log
commit 7cb263b91b6b0a1285f34bb8fd2088b4cc812cc9 (HEAD -> main)
Author: Johannes Kleinlercher <[email protected]>
Date:   Fri Jun 21 16:37:55 2024 +0200

    neuer Commit mit dem Stand eines Files von einem alten Commit

Man sieht im Git-Log ist der letzte Commit verschwunden, aber lt. git status sind die Änderungen noch im Working-Directory.

Das <rev>~<n> steht für gehe n-Schritte ab dem Referenznamen zurück. Ohne Nummer entspricht dem ~1. In unserem Fall war die Referenz main, der Name unseres Branches.

Preisfrage: sind die Änderungen noch in der Staging-Area?

Wenn man 3 Commits zurückgehen will, dann kann man folgendes aufrufen:

$ git reset main~3

Wenn man die Änderungen im Working-Directory wieder committen will:

$ git commit -a -m "wieder committen"

Den letzten Commit rückgängig machen und die Änderungen auch im Working-Directory entfernen

Wenn man die Änderungen durch den letzten Commit sowohl im Git-Repository als auch im Working-Directory rückgängig machen will, muss man die Option --hard ergänzen.

$ git reset main~ --hard
HEAD is now at 90c4128 ich möchte nochmal commits erklären

Wichtig: HEAD ist auch eine Referenz und zeigt auch auf main

Das ist euch vlt beim git log bereits aufgefallen:

$ git log
commit 90c41286e4687cb13d0c3e36584f958f90a638d4 (HEAD -> main)

Einen früheren Commit rückgängig machen, aber nachvollziehbar in der Commit-Historie

Mit folgendem Befehl kann man einen bestimmten Commit (muss nicht der letzte sein!) rückgängig machen, indem einfach in einem neuen Commit die "Rückgängig-Änderungen" durchgeführt werden.

$ git revert 0e3d42a2 --no-edit

Wichtig: hier wird kein alter Commit gelöscht, sondern ein neuer Commit erstellt, der die Änderungen rückgängig macht. Die Korrektur ist also in der Commit-History nachvollziehbar:

$ git log

Achtung: das ganze wird kompliziert wenn man einen Commit reverted der Files anlegt, die in einem späteren Commit geändert werden. (Wenn wir Zeit haben können wir das in einem neuen Git-Repo kurz ausprobieren).

Einen früheren Commit rückgängig machen, aber in der Commit-Historie verschwinden lassen

Mit git rebase <ref>~<n> -i für interaktiv, kann ich mir die letzten Commits anzeigen lassen und die Commits löschen oder auch umsortieren. Ziemlicher git-Kungfu - aber wer weiß was er tut, soll ruhig machen ...

Zuerst Git-Log, um die Frage unten beantworten zu können:

$ git log

Und jetzt gehts mit dem Kungfu lost:

$ git rebase main~5 -i

Hat jemand eine Idee was mit den Commits nach dem gelöschten Commit passiert?