Как перебазироваться на более раннюю удаленную фиксацию?

У меня есть локальный коммит A, и я использовал git pull --rebase origin master, так что теперь A расположен поверх последнего удаленного основного коммита, но я понял, что не хочу этого делать и мне нужно фактически перебазироваться на более раннее видение мастера.

Я нашел хэш коммита earlier_commit_hash, связанный с предыдущим коммитом, и сделал git pull --rebase origin earlier_commit_hash, но, похоже, ничего не изменил (моя локальная ветка по-прежнему включает все коммиты удаленного мастера после earlier_commit_hash).

Каков правильный способ выполнить то, что мне нужно?

Вы можете создать новую ветку (локальную или удаленную), которая имеет более раннюю фиксацию как HEAD, а затем перебазировать эту ветку. Я бы предпочел местный филиал в этом случае. Причина в том, чтобы не оставлять на удаленке никаких ошибок, которые я могу сделать, чтобы потенциально повлиять на других.

Lucas Roberts 06.04.2022 15:09

@LucasRoberts Подождите, скажите, что я сейчас в местном отделении current. Вы говорите, что я должен создать еще одну локальную ветку another, где anotherHEAD указывает на earlier_commit_hash, верно? После этого я не понимаю, что делать. Вы предлагаете мне сделать git pull --rebase another в моей ветке current? Казалось бы, это столкнется с той же проблемой, что и в моем ОП? Или ты предлагаешь from another, мне cherry-pickA?

David 06.04.2022 15:13

Я бы последовал ответу ypnos, за который проголосовали, он чище и содержит меньше команд, чем то, что я описывал.

Lucas Roberts 06.04.2022 15:17
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
42
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

Вместо этого вы можете попробовать rebase --onto. Из справочной страницы:

       A range of commits could also be removed with rebase. If we have the following situation:

               E---F---G---H---I---J  topicA

       then the command

           git rebase --onto topicA~5 topicA~3 topicA

       would result in the removal of commits F and G:

               E---H'---I'---J'  topicA

       This is useful if F and G were flawed in some way, or should not be part of topicA.

Таким образом, вы можете использовать тот же механизм, чтобы точно вырезать все коммиты между ссылкой на master и вашими эксклюзивными для ветки коммитами.

Я попробую это, спасибо. Я объединяю rebase и pull в одну команду. Можно ли использовать git pull --rebase --onto origin earlier_commit_hash?

David 06.04.2022 15:14

Вы должны вызвать git fetch, а затем git rebase вместо git pull, чтобы иметь возможность использовать эту опцию.

ypnos 06.04.2022 15:17

Понял, сейчас попробую. Что означает тильда? Я не уверен, почему git rebase --onto topicA~5 topicA~3 topicA " приведет к удалению коммитов F и G: "

David 06.04.2022 16:01

Понял, думаю, теперь понял

David 06.04.2022 16:16

Если бы я был на вашем месте и моя ветка была бы в вашем состоянии, я бы использовал ответ Ипноса из rebase --onto. Это потому, что это, вероятно, самый эффективный однострочник, и мне удобно его делать.

При этом еще одна вещь, которую вы могли бы сделать, что может быть концептуально немного проще, — это посмотреть на свой reflog, найти фиксацию, в которой была ваша ветка до перебазирования, и вернуть свою ветку в то состояние, в котором она была до перебазирования:

git reset --hard <previous-commit-id>

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

Другие вопросы по теме