Português (Brasil) ▾ Topics ▾ Latest version ▾ git-reset last updated in 2.50.0

NOME

git-reset - Redefine o HEAD atual para a condição usada

RESUMO

git reset [-q] [<tree-ish>] [--] <pathspec>…​ git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>] git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>…​] git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]

DESCRIÇÃO

In the first three forms, copy entries from <tree-ish> to the index. In the last form, set the current branch head (HEAD) to <commit>, optionally modifying index and working tree to match. The <tree-ish>/<commit> defaults to HEAD in all forms.

git reset [-q] [<tree-ish>] [--] <pathspec>...
git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]

These forms reset the index entries for all paths that match the <pathspec> to their state at <tree-ish>. (It does not affect the working tree or the current branch.)

Isto significa que git reset <pathspec> é o oposto de git add <pathspec>. Este comando é equivalente a git restore [--source=<árvore>] --staged <pathspec>....

Depois de executar o git reset <pathspec> para atualizar a entrada do índice, você pode usar o git-restore[1] para verificar o conteúdo do índice para a árvore de trabalho. Como alternativa, utilizando git-restore[1] e especificando um commit com --source, você pode copiar o conteúdo de um caminho de um commit para o índice e a árvore de trabalho de uma vez só.

git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>...]

Interactively select hunks in the difference between the index and <tree-ish> (defaults to HEAD). The chosen hunks are applied in reverse to the index.

This means that git reset -p is the opposite of git add -p, i.e. you can use it to selectively reset hunks. See the "Interactive Mode" section of git-add[1] to learn how to operate the --patch mode.

git reset [<mode>] [<commit>]

This form resets the current branch head to <commit> and possibly updates the index (resetting it to the tree of <commit>) and the working tree depending on <mode>. Before the operation, ORIG_HEAD is set to the tip of the current branch. If <mode> is omitted, defaults to --mixed. The <mode> must be one of the following:

--soft

Does not touch the index file or the working tree at all (but resets the head to <commit>, just like all modes do). This leaves all your changed files "Changes to be committed", as git status would put it.

--mixed

Redefine o índice, mas não a árvore de trabalho (ou seja, os arquivos alterados são preservados, mas não marcados para um commit) e relata o que não foi atualizado. Esta é a ação predefinida.

Caso -N seja especificado, os caminhos removidos serão marcados como uma intenção de adicionar (consulte git-add[1]).

--hard

Resets the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded. Any untracked files or directories in the way of writing any tracked files are simply deleted.

--merge

Resets the index and updates the files in the working tree that are different between <commit> and HEAD, but keeps those which are different between the index and working tree (i.e. which have changes which have not been added). If a file that is different between <commit> and the index has unstaged changes, reset is aborted.

Em outras palavras, --merge faz algo como um git read-tree -u -m <commit>, mas carrega as entradas do índice não mescladas adiante.

--keep

Resets index entries and updates files in the working tree that are different between <commit> and HEAD. If a file that is different between <commit> and HEAD has local changes, reset is aborted.

--[no-]recurse-submodules

When the working tree is updated, using --recurse-submodules will also recursively reset the working tree of all active submodules according to the commit recorded in the superproject, also setting the submodules' HEAD to be detached at that commit.

Para as diferenças entre os três comandos consulte "Redefinir, restaurar e reverter" em git[1].

OPÇÕES

-q
--quiet

Fique em silêncio, reporte apenas as mensagens de erro.

--refresh
--no-refresh

Atualize o índice após uma redefinição mista. Ativado por padrão.

--pathspec-from-file=<file>

Pathspec is passed in <file> instead of commandline args. If <file> is exactly - then standard input is used. Pathspec elements are separated by LF or CR/LF. Pathspec elements can be quoted as explained for the configuration variable core.quotePath (see git-config[1]). See also --pathspec-file-nul and global --literal-pathspecs.

--pathspec-file-nul

Only meaningful with --pathspec-from-file. Pathspec elements are separated with NUL character and all other characters are taken literally (including newlines and quotes).

--

Não interprete mais argumentos como opções.

<pathspec>...

Limita os caminhos afetados pela operação.

Para mais detalhes sobre a sintaxe, consulte a entrada pathspec em gitglossary[7].

EXEMPLOS

