Git, Como redefinir a origem / mestre para um commit?


245

Redefino meu mestre local para uma confirmação por este comando:

git reset --hard e3f1e37

Quando eu insiro o $ git statuscomando, o terminal diz:

# On branch master
# Your branch is behind 'origin/master' by 7 commits, and can be fast-forwarded.

#   (use "git pull" to update your local branch)
#
nothing to commit, working directory clean

Como também desejo redefinir a origem / cabeçalho, efetue o checkout para origin / master:

$ git checkout origin/master
Note: checking out 'origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 2aef1de... master problem fixed for master. its okay now.

e redefina o cabeçalho por este comando:

$ git reset --hard e3f1e37
HEAD is now at e3f1e37 development version code incremented for new build.

Então tentei adicionar commit à origem / cabeçalho que não obtive êxito.

$ git commit -m "Reverting to the state of the project at e3f1e37"
# HEAD detached from origin/master
nothing to commit, working directory clean

Finalmente, faço o checkout para meu mestre local.

$ git checkout master
Switched to branch 'master'
Your branch is behind 'origin/master' by 7 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Desde que, redefini a cabeça de origem / mestre, espero que local e origem devam estar na mesma direção, mas como você vê, o git está dizendo que meu local / mestre está atrás de origem / mestre por 7 commits.

Como posso corrigir esse problema? O que estou procurando é o chefe do local / mestre e a origem / mestre apontam para o mesmo commit. A imagem a seguir mostra o que eu fiz. Obrigado.

insira a descrição da imagem aqui


Antes de mais nada, verifique se você tem permissão para código de impulso força para um ramo protegidos em seu projeto, caso contrário você não será capaz ...
DarmVillegas

Respostas:


563

origin/xxxramos são sempre ponteiros para um controle remoto. Você não pode vê-los porque eles não são ponteiros para o seu repositório local (você apenas faz o checkout do commit. É por isso que você não verá o nome escrito no marcador de ramificação da interface da linha de comandos, apenas o hash de commit).

O que você precisa fazer para atualizar o controle remoto é forçar as alterações locais a serem dominadas:

git checkout master
git reset --hard e3f1e37
git push --force origin master
# Then to prove it (it won't print any diff)
git diff master..origin/master

9
isso faz a operação solicitada, mas lembre-se de que isso deixará as pessoas que já retiraram os commits do master.
Mnagel

Eu segui esses passos e ele retrocedeu. Mas a origem / HEAD agora está apontando para um ramo que não seja o mestre. Oque posso fazer para consertar isso?
Daniil Shevelev

1
Você não deve se importar com a origem / HEAD, basta empurrar o bom árbitro para origin / ref
Simon Boudrias

Concordou, teve que fazer isso hoje depois de fundir acidentalmente os ramos errados e depois avançar para a origem. Funciona bem, mas pode ser muito perturbador se outras pessoas estiverem verificando os ramos afetados desde a origem. Use com cuidado.
Nick W.

1
Não funciona remote: error: denying non-fast-forward refs/heads/master (you should pull first)
precisa saber é o seguinte

52

A solução encontrada aqui nos ajudou a atualizar o mestre para um commit anterior que já havia sido enviado:

git checkout master
git reset --hard e3f1e37
git push --force origin e3f1e37:master

A principal diferença da resposta aceita é o hash de confirmação "e3f1e37:" antes do mestre no comando push.


1
Não funciona:remote: error: denying non-fast-forward refs/heads/master (you should pull first)
m0skit0

@ m0skit0 como a mensagem da palavra you should pull first:)
intuitivepixel

A resposta para isso está em stackoverflow.com/a/10544328/1019307 - git config receive.denynonfastforwards falsemas, na verdade, defino isso manualmente no meu repositório git local /opt/gitque criei para brincar com as idéias aqui. Não tenho certeza de como ou se isso pode ser feito para bitbucket, github etc.
HankCa

Olá @jkovacs, não quero que novas alterações no master sejam removidas. Eu só quero enviar esse hash de confirmação "e3f1e37" para o mestre de origem. É possível pular o segundo comando git reset --hard "e3f1e37"?
KarenAnne

Olá @jkovacs, acabei de confirmar que posso pular a segunda etapa. :)
KarenAnne

2

Supondo que sua ramificação seja chamada masteraqui e remotamente, e que seu controle remoto seja chamado, originvocê pode:

git reset --hard <commit-hash>
git push -f origin master

No entanto, você deve evitar fazer isso se mais alguém estiver trabalhando com seu repositório remoto e tiver feito suas alterações. Nesse caso, seria melhor reverter os commits que você não deseja e depois pressionar normalmente.


1

Como tive uma situação semelhante, pensei em compartilhar minha situação e como essas respostas me ajudaram (obrigado a todos).

Então, decidi trabalhar localmente, alterando meu último commit toda vez que quisesse salvar meu progresso no ramo principal (eu sei, eu deveria ter me ramificado, comprometido com isso, continuado pressionando e depois voltando ao master).

Certa noite, com um medo paranóico de perder meu progresso em falha de hardware ou algo fora do éter, decidi levar o mestre à origem. Mais tarde, eu continuei alterando minha filial principal local e, quando decidi que era hora de pressionar novamente, fui confrontado com diferentes ramificações principais e descobri que não posso alterar a origem / upstream ( duh! ) Como posso ramificar as ramificações locais.

Portanto, não fiz o checkout do mestre localmente porque já estava atrás de uma confirmação. O mestre permaneceu inalterado. Eu nem precisei redefinir --hard, meu commit atual estava OK.

Eu apenas forcei o push à origem, sem especificar o que eu queria forçar no master, pois nesse caso é o que quer que seja o HEAD. Verificado git diff master..origin/masterpara que não houvesse diferenças e é isso. Tudo consertado. Obrigado! (Eu sei, eu sou um novato imbecil, por favor, perdoe!).

Portanto, se você já está bem com seu ramo mestre localmente, apenas:

git push --force origin master
git diff master..origin/master
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.