Git: Como ignorar avanço rápido e reverter origem para commit anterior?

eu usei

 git reset --hard dc082bc ... 

para reverter para o ramo de volta a um estado anterior obrigatório, devido a alguns commits ruins. Isso rebobinou meu ramo local. No entanto, eu quero voltar a ramificação em ‘origem’ para o mesmo commit para que eu possa começar de novo. Alguém poderia me dizer como reverter o ramo de origem (não mestre) para este commit?

Eu tentei git push origem mestre, mas dá o seguinte erro

  !  [rejeitado] branch -> branch (não-fast-forward)
 erro: falha ao enviar algumas refs para 'git@github.com: xxx / xxx.git'
 Para evitar que você perca o histórico, as atualizações de não avanço rápido foram rejeitadas
 Mesclar as alterações remotas antes de pressionar novamente.  Veja a 'Nota sobre
 seção 'fast-forwards' de 'git push --help' para detalhes.

Você pode tentar git push --force para forçar o push.

 --force 

Normalmente, o comando se recusa a atualizar uma referência remota que não seja um ancestral da referência local usada para sobrescrevê-la. Este sinalizador desativa o cheque.
Isso pode fazer com que o repository remoto perca commits; use-o com cuidado.

Então, se muitas pessoas já tiverem retirado o mesmo branch da origem, isso pode causar algum problema de rebase do lado deles.
Essa operação pode ser bloqueada no lado do servidor, como ebneter aponta (nos comentários):

Dependendo de como o controle remoto está configurado, isso pode não funcionar
– todos os meus receive.denyNonFastForwards = true centrais são configurados com receive.denyNonFastForwards = true e receive.denyDeletes = true , caso em que qualquer cirurgia desse tipo deve ser feita no servidor remoto.

No entanto, no caso do GitHub, essas configurações não estão prontamente disponíveis para o usuário que gerencia seu repository GitHub.
Então, se você git push --force por engano, tudo o que resta é abrir um caso para o suporte do GitHub , para eles verificarem seus reflexos locais (ie “GitHub”) e ver se eles podem restaurar commits antigos.
(Já que os reflogs são locais, como eu fui lembrado recentemente . Então commits que são substituídos por novos durante push --force ainda só são visíveis, se nenhum ‘ git gc ‘ ou ‘ git prune ‘ já tiver ocorrido, no GitHub lado do servidor)

Então Marco Ceppi insiste (nos comentários):

isso pode atrapalhar outros repositores locais se você forçar os pushs – embora as vezes seja apenas um mal necessário (talvez eu tenha feito isso duas vezes na minha vida útil usando o Git)

Para adicionar à minha resposta anterior , e para abordar o fato de que um git push forçado pode realmente atrapalhar os repositorys locais de outros contribuidores, o git 1.8.5 (próximo Q4 de 2013) verá uma nova opção:

 git push --force-with-lease 

Veja a origem dessa opção neste tópico :

Se algo acontecer em ‘ origin ‘ ao ramo que você está forçando ou excluindo desde que você buscou inspecioná-lo, você pode acabar perdendo o trabalho de outras pessoas .

Alguém que não tenha conhecimento da decisão de rebobinar e reconstruir o ramo pode tentar empurrar para o ramo entre o tempo que você buscou para rebase-lo e o tempo que você pressionou para substituí-lo com o resultado do rebasing.

Nós podemos make these pushes safer , permitindo opcionalmente que o usuário diga ” git push ” isto:

Estou forçando / excluindo, com base na suposição de que o valor de ‘branch’ ainda está nesse object.
Se essa suposição não mais se sustentar, ou seja, se algo aconteceu ao ramo desde que comecei a me preparar para esse esforço, por favor, não prossiga e falhe nesse empurrão.

Você pode ver a documentação completa de --force-with-lease in commit 28f5d17

--force-with-lease protegerá todas as referências remotas que serão atualizadas, exigindo que seu valor atual seja o mesmo que um padrão razoável, a menos que especificado de outra forma;

Por enquanto, “algum padrão razoável” é provisoriamente definido como “o valor da ramificação de rastreamento remoto que temos para a referência do remoto sendo atualizado”, e é um erro se não tivermos essa ramificação de rastreamento remoto.

Isso explica a parte “lease” dessa opção:

force-with-lease “: você supõe que você fez o lease no ref quando você foi buscar para decidir qual deveria ser o histórico rebased, e você pode fazer push somente se o lease não tiver sido quebrado.


Isso já está sendo testado e mencionado em ” O que há de cozinhar em git.git (Ago de 2013, # 07; Qua, 28) “:

By the way, o impulso que substitui o habitual “deve fast-forward” foi feito usando a opção ” force-with-lease ” que foi cozinhar em next , da next forma:

 $ git fetch ko next $ anchor=$(git rev-parse --verify FETCH_HEAD) $ for remote in ko repo gph github2 do git push --force-with-lease=refs/heads/next:$anchor $remote next done 

Nota: ” git push --force-with-lease ” foi ensinado a informar se o push precisava forçar (ou avançar rapidamente).

Então este comando é mais detalhado em sua saída com o git 2.8 (março 2016)

push: corrigir relatório de status de referência para --force-with-lease

A opção de envio --force--with-lease leva a informações de status menos detalhadas que --force .
Em particular, a saída indica que uma referência foi rápida, mesmo quando foi atualizada.


Cuidado com essa opção sendo ignorada / ignorada, conforme explicado no Git 2.13 (Q2 2017) .