Chapters ▾ 2nd Edition

2.4 Grunderna i Git - Ångra saker

Ångra saker

När som helst kan du vilja ångra något. Här går vi igenom några grundläggande verktyg för att ångra ändringar du har gjort. Var försiktig, för du kan inte alltid ångra dina ångringar. Det här är ett av de få områden i Git där du kan förlora arbete om du gör fel.

En vanlig åtgärd är när du gör en incheckning för tidigt och glömmer att lägga till filer, eller när du skriver fel i incheckningsmeddelandet. Om du vill göra om incheckningen, lägga till fler ändringar och spara igen, använder du --amend:

$ git commit --amend

Kommandot tar innehållet i köytan och använder det för incheckningen. Om du inte har gjort några ändringar sedan senaste incheckningen (till exempel om du kör kommandot direkt efter föregående incheckning) blir ögonblicksbilden exakt densamma och det enda som ändras är meddelandet.

Samma textredigerare startas, men den innehåller redan meddelandet från föregående incheckning. Du kan redigera det som vanligt, men det skriver över den tidigare incheckningen.

Som exempel: om du gör en incheckning och sedan inser att du glömde köa ändringar i en fil kan du göra så här:

$ git commit -m 'Initial commit'
$ git add forgotten_file
$ git commit --amend

Du får en enda incheckning – den andra ersätter resultatet av den första.

Notera

Det är viktigt att förstå att när du gör ett tillägg av din senaste incheckning så ersätter du den med en ny, förbättrad incheckning som tränger undan den gamla och lägger den nya på dess plats. I praktiken är det som om den föregående incheckningen aldrig existerade, och den syns inte längre i historiken.

Det uppenbara värdet med att göra på detta sätt är att kunna göra små förbättringar i den senaste incheckningen utan att fylla historiken med meddelanden av typen "Oj, glömde lägga till en fil" eller "Hoppsan, rättade ett stavfel".

Notera

Gör bara --amend på incheckningar som fortfarande är lokala och inte har skickats någonstans. Att ändra redan skickade incheckningar och sedan tvinga upp grenen skapar problem för dina medarbetare. För mer om vad som händer och hur man återställer om man drabbas, se Farorna med grenflyttning.

Ta bort en köad fil

De två följande avsnitten visar hur du arbetar med köytan och ändringar i arbetskatalogen. Det trevliga är att kommandot du använder för att se statusen även påminner dig om hur du ångrar ändringar. Säg att du har ändrat två filer och vill spara dem som två separata incheckningar, men råkar skriva git add * och köar båda. Hur tar du bort en av dem från köytan? git status påminner dig:

$ git add *
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README
    modified:   CONTRIBUTING.md

Precis under "Changes to be committed" står det att du kan använda git reset HEAD <file>…​ för att ta bort från köytan. Låt oss använda det för CONTRIBUTING.md:

$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M	CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Kommandot är lite märkligt, men det fungerar. CONTRIBUTING.md är ändrad men återigen oköad.

Notera

Det stämmer att git reset kan vara ett farligt kommando, särskilt med flaggan --hard. I exemplet ovan rörs inte filen i arbetskatalogen, så det är relativt säkert.

Just nu är det här allt du behöver veta om git reset. Vi går igenom mycket mer i detalj vad reset gör och hur du kan använda det till intressanta saker i Nollställning förklarad.

Återställa en ändrad fil

Vad gör du om du inser att du inte vill behålla dina ändringar i CONTRIBUTING.md? Hur kan du enkelt återställa den till det skick den hade vid senaste incheckningen (eller när du klonade den, eller hur den nu hamnade i arbetskatalogen)? Som tur är visar git status även detta. I den senaste utskriften ser den oköade delen ut så här:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Den talar uttryckligen om hur du kastar bort ändringarna. Låt oss göra det:

$ git checkout -- CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

Du kan se att ändringarna nu är borta.

Viktigt

Det är viktigt att förstå att git checkout — <file> är ett farligt kommando. Alla lokala ändringar i filen försvinner – Git ersätter filen med den senast köade eller incheckade versionen. Använd aldrig kommandot om du inte är helt säker på att du inte vill behålla ändringarna.

Om du vill behålla ändringarna men ändå få undan dem för stunden går vi igenom gömman och greningar i Git-grenar; det är oftast bättre alternativ.

Kom ihåg att allt som är incheckat i Git nästan alltid kan återställas. Även incheckningar på grenar som tagits bort eller incheckningar som skrivits över med --amend kan återställas (se Dataåterställning för dataåterställning). Men allt du förlorar som aldrig har checkats in är sannolikt borta för gott.

Ångra med git restore

Git version 2.23.0 introducerade ett nytt kommando: git restore. Det är i praktiken ett alternativ till git reset, som vi just gick igenom. Från och med Git 2.23.0 använder Git git restore i stället för git reset för många åtgärder som ångrar ändringar.

Låt oss gå igenom samma exempel, men använda git restore i stället för git reset.

Ta bort en köad fil med git restore

De två följande avsnitten visar hur du arbetar med köytan och arbetskatalogen med git restore. Det fina är att kommandot du använder för att se statusen även påminner dig om hur du ångrar ändringar. Säg att du har ändrat två filer och vill göra två separata incheckningar, men råkar skriva git add * och köar båda. Hur tar du bort en av dem? git status påminner dig:

$ git add *
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   CONTRIBUTING.md
	renamed:    README.md -> README

Precis under "Changes to be committed" står det att du kan använda git restore --staged <file>…​. Låt oss ta bort CONTRIBUTING.md från köytan:

$ git restore --staged CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    README.md -> README

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:   CONTRIBUTING.md

CONTRIBUTING.md är ändrad men återigen oköad.

Återställa en ändrad fil med git restore

Vad gör du om du inte vill behålla ändringarna i CONTRIBUTING.md? Återigen visar git status exakt hur du gör:

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:   CONTRIBUTING.md

Den säger att du ska köra git restore <file>. Låt oss göra det:

$ git restore CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)

    renamed:    README.md -> README

Ändringarna är nu borta.

Viktigt

git restore <file> är också ett farligt kommando. Alla lokala ändringar i filen försvinner – Git ersätter filen med den senast köade eller incheckade versionen. Använd det bara om du är helt säker på att du inte vill behålla ändringarna.