Desfazendo um "add" (adicionar)
$ edit                                     (1)
$ git add frotz.c filfre.c
$ mailx                                    (2)
$ git reset                                (3)
$ git pull git://info.exemplo.com/ nitfol  (4)
  1. Você está trabalhando alegre e feliz em algo e encontra as alterações nesses arquivos em boas condições. Você não deseja vê-los quando executar o comando git diff, porque planeja trabalhar em outros arquivos e as alterações nesses arquivos são uma distração.

  2. Alguém pede para você fazer um pull, e as mudanças parecem dignas de serem mescladas.

  3. No entanto, você já sujou o índice (ou seja, o seu índice não corresponde ao commit HEAD). Mas você sabe que o pull que você fará não afeta o arquivo frotz.c ou o arquivo filfre.c, portanto, você reverte as alterações no índice destes dois arquivos. As suas alterações na árvore de trabalho permanecem lá.

  4. Então você pode fazer o pull e mesclar deixando as alterações nos arquivo frotz.c e` filfre.c` ainda na árvore de trabalho.

Desfazer um commit e refazendo-o
$ git commit ...
$ git reset --soft HEAD^      (1)
$ edit                        (2)
$ git commit -a -c ORIG_HEAD  (3)
  1. Isso geralmente é feito quando você se lembra que o commit que acabou de fazer está incorreto ou errou algo na sua mensagem do commit, ou ambos. Deixa a árvore de trabalho como estava antes de "redefinir".

  2. Faça as correções nos arquivos da árvore de trabalho.

  3. "reset" copia o cabeçalho antigo para .git/ORIG_HEAD; refaça o commit iniciando com sua a mensagem de registro log. Caso você não precise editar mais a mensagem, em vez disso poderá usar a opção -C.

    Consulte também a opção --amend para git-commit[1].

Desfazendo um commit, tornando-o uma ramificação do tópico
$ git branch topic/wip          (1)
$ git reset --hard HEAD~3       (2)
$ git switch topic/wip          (3)
  1. Você fez alguns commits, mas percebe que eles eram prematuros para estar no ramo master. Você deseja continuar dando polimento neles numa ramificação de tópico, portanto, crie a ramificação topic/wip fora do HEAD atual.

  2. Rebobine o ramo principal para se livrar destes três commits.

  3. Mude para o ramo topic/wip e continue trabalhando.

Desfaça-se dos commits permanentemente
$ git commit ...
$ git reset --hard HEAD~3   (1)
  1. Os últimos três commits (HEAD, HEAD^ e`HEAD~2`) foram ruins e você não deseja mais vê-los novamente. Não faça isso caso já tenha repassado estes commits para outra pessoa. (Para saber mais sobre as implicações desta ação, consulte a seção "RECUPERANDO DO UPSTREAM REBASE" no git-rebase[1].)

Desfazendo uma mesclagem ou pull
$ git pull                         (1)
Mesclagem automática do nitfol
CONFLITO (conteúdo): Houve um conflito durante a mesclagem com nitfol
A mesclagem automática falhou; arrume os conflitos e faça um novo commit.
$ git reset --hard                 (2)
$ git pull . $ git pull . topic/branch          (3)
Atualizando de 41223... para 13134...
Fast-forward
$ git reset --hard ORIG_HEAD       (4)
  1. Tente atualizar a partir do upstream responsável pelos diversos conflitos; você não estava pronto para perder muito tempo mesclando agora, então decide fazer isso mais tarde.

  2. O "pull" não fez a consolidação de mesclagem, portanto, git reset --hard, que é um sinônimo de git reset --hard HEAD, limpa a bagunça do arquivo do índice e da árvore de trabalho.

  3. Mescle uma ramificação de tópico na ramificação atual, o que resultou num avanço rápido.

  4. Mas você decidiu que o ramo de tópicos ainda não está pronto para consumo público. O "pull" ou "merge" sempre deixa o cume original do ramo atual em ORIG_HEAD, portanto, a redefinição forçada traz o seu arquivo do índice e a árvore de trabalho de volta para esta condição e redefine o cume do ramo para este commit.

Desfaça uma mesclagem ou pull dentro de uma árvore de trabalho suja
$ git pull                         (1)
Auto-merging nitfol
Merge made by recursive.
 nitfol                |   20 +++++----
 ...
$ git reset --merge ORIG_HEAD      (2)
  1. Mesmo que você tenha modificações locais em sua árvore de trabalho, você pode usar com segurança git pull quando souber que a alteração no outro ramo não se sobrepõe a elas.

  2. Após inspecionar o resultado da mesclagem, você pode achar que a alteração na outra ramificação não é satisfatória. Se executar o git reset --hard ORIG_HEAD permitirá que você volte para onde estava, mas descartará as alterações locais que você não quer. O git reset --merge mantém suas alterações locais.

