Pergunta

Quando eu trabalhei um pouco com o meu código-fonte, eu fiz a minha coisa usual cometer e então eu empurrado para um repositório remoto. Mas então percebi que eu esqueci de organizar meus importações no código fonte. Então eu o comando alterar para substituir a submissão anterior:

> git commit --amend

Infelizmente o commit não pode ser empurrado de volta para o repositório. Ele é rejeitado como esta:

> git push origin
To //my.remote.repo.com/stuff.git/
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to '//my.remote.repo.com/stuff.git/'

O que devo fazer? (I pode acessar o repositório remoto.)

Foi útil?

Solução

Na verdade, eu, uma vez empurrado com --force e .git repositório e tenho repreendido por Linus BIG TIME . Em geral, isso vai criar um monte de problemas para outras pessoas. A resposta simples é "não faça isso".

Eu vejo outros deram a receita para fazê-lo de qualquer maneira, por isso não vou repeti-las aqui. Mas aqui vai uma dica para se recuperar da situação após de ter empurrado o alterada comprometer com --force (ou + master).

  1. Use git reflog para encontrar o velho comprometer que você alterado (chamemos-lhe old, e vamos chamar o novo commit que você criou, através da alteração new).
  2. Criar uma mesclagem entre old e new, registrando a árvore da new, como git checkout new && git merge -s ours old.
  3. Mesclar que a sua principal com git merge master
  4. Atualize seu mestre com o resultado com git push . HEAD:master
  5. Empurre o fora resultado.

As pessoas então que estavam a infelicidade de ter baseado o seu trabalho sobre a cometer você obliterado por que altera e forçando um empurrão verá a fusão resultante vai ver que você é a favor new sobre old. Suas fusões posteriores não verá os conflitos entre old e new que resultaram da sua alteração, para que eles não têm que sofrer.

Outras dicas

Você está vendo uma característica de segurança Git. Git se recusa a atualizar o ramo remoto com o seu ramo, porque a cabeça do seu ramo comprometer não é um descendente direto do atual chefe cometem do ramo que você está empurrando a.

Se não fosse este o caso, então duas pessoas empurrando para o mesmo repositório de mais ou menos ao mesmo tempo não saberia que havia um novo commit entrando ao mesmo tempo e quem empurrou última perderia o trabalho do empurrador anterior sem que nenhum deles percebendo isso.

Se você sabe que você é a única pessoa empurrando e você quer empurrar um alterada cometer ou empurrar um commit que os ventos de volta o ramo, você pode 'forçar' Git para atualizar o ramo remoto usando o interruptor -f.

git push -f origin master

Mesmo isso pode não funcionar como Git permite repositórios remotos de recusar empurrões não fastforward no extremo usando a variável de configuração receive.denynonfastforwards. Se este for o caso, o motivo da recusa será parecido com este (observe a parte 'remoto rejeitou'):

 ! [remote rejected] master -> master (non-fast forward)

Para contornar este problema, você quer necessidade de alterar a configuração do repositório remoto ou como um sujo cortar você pode excluir e recriar o ramo assim:

git push origin :master
git push origin master

Em geral, o último parâmetro para git push usa o <local_ref>:<remote_ref> formato, onde local_ref é o nome do ramo no repositório local e remote_ref é o nome do ramo no repositório remoto. Este par comando usa dois atalhos. :master tem uma local_ref nulo que significa empurrar um ramo nulo para o master lado remoto, ou seja, eliminar a filial remota. Um nome de filial sem meios : empurrar a filial local com o nome dado para o ramo remoto com o mesmo nome. master nesta situação é curto para master:master.

Breve discurso:. O fato de que ninguém publicou a resposta simples aqui demonstra a facilidade de hostilidade desesperado exibido pelo Git CLI

De qualquer forma, a maneira "óbvia" para fazer isso, supondo que você não tentou forçar o impulso, é puxar pela primeira vez. Isso puxa a mudança que você alterada (e assim já não tem) para que você tê-lo novamente.

Depois de ter resolvido todos os conflitos, você pode empurrar novamente.

Assim:

git pull

Se você receber erros de tração, talvez algo está errado na sua configuração de repositório local (eu tinha um ref errado no .git / secção ramo config).

E depois

git push

Talvez você terá um extra comprometer com a narração assunto sobre um "merge Trivial".

Resposta curta:. Não empurre commits alterados para um repositório público

Long resposta: Alguns comandos do Git, como git commit --amend e git rebase, realmente reescrever o gráfico história. Isso é bom, desde que você não publicou as alterações, mas uma vez que você fizer isso, você realmente não deve ser perder tempo com a história, porque se alguém já tem as alterações, em seguida, quando eles tentam puxar novamente, ele pode falhar . Em vez de alterar um commit, você deve apenas fazer um novo comprometer com as mudanças.

No entanto, se você realmente quer empurrar um alterada cometer, você pode fazê-lo como este:

$ git push origin +master:master

O sinal + líder forçará o impulso para ocorrer, mesmo se ele não resultar em um "fast-forward" cometer. (A fast-forward cometer ocorre quando as alterações que estão empurrando são um descendente direto de já as mudanças no repo público.)

Aqui está uma maneira muito simples e limpo para empurrar as alterações depois de já ter feito um commit --amend:

git reset --soft HEAD^
git stash
git push -f origin master
git stash pop
git commit -a
git push origin master

