Хотите изменить мой мастер на более старую фиксацию, как я могу это сделать?

92

Я хочу вернуться к предыдущей фиксации, а затем опубликовать этот код, а затем вернуться к последней фиксации.

т.е. мой мастер указывает на более старую версию фиксации, чтобы я мог удалить эту версию, а затем я хочу вернуться к последней фиксации, которой я был изначально.

Как я могу это сделать?

Blankman
источник

Ответы:

100

Если вы хотите сделать это и вернуть мастер к предыдущей фиксации:

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

Альтернативно:

git reset --hard master~1        # Reset current branch to one commit ago on master
Тайлер Брок
источник
1
Итак, год спустя я смотрю на это и думаю, что это ужасный способ сделать это. Ну, по крайней мере, это легко понять.
Тайлер Брок
1
да, именно поэтому я проголосовал за, легко понять, может быть, вам стоило предоставить ссылку на лучший способ?
Эндрю Аткинсон
1
Мне пришлось сделать то же самое с помощью SourceTree. Процесс похожий. 1) создайте новую ветку для текущего состояния мастера, чтобы ничего не потерять. 2) удалить мастер 3) создать новую ветку мастера, выбрав желаемый коммит
Данило Гомес
Что происходит с коммитом, который мы «удалили» из мастера после этого?
Arthur Colombini Gusmão
1
Этого следует избегать, если у вас есть удаленное репо. Если вы это сделаете, это вызовет некоторые ошибки, потому что адрес первого мастера отличается от нового мастера, который вы создали недавно.
MAChitgarha
60

Ваш вопрос непонятен. Я думаю, что вы просите вот что:

git push -f origin $old_commit_id:master

Что это будет делать? Она будет толкать себя $old_commit_idобязательство в originкачестве нового главы origin«S masterотрасли.

Если это то, что вы хотели, вам вообще не нужно трогать местный masterфилиал.

Аристотель Пагальцис
источник
Это стало master (non-fast-forward)для меня неудачей. Решение @jtdubs сработало.
Бобби Нортон,
3
Просто передайте -fего принудительно - хотя удаленное репо может быть настроено так, чтобы это запретить. Я обновил ответ.
Аристотель Пагальцис
у меня не работает, но принятый ответ работает
MobileMon
Вы не сказали точно, что вы хотели или почему это не сработало, поэтому я не могу сказать вам, почему это не так и как это могло быть сделано (если бы это было возможно).
Аристотель Пагальцис
Похоже, что при таком подходе вы теряете прошлую историю удаленно, меня устраивает. Просто вызываю это.
Шон
43

использовать git reset --hard <old commit number>

он сбросит HEAD на этот старый коммит.

Кроме того, вам нужно использовать git push -f originдля изменения удаленного репо.

KawaiKx
источник
34

Если вы хотите избежать принудительного нажатия, вот как вернуть ваше репо к более старому фиксации и сохранить всю промежуточную работу:

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!

Выполнено! Замените 307a5cd любым коммитом, который вы хотите в своем репо.

(Я знаю, что первые две строки можно объединить, но я думаю, что это делает менее понятным, что происходит)

Вот это графически:

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

Вы эффективно удаляете c3 и c4 и снова устанавливаете свой проект на c2. Однако c3 и c4 все еще доступны в истории вашего проекта, если вы когда-нибудь захотите увидеть их снова.

Бронсон
источник
1
Это сработало без сбоев! Если вы зашли так далеко и читаете это - это, кажется, самый чистый способ вернуть мастер к более глубокой фиксации.
ddisqq
Я не могу найти слов, чтобы объяснить, как сильно я тебя за это люблю, я без слов прекрасен, что смог исправить то, из-за чего я уже 6 часов прослушивал и у меня так сильно болела голова. Спасибо, сэр!!!!!!!
Костас Цакалидис
9

Предполагая такой график фиксации:

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

Вы хотите сначала оформить заказ masterи создать ветку, указывающую на masterтекущее местоположение:

git checkout master
git branch pointer master

Теперь должно выглядеть так:

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

Теперь, когда вы уже в процессе master, мы прикажем masterветке переместиться на одну фиксацию назад:

git reset master~1

Теперь masterнужно переместиться на один пробел назад, но pointerветка все еще находится на последней фиксации:

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

На этом этапе вы можете нажать masterна удаленный компьютер или где-либо еще, а затем быстро слить его обратно в pointerветку. Вы можете убить pointerветку в этот момент:

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

Финал:

| (A) ---------> (B) ----------> (C)
|                 ^               ^
|         [ origin/master ]    (HEAD, master)
C0M37
источник
1
Если origin / master находится на C, git push origin masterпроизойдет сбой, так как кончик вашей текущей ветки находится за своим удаленным аналогом . Вы также должны передать флаг -f.
sassospicco
8

Вы можете просто git checkout <commit-id>сделать все, что вам нужно, а затем git checkout masterвернуться к новому коду.

Если вам действительно нужно изменить старый код, чтобы выпустить его, вам, вероятно, следует:

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

Кроме того, я не могу рекомендовать git flow достаточно. Все это довольно просто.

jtdubs
источник
1

Чтобы перейти к предыдущей версии:

git checkout <version hash>

делай свою работу здесь и совершай ее с

git commit --amend

Чтобы вернуться к мастеру :

git checkout master

Пабло Фернандес
источник
1
Это не сработает. git reset --hardуказал своей главной веткой обратно на старую фиксацию, поэтому git checkout masterничего не будет делать.
jtdubs 05
Правда, спасибо за исправление. +1 к вам, я бы тоже удалил свой ответ, но я думаю, что этот commit --amendшаг достаточно полезен
Пабло Фернандес
Что --amend?
Шафизаде