Fluxo de trabalho interrompido

Suponha que você seja interrompido por uma solicitação de correção urgente enquanto estiver no meio de uma grande alteração. Os arquivos em sua árvore de trabalho ainda não estão em condições para um commit, mas você precisa acessar uma outra ramificação para obter uma correção rápida.

$ git switch feature  ;# você estava trabalhando no ramo "feature" e
$ work work work      ;# foi interrompido
$ git commit -a -m "snapshot WIP"                 (1)
$ git switch master
$ fix fix fix
$ git commit ;# faz o commit com um registro log real
$ git switch feature
$ git reset --soft HEAD^ ;# retorna para a condição WIP (2)
$ git reset                                       (3)
  1. Este commit será desfeito de modo que o descarte de uma mensagem de registro log seja OK.

  2. Isso remove o commit WIP do histórico e define a sua árvore de trabalho para a condição anterior antes de você fazer este instantâneo.

  3. Neste ponto o arquivo do índice ainda possui todas as alterações do WIP que você fez o commit como instantâneo WIP. Isso faz a atualização do índice para demonstrar que os seus arquivos WIP estão inalterados.

    Consulte também git-stash[1].

Redefine um único arquivo no índice

Suponha que você tenha adicionado um arquivo ao seu índice mas depois decida que você não quer mais adicioná-lo ao seu commit. Você pode remover o arquivo do índice enquanto mantém suas alterações com o git reset.

$ git reset -- frotz.c                      (1)
$ git commit -m "Faz o commit dos arquivos no índice"     (2)
$ git add frotz.c                           (3)
  1. Isso remove o arquivo do índice enquanto o mantém no diretório de trabalho.

  2. Isso faz o commit de todas as outras modificações no índice.

  3. Adiciona o arquivo ao índice novamente.

Mantenha as alterações na árvore de trabalho ao descartar alguns commits anteriores

Suponha que você esteja trabalhando em algo e faz o commit, você continua trabalhando mais um pouco, porém agora você acha que o que tem na sua árvore de trabalho deve estar em outro ramo que não tem nada a ver com o commit que você fez anteriormente. Você pode iniciar um novo ramo e redefini-lo, mantendo as alterações na sua árvore de trabalho.

$ git tag start
$ git switch -c branch1
$ edit
$ git commit ...                            (1)
$ edit
$ git switch -c branch2                     (2)
$ git reset --keep start                    (3)
  1. Isso faz o commit das suas primeiras edições em branch1.

  2. Em um mundo ideal você poderia ter percebido que o commit anterior não pertencia ao novo tópico quando você criou e alternou para o "branch2" (i.e. "switch -c branch2 start"), mas ninguém é perfeito.

  3. Porém é possível´ usar a opção reset --keep para remover o commit indesejado após alternar para branch2.

Divida um commit numa sequência de commits

Suponha que você tenha criado muitas alterações logicamente separadas e tenha feito o commit deles juntos. Depois, você decide que seria melhor ter cada pedaço lógico associado ao seu próprio commit. É possível utilizar o git reset para retroceder o histórico sem alterar o conteúdo dos seus arquivos locais e sucessivamente utilizar o comando git add -p para selecionar interativamente quais os blocos que deseja incluir em cada commit utilizando o comando git commit -c para preencher previamente a mensagem do commit.

$ git reset -N HEAD^                        (1)
$ git add -p                                (2)
$ git diff --cached                         (3)
$ git commit -c HEAD@{1}                    (4)
...                                         (5)
$ git add ...                               (6)
$ git diff --cached                         (7)
$ git commit ...                            (8)
  1. First, reset the history back one commit so that we remove the original commit, but leave the working tree with all the changes. The -N ensures that any new files added with HEAD are still marked so that git add -p will find them.

  2. Em seguida, selecionamos interativamente os blocos das diferenças para serem adicionas utilizando o recurso git add -p. Isso lhe perguntará sobre cada pedaço diff em sequência, assim você poderá usar de comandos simples como "yes, include this" (sim, inclua isso), "no don’t include this" (não, não inclua isso) ou mesmo o poderoso recurso "edit" (editar).

  3. Uma vez satisfeito com os blocos que deseja incluir, você deve verificar o que foi preparado para o primeiro commit utilizando a opção git diff --cached. Isso exibe todas as alterações que foram movidas para o índice e que estão prontas para o commit.

  4. Em seguida, faça o commit das alterações armazenadas no índice. A opção -c especifica para ser feito o preenchimento prévio da mensagem original do commit iniciado com o primeiro commit. É útil para evitar ter que digitá-la novamente. O HEAD@{1} é uma notação especial para o commit onde o HEAD estava antes da redefinição (reset) do commit original (1 alteração atrás). Para mais detalhes consulte git-reflog[1]. Você também pode utilizar qualquer outro commit válido como referência.

  5. Você pode repetir os passos 2-4 diversas vezes para quebrar o código original em diversos commits.

  6. Agora que você dividiu diversas alterações em seus próprios commits e pode não mais usar o modo patch do git add, para que possa selecionar todas os commits restantes que não foram alterados.

  7. Novamente, verifique se você incluiu o que deseja. Você também deve verificar se o git diff não exibe nenhuma outra alteração restante nos commits que serão realizados depois.

  8. E finalmente, crie o commit final.

