git to - Como modificar commits existentes e não processados?




branch desconsiderar (23)

Eu escrevi a coisa errada em uma mensagem de commit. Como alternativa, esqueci de incluir alguns arquivos.

Como posso alterar a mensagem / arquivos de commit? O commit ainda não foi enviado.


Answers

Se é o seu último commit, apenas altere o commit:

git commit --amend -o -m "New commit message"

(usando o --only -o ( --only ) para garantir que você altere apenas a mensagem de confirmação)


Se é um commit enterrado, use o ótimo repositório interativo :

git rebase -i @~9   # Show the last 9 commits in a text editor

Encontre o commit desejado, altere pick para r ( reword ) e salve e feche o arquivo. Feito!


Tutorial de vim em miniatura (ou, como rebase com apenas 8 pressionamentos de tecla 3j cw r Esc ZZ ):

  • Corra vimtutor se você tiver tempo
  • h j k l correspondem às teclas de movimento
  • Todos os comandos podem ser prefixados com um "intervalo", por exemplo, 3j se move para baixo 3 linhas
  • i para entrar no modo de inserção - o texto digitado aparecerá no arquivo
  • Esc ou Ctrl c para sair do modo de inserção e retornar ao modo "normal"
  • u para desfazer
  • Ctrl r para refazer
  • dd , dw , dl para excluir uma linha, palavra ou letra, respectivamente
  • cc , cw , cl para alterar uma linha, palavra ou letra, respectivamente (o mesmo que dd i )
  • yy , yw , yl para copiar ("yank") uma linha, palavra ou letra, respectivamente
  • p ou P para colar depois ou antes da posição atual, respectivamente
  • :w Enter para salvar (gravar) um arquivo
  • :q! Entre para sair sem salvar
  • :wq Enter ou ZZ para salvar e sair

Se você editar bastante o texto, mude para o layout do teclado Dvorak, aprenda a digitar e aprenda o vim. Vale a pena o esforço? Sim.


ProTip ™: Não tenha medo de experimentar comandos "perigosos" que reescrevem o histórico * - o Git não exclui seus commits por 90 dias por padrão; você pode encontrá-los no reflog:

