После git rebase --hard, почему ветка моей темы не изменилась? - PullRequest
1 голос
/ 22 апреля 2019

Я случайно перебазировал свою ветку веткой DEV, а затем перенес ее в удаленный репозиторий.С помощью rebase я выбрал текущие изменения и, следовательно, мои локальные изменения были перезаписаны.

Я потерял свой предыдущий коммит в rebase, но нашел его, запустив git log.Затем я бежал git checkout commitId и даже git reset --hard commitId.Тем не менее, в обоих случаях моя кодовая база по-прежнему показывает последний перебазированный код в моей ветке.

Как мне вернуть свою ветвь в прежнее состояние?

Ответы [ 2 ]

1 голос
/ 22 апреля 2019

Отдельно Что?Чувак, где мой коммит?

Проверка хэша коммита или имени объекта входит в то, что в документации git называется состояние отсоединенного HEAD .

Иногдаполезно иметь возможность извлекать коммит, который не находится на кончике какой-либо именованной ветви, или даже создавать новый коммит, на который не ссылается именованная ветвь.Давайте посмотрим, что происходит, когда мы фиксируем коммит b (здесь мы показываем [три] способа, как это можно сделать):

$ git checkout v2.0      # or
$ git checkout master^^  # or
$ git checkout b

   HEAD (refers to commit 'b')
    |
    v
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

Обратите внимание, что независимо от того, какую команду checkout мы используем, HEAD теперь относится непосредственно к коммиту b .Это известно как находящееся в отдельном состоянии HEAD.Это просто означает, что HEAD относится к конкретному коммиту, а не к именованной ветви.

Как вы заметили, git с удовольствием создаст новые коммиты, перебазирует, объединит и так далее сотделенный заголовок, но поскольку ни одна метка или ветвь не ссылаются на результирующую неназванную ветвь, потерять ее будет легко.Вы смогли найти свой оригинальный коммит с помощью git log.Когда вы сделали более радикальную операцию, вы можете посмотреть результат git reflog.

Исправление

Исправление вашей ветви, как описано в вашем вопросе, будет включатьследующая последовательность:

  1. Повторно подключите HEAD к вашей ветви (далее именуемой topic/my-branch)
  2. Сброс topic/my-branch туда, где он был до
  3. Исправьте origin/topic/my-branch из более раннего толчка.
    • Либо сделайте все сразу с принудительным нажатием, либо
    • Удалите старую удаленную ветку и протолкните вашу фиксированную историю

Reattach HEAD

Вместо того, чтобы использовать хэш SHA-1, проверьте вашу ветку по имени

git checkout topic/my-branch

Исправьте ваше местное отделение

Затем положите его туда, где он был с git reset --hard.Вы будете использовать ту же команду, но контекст будет другим: HEAD после git checkout указывает на topic/my-branch, а не на commitId напрямую.

git reset --hard commitId

Исправитьудаленная ветка

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

git push --force origin topic/my-branch

Администратор удаленного репозитория, возможно, предпринял весьма разумный шаг, чтобы запретить принудительные нажатия (почему, см. Ниже).Если это так, попробуйте последовательность

  1. Удалите ветку на удаленной стороне, а затем
  2. Нажмите исправленную локальную ветку

В старом плохомВ наши дни нам приходилось удалять удаленные ветви с неочевидными

git push origin :topic/my-branch

, но в настоящее время они пишутся

git push --delete origin topic/my-branch

Очистив путь, теперь нажмите на свою ветку, чтобы вернуть вещи обратногде они были раньше.

git push origin topic/my-branch

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

Слова предостережения

Большую часть времени вам приходится много работать, чтобы убедить Git уничтожить работу.Однако git reset --hard, удаление удаленных веток и git push --force - все это острые инструменты - полезные, когда они вам нужны, но опасные при небрежном использовании.Как и в случае rm -rf, сделайте паузу, чтобы подумать, действительно ли вы имеете в виду команду, которую собираетесь запустить.

1 голос
/ 22 апреля 2019

Я подозреваю небольшую путаницу в порядке команд здесь. Если вы сделали

git checkout <commitId>

он отсоединит ваш HEAD затем ваш последующий

git reset --hard <commitId>

не имел никакого эффекта, так как в настоящее время ни одна ветвь не извлечена.

Оформите ветку перед сбросом, и все будет хорошо:

git checkout <yourBranchName>
git reset --hard <commitId>
...