O que faz o seguinte:

  • cabeça ramo Repor pai cometeu.
  • Stash esta última confirmação.
  • Força push to remoto. O controle remoto agora não tem a última confirmação.
  • Pop seu esconderijo.
  • Commit limpa.
  • Push to remoto.

Lembre-se de mudar "origem" e "mestre" se aplicar a um ramo diferente ou remoto.

Eu ter resolvido-lo, descartando minha alterada locais cometer e acrescentando as novas mudanças no topo:

# Rewind to commit before conflicting
git reset --soft HEAD~1

# Pull the remote version
git pull

# Add the new commit on top
git add ...
git commit
git push

Eu tive o mesmo problema.

  • Acidentalmente alterada a última confirmação que já foi empurrado
  • Feito um monte de mudanças localmente, comprometido cerca de cinco vezes
  • tentou empurrar, tenho um erro, em pânico, fundiu remoto, tem um monte de não-meu-arquivos, empurrado, falhou, etc.

Como Git-novato, eu pensei que era completa FUBAR .

Solução: Um pouco como @bara sugeriu + criado um ramo backup local

# Rewind to commit just before the pushed-and-amended one.
# Replace <hash> with the needed hash.
# --soft means: leave all the changes there, so nothing is lost.
git reset --soft <hash>

# Create new branch, just for a backup, still having all changes in it.
# The branch was feature/1234, new one - feature/1234-gone-bad
git checkout -b feature/1234-gone-bad

# Commit all the changes (all the mess) not to lose it & not to carry around
git commit -a -m "feature/1234 backup"

# Switch back to the original branch
git checkout feature/1234

# Pull the from remote (named 'origin'), thus 'repairing' our main problem
git pull origin/feature/1234

# Now you have a clean-and-non-diverged branch and a backup of the local changes.
# Check the needed files from the backup branch
git checkout feature/1234-gone-bad -- the/path/to/file.php

Talvez não seja uma solução rápida e limpa, e eu perdi a minha história (1 comprometer em vez de 5), mas salvou um dia de trabalho.

Se você não empurrou o código para a sua filial remota (GitHub / Bitbucket) você pode mudar a mensagem de log na linha de comando como abaixo.

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

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

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

Se você já empurrou o código com uma mensagem errada, então você precisa ter cuidado ao alterar a mensagem. ou seja depois de alterar a mensagem de confirmação e tentar empurrá-lo novamente você acabar com tendo problemas. Para torná-lo suave seguir os seguintes passos.

Por favor, leia a resposta inteira antes de fazê-lo

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 impulso força diretamente você pode acabar com problemas de código que outros desenvolvedores estão trabalhando no mesmo ramo. Então, para evitar esses conflitos você precisa puxar o código do seu ramo antes de fazer a empurrão força :

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

Esta é a melhor prática quando se muda a mensagem de commit, se ele já foi empurrado.

Se você sabe que ninguém tem puxado o seu un-alteradas cometem, use a opção --force-with-lease de git push.

Em TortoiseGit, você pode fazer a mesma coisa em "Push ..." opções. "Force: descarte de maio" e verificando "alterações conhecidas"

Force (pode descartar conhecido mudanças) permite que o repositório remoto para aceitar um empurrão mais seguro não-fast-forward. Isso pode fazer com que o repositório remoto para commits perder; usá-lo com cuidado. Isso pode evitar a perda de alterações desconhecidos de outras pessoas sobre o controle remoto. Ele verifica se o ramo do servidor aponta para o mesmo cometem como o ramo de rastreamento remoto (mudanças conhecido). Se sim, um empurrão força será realizada. Caso contrário, ela será rejeitada. Desde git não têm etiquetas remoto de rastreamento, tags não podem ser substituídos usando esta opção.

Aqui está uma maneira muito simples e limpo para empurrar as alterações depois de já ter feito um git add "your files" e git commit --amend:

git push origin master -f

ou

git push origin master --force

Você está recebendo este erro porque o Git remoto já tem estes se comprometem a arquivos. Você tem que forçar empurrar o ramo para que isso funcione:

git push -f origin branch_name

Também certifique-se de puxar o código remoto como alguém em sua equipe poderia ter empurrado para o mesmo ramo.

git pull origin branch_name

Este é um dos casos em que temos de forçar empurrar a comprometer-se remota.

Eu tive que corrigir esse problema com puxando a partir do repo remoto e lidar com os conflitos de mesclagem que surgiram, cometer e empurre. Mas eu sinto que há uma maneira melhor.

Eu apenas continuei fazendo o que Git me disse para fazer. Assim:

  • Não consegue empurrar por causa da alterada cometer.
  • Eu faço um puxão como sugerido.
  • mesclagem falha. então eu corrigi-lo manualmente.
  • Criar um novo commit (rotulada "Merge") e empurrá-lo.
  • parece funcionar!

Nota:. O alterada commit foi o mais recente

Aqui, como eu fixo uma edição em um commit anterior:

  1. Salve o trabalho até agora.
  2. Stash suas alterações distância para agora se fez:. git stash Agora sua cópia de trabalho é limpa no estado de seu último commit
  3. Faça as edições e correções.
  4. Confirme as alterações em "alterar" modo: git commit --all --amend
  5. O editor vai aparecer pedindo uma mensagem de log (por padrão, a antiga mensagem de log). Salvar e feche o editor Quando você está feliz com ele.

    As novas mudanças são adicionados ao velho cometer. Veja por si mesmo com git log e git diff HEAD^

  6. Re-aplicar as alterações escondido, se fez: git stash apply

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top