DISCUSSÃO

As tabelas abaixo demonstram o que acontece durante a execução:

git reset --option target

para redefinir o HEAD para outro commit (` target`) com as diferentes opções de redefinição, dependendo do estado dos arquivos.

Nas tabelas, A, B, C e D são algumas diferenças entre as condições de um arquivo. Por exemplo, a primeira linha da primeira tabela significa que caso um arquivo esteja no estado A na árvore de trabalho, no estado` B` no índice, no estado C em HEAD e no estado D no alvo, o git reset --soft target deixará o arquivo na árvore de trabalho no estado A e o índice no estado B. Ele redefine (ou seja, move) o HEAD (ou seja, o cume do ramo atual, caso tenha um) para target (que tem o arquivo no estado D).

working index HEAD target         working index HEAD
----------------------------------------------------
 A       B     C    D     --soft   A       B     D
			  --mixed  A       D     D
			  --hard   D       D     D
			  --merge (desaprovado)
			  --keep  (desaprovado)
working index HEAD target         working index HEAD
----------------------------------------------------
 A       B     C    C     --soft   A       B     C
			  --mixed  A       C     C
			  --hard   C       C     C
			  --merge (desaprovado)
			  --keep   A       C     C
working index HEAD target         working index HEAD
----------------------------------------------------
 B       B     C    D     --soft   B       B     D
			  --mixed  B       D     D
			  --hard   D       D     D
			  --merge  D       D     D
			  --keep  (desaprovado)
working index HEAD target         working index HEAD
----------------------------------------------------
 B       B     C    C     --soft   B       B     C
			  --mixed  B       C     C
			  --hard   C       C     C
			  --merge  C       C     C
			  --keep   B       C     C
working index HEAD target         working index HEAD
----------------------------------------------------
 B       C     C    D     --soft   B       C     D
			  --mixed  B       D     D
			  --hard   D       D     D
			  --merge (desaprovado)
			  --keep  (desaprovado)
working index HEAD target         working index HEAD
----------------------------------------------------
 B       C     C    C     --soft   B       C     C
			  --mixed  B       C     C
			  --hard   C       C     C
			  --merge  B       C     C
			  --keep   B       C     C

git reset --merge is meant to be used when resetting out of a conflicted merge. Any mergy operation guarantees that the working tree file that is involved in the merge does not have a local change with respect to the index before it starts, and that it writes the result out to the working tree. So if we see some difference between the index and the target and also between the index and the working tree, then it means that we are not resetting out from a state that a mergy operation left after failing with a conflict. That is why we disallow --merge option in this case.

git reset --keep is meant to be used when removing some of the last commits in the current branch while keeping changes in the working tree. If there could be conflicts between the changes in the commit we want to remove and the changes in the working tree we want to keep, the reset is disallowed. That’s why it is disallowed if there are both changes between the working tree and HEAD, and between HEAD and the target. To be safe, it is also disallowed when there are unmerged entries.

As tabelas a seguir demonstram o que acontece quando há entradas que não foram mescladas:

working index HEAD target         working index HEAD
----------------------------------------------------
 X       U     A    B     --soft  (disallowed)
			  --mixed  X       B     B
			  --hard   B       B     B
			  --merge  B       B     B
			  --keep  (desaprovado)
working index HEAD target         working index HEAD
----------------------------------------------------
 X       U     A    A     --soft  (disallowed)
			  --mixed  X       A     A
			  --hard   A       A     A
			  --merge  A       A     A
			  --keep  (desaprovado)

O X significa qualquer condição e U significa um índice não mesclado.

GIT

Parte do conjunto git[1]

scroll-to-top