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


92

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

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

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

Ответы:


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для изменения удаленного репо.


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)

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 достаточно. Все это довольно просто.


1

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

git checkout <version hash>

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

git commit --amend

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

git checkout master


1
Это не сработает. git reset --hardуказал своей главной веткой обратно на старую фиксацию, поэтому git checkout masterничего не будет делать.
— jtdubs 05

Правда, спасибо за исправление. +1 к вам, я бы тоже удалил свой ответ, но я думаю, что этот commit --amendшаг достаточно полезен
— Пабло Фернандес

Что --amend?
— Шафизаде
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.