Git: Uma explicação detalhada das operações “reset” e…

O Reset é um comando de desfazer muito poderoso no Git. Com o Reset, você pode desfazer commits, retirar alterações da área de preparação e descartar modificações. Compreender os três modos do Reset é fundamental para o controle de versão.

1. Revisitando conceitos básicos

(1) O que é um reset?

Um reset é uma operação que move o ramo atual para um local especificado:

100%
graph TB
    A[git reset] --> B{Pattern}
    B -->|soft| C[Move only the pointer<br/>Preserve the temporary storage area and the workspace]
    B -->|mixed| D[Move the pointer+Update the temporary storage area<br/>Save Workspace]
    B -->|hard| E[Move the pointer+Update the temporary storage area+Update Workspace]
    
    style C fill:#d4edda
    style D fill:#fff3cd
    style E fill:#f8d7da

(2) As três áreas do Git

Para entender o reset, primeiro é preciso compreender as três áreas de trabalho do Git:

100%
graph TB
    HEAD[HEADPointer] --> Branch[Branch pointer]
    Branch --> Repo[Repository<br/>Repository]
    Repo --> Stage[Buffer<br/>Staging Area]
    Stage --> Work[Workspace<br/>Working Directory]
    
    style HEAD fill:#f8d7da
    style Repo fill:#c3e6cb
    style Stage fill:#d4edda
    style Work fill:#fff3cd

(3) Redefinir direção

Você pode reiniciar para frente ou para trás:


2. Três modos de reinicialização

(1) Reinicialização suave (--soft)

Mova apenas os ponteiros HEAD e de ramificação, preservando a área de preparação e a área de trabalho.

▶ Exemplo: Reinicialização suave

BASH
# View Current Status
git log --oneline -3

# Output:
# d4e5f6g (HEAD -> main) feat: Add FeatureC
# h7i8j9k feat: Add FeatureB
# k9l0m1n feat: Add FeatureA

# Soft reset to the previous commit
git reset --soft HEAD~1

# View Status
git status

# Output:
# On branch main
# Changes to be committed:
#   (use "git restore --staged <file>..." to unstage)
#   new file:   feature-c.js

# View History
git log --oneline -3

# Output:
# h7i8j9k (HEAD -> main) feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# a1b2c3d Initial commit

# The commit is still in the staging area,You can resubmit it.
git commit -m "feat: Re-add FeatureC"

Efeitos de uma reinicialização suave:

(2) Reinicialização mista (--mixed, padrão)

Mover os ponteiros HEAD e de ramificação, atualizar a área de preparação e preservar o diretório de trabalho.

▶ Exemplo: Reinicialização híbrida

BASH
# View Current Status
git log --oneline -3

# Output:
# d4e5f6g (HEAD -> main) feat: Add FeatureC
# h7i8j9k feat: Add FeatureB
# k9l0m1n feat: Add FeatureA

# Mixed Reset(Default Mode)
git reset HEAD~1

# Or specify explicitly
git reset --mixed HEAD~1

# View Status
git status

# Output:
# On branch main
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#   feature-c.js

# View History
git log --oneline -3

# Output:
# h7i8j9k (HEAD -> main) feat: Add FeatureB
# k9l0m1n feat: Add FeatureA

# Edits in the workspace,Needs to be redoneadd
git add feature-c.js
git commit -m "feat: Re-add FeatureC"

Efeitos de uma reinicialização híbrida:

(3) Reinicialização total (--hard)

Mova os ponteiros HEAD e de ramificação e atualize a área de preparação e o diretório de trabalho.

▶ Exemplo: Reinicialização total

BASH
# View Current Status
git log --oneline -3

# Output:
# d4e5f6g (HEAD -> main) feat: Add FeatureC
# h7i8j9k feat: Add FeatureB
# k9l0m1n feat: Add FeatureA

# Hard Reset
git reset --hard HEAD~1

# Output:
# HEAD is now at h7i8j9k feat: Add FeatureB

# View Status
git status

# Output:
# On branch main
# nothing to commit, working tree clean

# View History
git log --oneline -3

