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

Принимая во внимание, что есть несколько команд git, которые не имеют смысла в голом репозитории (поскольку голые репозитории не используют индексы и не имеют рабочего каталога),

git reset --hard HEAD^ 

не является решением для отмены последнего изменения в таком репозитории.

Поискав в Интернете, все, что я смог найти по теме, это это , в котором мне представлены три способа сделать это:
1. "обновить реф вручную (что включает сантехнику)";
2. "git push -f из не голого репозитория";
3. " git branch -f this $that".

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


person Lavinia-Gabriela Dobrovolschi    schedule 07.01.2011    source источник
comment
@Lavinia-Garbriela Dobrovol Не используйте сложные вещи ниже. Вы пытаетесь переместить HEAD в другую фиксацию, и для этого предназначен git reset, даже в голом репо. Согласно моему ответу ниже, используйте: git reset --soft ‹commit› С --soft вы не пытаетесь изменить несуществующее рабочее дерево и индекс, поэтому git позволяет вам выполнить сброс без проблем.   -  person Hazok    schedule 12.05.2011


Ответы (4)


Вы можете использовать команду git update-ref. Чтобы удалить последнюю фиксацию, вы должны использовать:

$ git update-ref HEAD HEAD^

Или если вы не в той ветке, из которой не можете удалить последний коммит:

$ git update-ref refs/heads/branch-name branch-name^

Вы также можете передать sha1, если хотите:

$ git update-ref refs/heads/branch-name a12d48e2

См. документацию по команде git-update-ref.

person Sylvain Defresne    schedule 07.01.2011
comment
@ Lavinia-Gabriela Dobrovolschi: верно, я не был знаком с точным синтаксисом. - person VonC; 07.01.2011
comment
@VonC Вы можете указать ‹ref› в git update-ref <ref> <newvalue> как правильную ветвь, например, refs/heads/master вместо HEAD. Надеюсь, я правильно понял ваш вопрос. - person Lavinia-Gabriela Dobrovolschi; 07.01.2011
comment
@Sylvain: +1 хорошее редактирование. @Lavinia-Gabriela Dobrovolschi, спасибо за точность. Это гораздо практичнее (полагаю, если у вас есть прямой доступ к удаленному серверу). - person VonC; 07.01.2011
comment
Примеры вводят в заблуждение относительно аргумента branch-name. При использовании update-ref с «ветвью» вы обязательно должны указать полное имя ссылки на ветку (т.е. добавить refs/heads/ к обычному короткому имени ветки). Если вы просто используете короткое имя, вы в конечном итоге создадите/обновите $GIT_DIR/branch-name вместо $GIT_DIR/refs/heads/branch-name. Существование как branch-name, так и refs/heads/branch-name вызовет предупреждения «refname … is ambiguous». - person Chris Johnsen; 17.05.2011
comment
Этот ответ намного сложнее того, что предложил Зак. И его решение отлично работает. - person Krystian; 07.02.2012

Если вы используете следующее в голом репо:

git reset --soft <commit>

тогда вы не столкнетесь с проблемами, которые у вас есть, используя параметры --hard и --mixed в голом репо, поскольку вы не пытаетесь изменить что-то, чего нет в голом репо (например, рабочее дерево и индекс). В вашем случае конкретно вы хотели бы использовать (из голого репо):

git reset --soft HEAD^

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

git symbolic-ref HEAD refs/heads/<branch_name>

Чтобы увидеть текущую выбранную ветку, используйте:

git symbolic-ref HEAD

https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html

person Hazok    schedule 11.04.2011
comment
Как вы выбираете ветку, которую хотите переместить? Ваш пример отлично работает на мастере, но git checkout other_branch не работает на голом. - person Gauthier; 20.12.2011
comment
Хммм... Мне интересно, кто проголосовал за меня. Вопрос не спрашивал, как переключать ветки в удаленном репо, он спрашивал, как выполнить сброс на голом репо. Чтобы изменить ветку по умолчанию в удаленном репозитории, используйте git symbolic-ref HEAD refs/heads/‹branch_name›. - person Hazok; 20.05.2013

git push -f должно работать нормально:
если вы клонируете это голое репо, удалите последнюю фиксацию (git reset --hard HEAD^, как вы упомянули, но в локальном не голом репо) и отправьте обратно (-f):

  • вы не меняете SHA1 для других коммитов, предшествующих тому, который вы удаляете.
  • вы уверены, что отталкиваете точное содержимое голого репо за вычетом дополнительной фиксации (потому что вы только что сначала клонировали его).
person VonC    schedule 07.01.2011
comment
@ VonC Привет, Вон, я видел, как ты много отвечаешь на Git, поэтому хотел спросить тебя ... Мне было любопытно, почему бы git reset --soft <sha1>, как показано в моем ответе ниже, не быть рекомендуемой практикой для перемещения HEAD на голом репо? - person Hazok; 17.05.2011
comment
Я предполагаю, что еще одна причина, по которой я спрашиваю, заключается в том, что использование программного сброса для голых репозиториев не является легкодоступной информацией, и многие форумы, кажется, имеют излишне сложные обходные пути, когда кажется, что программный сброс является лучшей практикой из-за наименьшего количества ввода и наименьшего шанса за ошибку. - person Hazok; 17.05.2011
comment
@Zach: reset --soft должен работать, когда делается непосредственно на голом репо. Я подозреваю, что это делается редко, потому что репозиторий с открытым исходным кодом, как правило, представляет собой восходящий репозиторий (т. е. репозиторий, в который вы отправляете данные), и в большинстве случаев вы не делаете иметь к нему прямой локальный доступ. Но если вы это сделаете, то это, безусловно, еще один хороший пример использования reset --soft (как в stackoverflow.com/questions/5203535/ ) Итак, +1 к вашему ответу. - person VonC; 17.05.2011

Вы также можете использовать нотацию git refspec и сделать что-то вроде этого:

git push -f origin +<commit you want to revert to>:<destination_head | branch_name>

Это принудительно обновляет ветку назначения (обозначенную ссылкой) до исходной фиксации, обозначенной частью +<object ref>.

person alup    schedule 31.01.2012
comment
кроме случаев, когда на ветке есть акл - что обычно бывает, если нужно сделать на самом голом репо... - person David Schmitt; 31.01.2012