Как мне «повторно открыть» коммит git?

#git #mercurial #rebase

#git #mercurial #перебазировать

Вопрос:

(Обратите внимание, я не ищу ответ git rebase -i )

В mercurial я могу «повторно открыть» коммит, импортировав его в свою очередь исправлений:

 hg qimport tip
  

Коммит «открыт» в том смысле, что он такой же, как и до того, как я его совершил, я могу вернуться, выполнить hg diff , hg status и т.д. Как мне это сделать в git?

(Все, что я нашел в Интернете, предлагает git rebase -i , а затем выберите редактировать, но это другое, потому что коммит не «открыт» таким же образом.)

Комментарии:

1. Другой вариант — оставить коммит там, изменить еще некоторые вещи, а затем использовать их для внесения изменений в коммит ( git commit --amend ).

Ответ №1:

Вам просто нужно переместить указатель HEAD вверх, не внося никаких изменений в вашу рабочую копию:

 git reset --soft HEAD^
  

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

HEAD — это «волшебный» указатель git, который всегда указывает на текущую ссылку (т. Е. Родительский элемент вашей рабочей копии). Курсор (^) указывает на родительский элемент. Вы можете использовать это повторно, например, HEAD ^^ ссылается на родительский элемент последнего коммита.

Комментарии:

1. Отличный ответ, спасибо! Не могли бы вы отметить, что вы теряете сообщение о фиксации, как это сделал @wulong?

2. Если вы действительно хотите использовать его повторно, HEAD^^^^^ это то же самое, что HEAD~5 . (А точнее, HEAD это символическая ссылка, указывающая на текущую извлеченную ветвь, которая указывает на текущую извлеченную фиксацию или прямо на фиксацию, если вы находитесь в состоянии отсоединенной головы, без извлеченной ветви.)

3. @PaulBiggar: Избежать потери сообщения о фиксации — отличная причина для внесения изменений вместо сброса. Однако, если вы выполните сброс, вы все равно можете косвенно восстановить сообщение о фиксации. HEAD@{1} относится к ранее извлеченной фиксации, которая (если вы ничего больше не сделали) будет фиксацией перед сбросом. Вы можете использовать git commit -c HEAD@{1} , чтобы использовать его сообщение о фиксации в качестве отправной точки. (Если с тех пор вы переместили HEAD, вы можете использовать git reflog , чтобы найти коммит дальше в журналах повторных записей.)

4. @PaulBiggar Неточно говорить, что при этом вы теряете сообщение о фиксации, поскольку Git все еще сохраняет его с этим коммитом (который не теряется до тех пор, пока ссылки без каких-либо указателей не будут удалены). Вы можете увидеть это с помощью git reflog . Как упоминал Джефроми, вы можете ссылаться на сообщение другого коммита с -c флагом, но почти всегда проще просто скопировать-вставить или переписать его (по моему опыту, в любом случае).

Ответ №2:

Предполагая, что вы еще не отправили его в свой удаленный репозиторий, git reset --soft HEAD^ «повторно откроете» свой последний коммит за счет потери вашего сообщения о фиксации.

Ответ №3:

Вы можете достичь того же результата с помощью git commit --amend .

Смотрите сравнительную таблицу между Hg и Git.

Ответ №4:

Скотт Чакон (замечательно) подробно рассказал о команде ‘git reset’:http://progit.org/2011/07/11/reset.html Не стесняйтесь взглянуть на это.