$ git reset @~3   # go back 3 commits
$ git reflog
c4f708b [email protected]{0}: reset: moving to @~3
2c52489 [email protected]{1}: commit: more changes
4a5246d [email protected]{2}: commit: make important changes
e8571e4 [email protected]{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started

* Cuidado com opções como --hard e --force - eles podem descartar dados.
* Além disso, não reescreva o histórico em nenhum ramo em que você esteja colaborando.


Se você quiser apenas editar o último uso de commit:

git commit --amend

ou

git commit --amend -m 'one line message'

Mas se você quiser editar vários commits seguidos, você deve usar o rebasing em vez disso:

git rebase -i <hash of one commit before the wrong commit>

Em um arquivo como o acima, escreva edit / e ou uma das outras opções e pressione salvar e sair.

Agora você estará no primeiro commit errado. Faça alterações nos arquivos e eles serão organizados automaticamente para você. Tipo

git commit --amend

salvar e sair disso e digite

git rebase --continue 

para ir para a próxima seleção até terminar com todas as suas seleções.

Note que estas coisas mudam todos os seus hashes SHA após aquele commit em particular.


Para quem procura uma GUI do Windows / Mac para ajudar na edição de mensagens antigas (ou seja, não apenas a mensagem mais recente), eu recomendo o SourceTree . Os passos a seguir estão abaixo.

Para confirmações que ainda não foram enviadas para um controle remoto:

  1. Certifique-se de ter confirmado ou armazenado todas as alterações atuais (ou seja, para que não haja arquivos listados na guia "Status do arquivo") - isso não funcionará de outra forma.
  2. Na aba "Log / Histórico", clique com o botão direito do mouse na entrada com uma linha adjacente no gráfico um abaixo do (s) commit (s) que você deseja editar e selecione "Rebase children of <commit ref> interativamente ..."
  3. Selecione a linha inteira da mensagem de commit que você deseja alterar ( isto é, clique na coluna "Message" ).
  4. Clique no botão "Editar mensagem".
  5. Edite a mensagem como desejado na caixa de diálogo que aparece e clique em OK.
  6. Repita as etapas 3 a 4 se houver outras mensagens de confirmação a serem alteradas.
  7. Clique em OK: o re-lançamento começará. Se tudo estiver bem, a saída terminará "Concluído com sucesso".

... Ou ... para commits que já foram enviados:

Siga os passos nesta resposta , que são semelhantes aos acima, mas requerem um comando adicional para ser executado a partir da linha de comando para forçar o ramo a ser lido - leia tudo e aplique o cuidado necessário!


Eu adicionei o alias de reci, recmpara recommit (amend)isso, agora eu posso fazer isso com git recmou git recm -m.

$ vim ~/.gitconfig

[alias]

    ......
    cm = commit
    reci = commit --amend
    recm = commit --amend
    ......

Como já foi mencionado, git commit --amend é a maneira de sobrescrever o último commit. Uma nota: se você quiser também sobrescrever os arquivos , o comando será

git commit -a --amend -m "My new commit message"

Uau, então há muitas maneiras de fazer isso.

Ainda outra maneira de fazer isso é excluir o último commit, mas manter as alterações para que você não perca seu trabalho. Você pode então fazer outro commit com a mensagem corrigida. Isso seria algo parecido com isto:

git reset --soft HEAD~1
git commit -m 'New and corrected commit message'

Eu sempre faço isso se esqueço de adicionar um arquivo ou fazer uma alteração.

Lembre - se de especificar --soft invés de --hard , senão você perderá esse commit inteiramente.


Se você estiver usando a ferramenta Git GUI, existe um botão denominado emendar último commit. Clique nesse botão e, em seguida, ele exibirá seus últimos arquivos e mensagens de confirmação. Apenas edite essa mensagem e você poderá confirmá-la com uma nova mensagem de confirmação.

Ou use este comando em um console / terminal:

git commit -a --amend -m "My new commit message"

Se você precisar alterar uma mensagem de confirmação antiga em várias ramificações (isto é, a confirmação com a mensagem incorreta estiver presente em várias ramificações), convém usar:

git filter-branch -f --msg-filter \
'sed "s/<old message>/<new message>/g"' -- --all

O Git irá criar um diretório temporário para reescrever e adicionalmente fazer backup de referências antigas em refs/original/ .

  • -f reforçará a execução da operação. Isso é necessário se o diretório temporário já estiver presente ou se já houver referências armazenadas em refs/original . Se esse não for o caso, você pode soltar esse sinalizador.

  • -- separa opções de ramificação de filtro das opções de revisão.

  • --all irá certificar-se de que todos os ramos e tags são reescritos.

Devido ao backup de suas referências antigas, você pode facilmente voltar ao estado antes de executar o comando.

Digamos que você queira recuperar seu mestre e acessá-lo no branch old_master :

git checkout -b old_master refs/original/refs/heads/master

Eu percebi que eu tinha empurrado um commit com um erro de digitação. Para desfazer, fiz o seguinte:

git commit --amend -m "T-1000, advanced prototype"
git push --force

Aviso: a força que forçar as alterações substituirá a ramificação remota pela sua local. Certifique-se de que você não vai sobrescrever nada que você queira manter. Também seja cauteloso em forçar um commit (reescrito) alterado se alguém compartilhar o branch com você, porque eles precisarão reescrever seu próprio histórico se tiverem a cópia antiga do commit que você acabou de reescrever.


Se você estiver usando a GUI do Git, você pode alterar o último commit que não foi enviado:

Commit/Amend Last Commit

Atualize sua última mensagem de commit errada com uma nova mensagem de commit em uma linha:

git commit --amend -m "your new commit message"

Ou tente git reset como abaixo:

# You can reset your head to n number of commit
# NOT a good idea for changing last commit message
# but you can get an idea to split commit into multiple commits
git reset --soft HEAD^

# it will reset you last commit. Now, you
# can re-commit it with new commit message.

Usando reset para dividir commits em commits menores

git reset pode ajudá-lo a quebrar um commit em múltiplos commits também:

# reset your head. I am resetting to last commits:
git reset --soft HEAD^
# (you can reset multiple commit by doing HEAD~2(no. of commits)

# Now, reset your head for splitting it to multiple commits
git reset HEAD

# add and commit your files seperately to make multiple commits: e.g
git add app/
git commit -m "add all files in app directory"

git add config/
git commit -m "add all files in config directory"

Aqui você quebrou com sucesso seu último commit em dois commits.


Emendando a mensagem de commit mais recente

git commit --amend

irá abrir o seu editor, permitindo que você altere a mensagem de commit do commit mais recente. Além disso, você pode definir a mensagem de confirmação diretamente na linha de comando com:

git commit --amend -m "New commit message"

… No entanto, isso pode fazer com que mensagens de confirmação de várias linhas ou pequenas correções sejam mais complicadas de serem inseridas.

Certifique-se de que você não tenha nenhuma alteração na cópia de trabalho preparada antes de fazer isso ou eles também serão confirmados. (Alterações não organizadas não serão confirmadas.)

Alterando a mensagem de uma confirmação que você já enviou para sua ramificação remota

Se você já enviou sua confirmação para o seu ramo remoto, você precisará forçar o commit a:

git push <remote> <branch> --force
# Or
git push <remote> <branch> -f

Aviso: o envio forçado sobrescreve o ramo remoto com o estado do seu local . Se houver commits no branch remoto que você não tem em seu branch local, você perderá os commits.

Aviso: tenha cuidado ao alterar os commits que você já compartilhou com outras pessoas. Emendar os commits essencialmente os reescreve para ter diferentes IDs de SHA , o que representa um problema se outras pessoas tiverem cópias do commit antigo que você tenha reescrito. Qualquer um que tenha uma cópia do commit antigo precisará sincronizar seu trabalho com o commit recém-reescrito, o que às vezes pode ser difícil, então certifique-se de coordenar com os outros ao tentar reescrever o histórico de commits compartilhado, ou apenas reescrever commits compartilhados completamente.

Use rebase interativo

Outra opção é usar o rebase interativo.
Isso permite editar qualquer mensagem que você queira atualizar, mesmo que não seja a última mensagem.

Para fazer um git squash, siga estes passos:

// X is the number of commits to the last commit you want to be able to edit
git rebase -i HEAD~X

Depois de esmagar seus commits - escolha o e/r para editar a mensagem

Nota importante sobre rebas interativo

Quando você usa a git rebase -i HEAD~X , pode haver mais de X commits. O Git irá "coletar" todos os commits nos últimos X commits e se houver uma mesclagem em algum lugar entre esse range, você verá todos os commits também, então o resultado será X +.

Boa dica:

Se você tiver que fazer isso para mais de uma única ramificação e você puder enfrentar conflitos ao alterar o conteúdo, configure o git rerere e deixe o git resolver esses conflitos automaticamente para você.

🔥 Hot-tip

Você também pode escrever uma pequena função bash para corrigir a última mensagem de commit do git e empurrá-la para o controle remoto. Me ajuda o tempo todo. Aqui está a função; coloque-o em seu arquivo .bashrc ou similar .zshrc e recarregue seu shell.

# Amend the last commit message
# Push the changes to remote by force
# USAGE: gamend "Your New Commit Msg"
function gamend() {
    git commit --amend -m "[email protected]"
    git push --force
}

Documentação


Se a confirmação que você deseja corrigir não for a mais recente:

  1. git rebase --interactive $parent_of_flawed_commit

    Se você quiser consertar vários commits falhos, passe o pai do mais antigo deles.

  2. Um editor aparecerá, com uma lista de todos os commits desde o que você deu.

    1. Alterar pick para reword (ou em versões antigas do Git, para edit ) na frente de qualquer confirmação que você deseja corrigir.
    2. Depois de salvar, o Git irá repetir os commits listados.

  3. Para cada commit que você quer reescrever , o Git irá retornar ao seu editor. Para cada consolidação que você deseja editar , o Git coloca você no shell. Se você está no shell:

    1. Altere o commit da maneira que desejar.
    2. git commit --amend
    3. git rebase --continue

A maior parte desta seqüência será explicada a você pela saída dos vários comandos. É muito fácil, você não precisa memorizá-lo - lembre-se que o git rebase --interactive permite corrigir os commits não importa há quanto tempo eles foram.

Observe que você não desejará alterar os commits que você já enviou. Ou talvez você faça, mas nesse caso você terá que tomar muito cuidado para se comunicar com todos que podem ter tirado seus commits e feito trabalhos em cima deles. Como faço para recuperar / ressincronizar depois que alguém envia um rebase ou redefine para uma ramificação publicada?


Nesta questão, há muitas respostas, mas nenhuma delas explica detalhadamente como alterar mensagens de confirmação mais antigas usando o VIM. Eu estava preso tentando fazer isso sozinho, então aqui eu vou escrever em detalhes como eu fiz isso especialmente para pessoas que não têm experiência em VIM!

Eu queria mudar meus cinco últimos commits que eu já enviei para o servidor. Isso é muito 'perigoso' porque se alguém já tirou isso, você pode atrapalhar as coisas mudando as mensagens de commit. No entanto, quando você está trabalhando em seu próprio galho e tem certeza de que ninguém o puxou, você pode mudá-lo assim:

Digamos que você queira alterar seus cinco últimos commits e, em seguida, digite isso no terminal:

git rebase -i HEAD~5 * Onde 5 é o número de mensagens de confirmação que você deseja alterar. (então se você quiser mudar o 10º para o último commit você digita 10)

Este comando irá levá-lo para o VIM, onde você pode editar seu histórico de commit. Você verá seus últimos 5 commits no topo assim:

pick <commit hash> commit message

Em vez de pick você precisa escrever um novo reword . Você pode fazer isso no VIM digitando i , que faz você entrar no modo INSERT. (Você vê que você está no modo de inserção pela palavra INSERT na parte inferior) Para as confirmações que você deseja alterar digite reword em vez de pick

Então você precisa salvar e sair desta tela, você faz isso primeiro entrando no 'modo de comando' pressionando o botão esc. (você pode verificar se está no modo de comando se a palavra INSERT na parte inferior desaparecer). Em seguida, você pode digitar um comando digitando:, o comando para salvar e sair é wq . Então, se você digitar :wq você está no caminho certo.

Então o VIM vai passar por cima de cada mensagem de commit que você quer reformular, aqui você pode realmente mudar as mensagens de commit. Você fará isso entrando no modo INSERT, alterando a mensagem de confirmação, entrando no modo de comando e salvando e encerrando. Faça isso 5 vezes e você está fora do VIM!

Então, se você já enviou seus commits errados, você precisa git push --force para sobrescrevê-los. Lembre-se que o git push --force é uma coisa bastante perigosa para se fazer, então certifique-se de que ninguém tenha saído do servidor desde que você enviou seus commits errados!

Agora você mudou suas mensagens de commit!

(Como você vê, eu não sou tão experiente no VIM, então se eu usei o jargão errado para explicar o que está acontecendo, fique à vontade para me corrigir!)


Se você quiser apenas alterar sua última mensagem, use a sinalização --only ou seu atalho -o com commit --amend :

git commit --amend -o -m "New commit message"

Isso garante que você não aprimore acidentalmente seu commit com material preparado. Claro que é melhor ter uma configuração adequada do $EDITOR . Então você pode deixar a opção -m fora e o git preencherá previamente a mensagem de commit com a antiga. Desta forma, pode ser facilmente editado.


Eu prefiro assim.

git commit --amend -c <commit ID>

Caso contrário, haverá um novo commit com um novo ID de commit


Eu gosto de usar o seguinte:

  1. git status
  2. git add --all
  3. git commit -am "message goes here about the change"
  4. git pull <origin master>
  5. git push <origin master>

Usar

git commit --amend

Para entender em detalhes, um excelente post é 4. Reescrevendo a História do Git . Ele também fala sobre quando não usar o git commit --amend .


Você pode usar o git-rebase-reword

Ele é projetado para editar qualquer commit (não apenas o último) da mesma maneira que commit --amend

$ git rebase-reword <commit-or-refname>

É nomeado após a ação no rebase interativo para alterar um commit: "reword". Veja este post e man interactive mode-seção

Exemplos:

$ git rebase-reword b68f560
$ git rebase-reword HEAD^

Se você não empurrou o código para sua ramificação remota ( GitHub / Bitbucket ), você pode alterar a mensagem de confirmação na linha de comando, conforme abaixo.

 git commit --amend -m "Your new message"

Se você está trabalhando em um ramo específico, faça isso:

git commit --amend -m "BRANCH-NAME: new message"

Se você já enviou o código com a mensagem errada e precisa ser cuidadoso ao alterar a mensagem. Ou seja, depois de alterar a mensagem de confirmação e tentar empurrá-la novamente, você acaba tendo problemas. Para facilitar, siga estas etapas.

Por favor, leia minha resposta inteira antes de fazer isso.

git commit --amend -m "BRANCH-NAME : your new message"

git push -f origin BRANCH-NAME                # Not a best practice. Read below why?

Nota importante: Quando você usa o force push diretamente, pode acabar com problemas de código que outros desenvolvedores estão trabalhando na mesma ramificação. Então, para evitar esses conflitos, você precisa puxar o código do seu ramo antes de fazer o push force :

 git commit --amend -m "BRANCH-NAME : your new message"
 git pull origin BRANCH-NAME
 git push -f origin BRANCH-NAME

Essa é a melhor prática ao alterar a mensagem de confirmação, se já foi enviada.


Eu uso o Git GUI o máximo que posso, e isso te dá a opção de alterar o último commit:

Além disso, git rebase -i origin/master é um bom mantra que sempre lhe apresentará os commits que você fez em cima do master, e lhe dará a opção de alterar, deletar, reordenar ou squash. Não há necessidade de se apossar desse hash primeiro.


  1. Se você quiser apenas modificar sua última mensagem de commit, faça:

    git commit --amend
    

    Isso vai deixá-lo cair no seu exitor de texto e permitir que você altere a última mensagem de commit.

  2. Se você quiser alterar as últimas 3 mensagens de commit, ou qualquer uma das mensagens de commit até esse ponto, forneça HEAD~3 ao comando git rebase -i :

    git rebase -i HEAD~3
    

Se você quiser ver todos os commits em todos os branches que ainda não foram enviados, você pode estar procurando por algo assim:

git log --branches --not --remotes

E se você quiser apenas ver o commit mais recente em cada ramificação, e os nomes das ramificações, esta:

git log --branches --not --remotes --simplify-by-decoration --decorate --oneline






git git-commit git-rewrite-history amend