Quer mudar meu master para um commit mais antigo, como posso fazer isso?

90

Eu quero reverter para um commit anterior e, em seguida, publicar esse código e, em seguida, voltar para o commit mais recente.

ou seja, meu master está apontando para uma versão de commit mais antiga apenas para que eu possa puxar essa versão, então eu quero voltar para o commit mais recente que eu era inicialmente.

Como posso fazer isso?

Blankman
fonte

Respostas:

99

Se você quiser fazer isso e reverter o master para o commit anterior:

git checkout master~1            # Checkout previous commit on master
git checkout -b new_master       # Create branch for new master
git branch -D master             # Delete old master
git branch -mv new_master master # Make new_master master

Alternativamente:

git reset --hard master~1        # Reset current branch to one commit ago on master
Tyler Brock
fonte
1
Então, um ano depois, estou olhando para isso e pensando que essa é uma maneira horrível de fazer isso. Bem, pelo menos é um pouco fácil de entender.
Tyler Brock
1
sim é por isso que votei positivamente, fácil de entender, talvez você devesse ter apresentado um link para uma forma melhor?
Andrew Atkinson,
1
Tive que fazer o mesmo usando SourceTree. O processo é semelhante. 1) crie uma nova ramificação para o estado mestre atual, para que você não perca nada. 2) deletar master 3) criar novo branch master, selecionando o commit desejado
Danilo Gomes
O que acontece com o commit que "removemos" do master depois disso?
Arthur Colombini Gusmão
1
Isso deve ser evitado se você tiver um repo remoto. Isso causa alguns erros se você fizer isso, porque o endereço do primeiro mestre é diferente do novo mestre que você criou recentemente.
MAChitgarha
55

Sua pergunta não está clara. Acho que o que você está pedindo é:

git push -f origin $old_commit_id:master

O que isso vai fazer? Ele vai empurrar a $old_commit_idcomprometer-se origincomo o novo chefe originda masterfilial.

Se isso é o que você queria, não precisa tocar em sua masterfilial local .

Aristotle Pagaltzis
fonte
Isso causou um master (non-fast-forward)fracasso para mim. A solução @jtdubs funcionou.
Bobby Norton
3
Basta passar -fpara forçá-lo - embora o repo remoto possa ser configurado para proibir isso. Eu atualizei a resposta.
Aristóteles Pagaltzis,
não funciona para mim, a resposta aceita sim
MobileMon
Você não disse exatamente o que queria ou por que não funcionou, então não posso dizer por que não funcionou e como poderia ter sido feito (se pudesse).
Aristóteles Pagaltzis
Você parece perder a história do passado remotamente com essa abordagem, foi bom para mim. Apenas chamando.
Shawn
43

usar git reset --hard <old commit number>

ele irá redefinir o HEAD para este antigo commit.

além disso, você precisa usar git push -f originpara alterar o repositório remoto também.

KawaiKx
fonte
30

Se você deseja evitar forçar push, veja como reverter seu repo para um commit mais antigo e preservar todo o trabalho intermediário:

git checkout 307a5cd        # check out the commit that you want to reset to 
git checkout -b fixy        # create a branch named fixy to do the work
git merge -s ours master    # merge master's history without changing any files
git checkout master         # switch back to master
git merge fixy              # and merge in the fixed branch
git push                    # done, no need to force push!

Feito! Substitua 307a5cd pelo commit que você quiser em seu repo.

(Eu sei que as duas primeiras linhas podem ser combinadas, mas acho que isso torna menos claro o que está acontecendo)

Aqui está graficamente:

c1 -- c2 -- c3 -- c4 -- c2' -- c5 ...
        \              /
         '------------'

Você remove efetivamente c3 e c4 e define seu projeto de volta para c2. No entanto, c3 e c4 ainda estão disponíveis no histórico do seu projeto se você quiser vê-los novamente.

bronson
fonte
1
Isso funcionou sem problemas! Se você chegou até aqui e está lendo isso - esta parece ser a maneira mais limpa de reverter o master para um commit mais profundo.
ddisqq
Não consigo encontrar palavras para explicar o quanto eu te amo por isso, estou grato além das palavras por conseguir consertar algo que me irritou por 6h agora e me causou tanta dor de cabeça. Obrigado senhor !!!!!!!
Kostas Tsakalidis
9

Supondo um gráfico de confirmação como:

| (A) ---------> (B) ----------> (C)
|                                 ^
|                              (master)

Você deseja primeiro fazer check master- out e criar um branch que aponta para onde masteratualmente está:

git checkout master
git branch pointer master

Deve ficar assim agora:

| (A) ---------> (B) ----------> (C)
|                                 ^
|                       (HEAD, master, pointer)

Agora que você já está ligado master, diremos ao masterbranch para retroceder um commit:

git reset master~1

Agora, masterdeve ser movido um espaço para trás, mas o pointerbranch ainda está no commit mais recente:

| (A) ---------> (B) ----------> (C)
|                 ^               ^
|           (HEAD, master)    (pointer)

Neste ponto, você pode enviar masterpara um controle remoto ou qualquer outro lugar e, em seguida, avançar rapidamente e mesclá-lo de volta ao pointerbranch. Você pode matar o pointergalho nesse ponto:

git push origin master
git merge --ff-only pointer
git branch -D pointer

Final :

| (A) ---------> (B) ----------> (C)
|                 ^               ^
|         [ origin/master ]    (HEAD, master)
C0M37
fonte
1
Se origin / master estiver em C, git push origin masterirá falhar com a ponta de seu branch atual atrás de sua contraparte remota . Você também deve passar um sinalizador -f.
sassospicco
8

Você pode apenas git checkout <commit-id>fazer o que for necessário para git checkout mastervoltar ao novo código.

Se você realmente precisa modificar o código antigo para liberá-lo, provavelmente deve:

git checkout -b my_release <commit-id>
... prepare code for release ...
... release code ...
git checkout master
git merge my_release

Além disso, não posso recomendar o git flow o suficiente. Isso torna tudo muito fácil.

jtdubs
fonte
1

Para mover para uma versão anterior:

git checkout <version hash>

faça o seu trabalho aqui e comprometa-o com

git commit --amend

Para voltar ao mestre :

git checkout master

Pablo Fernandez
fonte
1
Isso não vai funcionar. git reset --hardapontou seu branch master de volta para o commit antigo, então git checkout masternão fará nada.
jtdubs
Verdade, obrigado pela correção. +1 para você, removeria minha resposta também, mas acho que a commit --amendetapa é útil o suficiente
Pablo Fernandez
O que é --amend?
Shafizadeh