# Output:
# h7i8j9k (HEAD -> main) feat: Add FeatureB
# k9l0m1n feat: Add FeatureA

# ⚠️ FeaturesCThe changes have been completely lost!

Efeitos de uma reinicialização total:

⚠️ Atenção: uma reinicialização total fará com que todas as alterações não salvas sejam perdidas. Use com cuidado!


3. Comparação dos modos de reinicialização

(1) Tabela comparativa dos três modos

Modo HEAD Área de preparação Diretório de trabalho Finalidade
soft Ação Imutável Imutável Desfazer commit, refazer commit
misto Mover Atualizar Manter Reverter e colocar em espera
difícil Mover Atualizar Atualizar Desfazer totalmente, descartar alterações

(2) Ilustrações dos três modos

100%
graph TB
    subgraph Before the reset
        A1[HEAD -> C3] --> B1[Buffer: C3Status]
        B1 --> C1[Workspace: C3Status]
    end
    
    subgraph softReset
        A2[HEAD -> C2] --> B2[Buffer: C3Status<br/>Retain]
        B2 --> C2[Workspace: C3Status<br/>Retain]
    end
    
    subgraph mixedReset
        A3[HEAD -> C2] --> B3[Buffer: C2Status<br/>Update]
        B3 --> C3[Workspace: C3Status<br/>Retain]
    end
    
    subgraph hardReset
        A4[HEAD -> C2] --> B4[Buffer: C2Status<br/>Update]
        B4 --> C4[Workspace: C2Status<br/>Update]
    end

(3) Selecione o modo adequado

Cenários de uso do soft:

Cenários de uso do mixed:

Cenários para o uso de “hard”:


4. Explicação detalhada do processo de reinicialização

(1) Reverter para um commit específico

▶ Exemplo: Reverter para um commit específico

BASH
# Revert to a Specific CommitID
git reset a1b2c3d

# Reset to a Specific Tag
git reset v1.0.0

# Reset to Relative Position
git reset HEAD~1   # Previous Commit
git reset HEAD~3   # Previous 3 commits
git reset HEAD^    # Previous Commit(Equivalent toHEAD~1)
git reset HEAD^^   # The first two commits

# Reset to a remote branch
git reset origin/main

(2) Desfazer o Stash

▶ Exemplo: Cancelar a preparação

BASH
# View the Stash
git status

# Output:
# Changes to be committed:
#   new file:   file1.js
#   new file:   file2.js

# Uncheck "Save a file to the clipboard"
git reset file1.js

# Or userestore
git restore --staged file1.js

# Discard all changes
git reset

# View Status
git status

# Output:
# Untracked files:
#   file1.js
#   file2.js

(3) Desfazer as alterações na área de trabalho

▶ Exemplo: Descartando alterações na área de trabalho

BASH
# View Workspace Changes
git status

# Output:
# Changes not staged for commit:
#   modified:   README.md

# Discard Workspace Changes
git restore README.md

# Or use the old syntax
git checkout -- README.md

# Discard all workspace changes
git restore .

# Or
git checkout -- .

# ⚠️ This will permanently lose any unsaved changes.!

5. A diferença entre “Redefinir” e “Reverter”

(1) reset x revert

Recurso redefinir reverter
Como usar Mover o ponteiro Criar um novo commit
Histórico Excluir histórico Manter histórico
Enviado Requer envio forçado Pode ser enviado normalmente
Segurança Os commits podem ser perdidos Os commits não serão perdidos
Casos de uso Commits locais não enviados Commits enviados

(2) Use reset para desfazer um commit local

▶ Exemplo: Use reset para desfazer um commit local

BASH
# An incorrect commit was created locally
git commit -m "Incorrect Submission"

# Undo Commit(Keep the changes)
git reset --soft HEAD~1

# Resubmit after making corrections
git commit -m "Correct Submission"

# Regular Push Notifications
git push origin main

(3) Use revert para desfazer um commit enviado

▶ Exemplo: Use revert para desfazer um commit enviado

BASH
# Pushed commits
git push origin main

# UsagerevertCreate a Revert Commit
git revert a1b2c3d

