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:
- Mover o ponteiro de ramificação: Mover o HEAD e o ponteiro de ramificação para o commit especificado
- Atualizar a área de armazenamento temporário: Determinar se a área de armazenamento temporário deve ser atualizada com base no modo
- Atualizar área de trabalho: Determinar se a área de trabalho deve ser atualizada com base no modo
- Desfazer ações: Desfazer commit, adição à área de preparação e modificações
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:
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
- HEAD: Aponta para o branch atual
- Ponteiro de ramificação: Aponta para um commit específico
- Repositório: Armazena todos os commits
- Área de preparação: Alterações prontas para serem confirmadas
- Área de trabalho: Os arquivos que você está editando no momento
(3) Redefinir direção
Você pode reiniciar para frente ou para trás:
- Reverter para trás: Desfazer o commit e voltar ao estado anterior
- Redefinir para a frente: Avança para o próximo commit (raramente usado)
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
# 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:
- ✅ Reverter commit
- ✅ Manter as alterações na área de preparação (as alterações ainda estão na área de preparação)
- ✅ Manter o espaço de trabalho (os arquivos permanecem inalterados)
(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
# 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:
- ✅ Reverter commit
- ✅ Desarmar (transferir as alterações da área de preparação para a área de trabalho)
- ✅ Preservar a área de trabalho (os arquivos permanecem inalterados)
(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
# 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:
- ✅ Reverter commit
- ✅ Retirar da lista de favoritos
- ✅ Descartar as alterações na área de trabalho (restaurar o arquivo ao estado de um commit especificado)
⚠️ 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
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:
- Cometi um erro nas informações que enviei e gostaria de reenviá-las
- Quero mesclar vários commits em um só
- Editar o conteúdo do envio
Cenários de uso do mixed:
- Reverter o commit e reorganizar as alterações
- Desmarque os arquivos na área de preparação e selecione novamente os arquivos que deseja confirmar
- Modo padrão, o mais utilizado
Cenários para o uso de “hard”:
- Descartar todas as alterações atuais
- Retornar a um estado específico
- Organize o espaço de trabalho (use com cuidado)
4. Explicação detalhada do processo de reinicialização
(1) Reverter para um commit específico
▶ Exemplo: Reverter para um commit específico
# 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
# 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
# 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
# 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
# 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
# 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
# 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
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
resete quando devo usarrevert?R: Para commits locais que ainda não foram enviados, use
resetpara desfazê-los; para commits que já foram enviados, userevertpara criar um commit reverso.resetreescreve o histórico, enquantoreverto preserva.
P: O
reset --hardcausará 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>ougit restore --staged <file>para descartar um item em espera. Usegit resetpara descartar todos os itens em espera.
P: Como faço para restaurar meus dados após uma reinicialização?
R: Use
git reflogpara visualizar o histórico de operações, localize a posição HEAD antes da reinicialização e usegit reset --hard <commit>para restaurá-la. Como alternativa, se você tiver um branch de backup, basta reinicializar para esse branch.
📖 Resumo
- Um reset é uma operação que move o ponteiro de ramificação para um local especificado.
- Três modos: suave (preserva as alterações), misto (preserva a área de trabalho) e radical (redefinição completa)
- Reinicialização suave: reverter o commit, preservando a área de preparação e o diretório de trabalho
- Reinicialização mista: reverte os commits e o staging, mas mantém o diretório de trabalho (padrão)
- Reinicialização total: desfaz completamente todas as alterações (use com cautela)
- reset x revert: “reset” é usado para ramos locais, enquanto “revert” é usado para ramos que já foram enviados
📝 Exercícios
-
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.
-
Exercício avançado: Simule um cenário de commit incorreto: crie um commit incorreto, use
resetpara desfazê-lo e, em seguida, faça o commit da versão correta para experimentar a aplicação prática dereset. -
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.