# Output:
# [main d4e5f6g] Revert "Incorrect Submission"
#  1 file changed, 1 deletion(-)

# Regular Push Notifications
git push origin main

# The history will retain the original submission andrevertSubmit
git log --oneline

# Output:
# d4e5f6g Revert "Incorrect Submission"
# a1b2c3d Incorrect Submission
# h7i8j9k Normal submission

6. Melhores práticas para reinicialização

(1) Processo de redefinição de segurança

▶ Exemplo: Reinicialização de segurança

BASH
# 1. View Current Status
git status
git log --oneline -5

# 2. Confirm which commit to roll back to
git log --oneline

# 3. First, create a backup branch(Optional)
git branch backup-branch

# 4. Perform a reset
git reset --hard a1b2c3d

# 5. Verification Results
git log --oneline -5
git status

# If the reset is done incorrectly,Can be restored
git reset --hard backup-branch

(2) Recuperação usando o reflog

▶ Exemplo: Como recuperar após uma reinicialização incorreta

BASH
# Operational error:A hard reset caused the commit to be lost
git reset --hard HEAD~3

# Viewreflog
git reflog

# Output:
# a1b2c3d HEAD@{0}: reset: moving to HEAD~3
# d4e5f6g HEAD@{1}: commit: feat: Add FeatureC
# h7i8j9k HEAD@{2}: commit: feat: Add FeatureB
# k9l0m1n HEAD@{3}: commit: feat: Add FeatureA

# Restore to the state prior to the reset
git reset --hard d4e5f6g

# Verification and Recovery
git log --oneline -5

(3) Reiniciar o fluxo de trabalho

100%
graph TB
    A[The operation needs to be undone] --> B{Has the operation been pushed??}
    B -->|Not pushed| C[Usagereset]
    B -->|Pushed| D[Usagerevert]
    C --> E{Keep or Discard Changes??}
    E -->|Yes| F[reset --soft/--mixed]
    E -->|No| G[reset --hard]
    D --> H[Create a Revert Commit]
    
    style C fill:#d4edda
    style D fill:#fff3cd
    style G fill:#f8d7da

❓ Perguntas Frequentes

P: Quais são as diferenças entre os três modos de reinicialização?

R: --soft apenas move o ponteiro, deixando as áreas temporária e de trabalho inalteradas; --mixed move o ponteiro e atualiza a área temporária, deixando a área de trabalho inalterada (padrão); --hard move o ponteiro e atualiza tanto a área temporária quanto a área de trabalho, restaurando totalmente o estado especificado.

P: Quando devo usar reset e quando devo usar revert?

R: Para commits locais que ainda não foram enviados, use reset para desfazê-los; para commits que já foram enviados, use revert para criar um commit reverso. reset reescreve o histórico, enquanto revert o preserva.

P: O reset --hard causará perda de dados?

R: As alterações não salvas serão perdidas. No entanto, você pode usar o reflog para recuperar a operação de redefinição mais recente. Mesmo que um commit seja redefinido, ainda é possível recuperá-lo usando seu ID de commit.

P: Como faço para desfazer uma operação git add?

R: Use git reset <file> ou git restore --staged <file> para descartar um item em espera. Use git reset para descartar todos os itens em espera.

P: Como faço para restaurar meus dados após uma reinicialização?

R: Use git reflog para visualizar o histórico de operações, localize a posição HEAD antes da reinicialização e use git reset --hard <commit> para restaurá-la. Como alternativa, se você tiver um branch de backup, basta reinicializar para esse branch.


📖 Resumo


📝 Exercícios

  1. Exercício básico: Crie vários commits, redefina-os usando cada um dos três modos de redefinição, observe as alterações na área de preparação e no diretório de trabalho e compreenda as diferenças entre os três modos.

  2. Exercício avançado: Simule um cenário de commit incorreto: crie um commit incorreto, use reset para desfazê-lo e, em seguida, faça o commit da versão correta para experimentar a aplicação prática de reset.

  3. Desafio: Experimente o poder do reflog: execute várias operações de reset, use o reflog para visualizar o histórico das operações, recupere-se de um reset malsucedido e compreenda os mecanismos de segurança de dados do Git.

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%