120

У меня есть 2 коммита, которые я не нажимал:

$ git status
# On branch master
# Your branch is ahead of 'faves/master' by 2 commits.

Как я могу откатить свой первый (самый старый), но оставить второй?

 $ git log
commit 3368e1c5b8a47135a34169c885e8dd5ba01af5bb
...

commit baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e
...

Отсюда:

http://friendfeed.com/harijay/742631ff/git-question-how-do-i-rollback-commit-just-want

Мне просто нужно сделать:

git reset --hard baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e

То есть?

9 ответов9

92

Самый безопасный и, вероятно, самый чистый путь - это интерактивная перебазировка.

git rebase -i HEAD^^

Или же,

git rebase -i baf8d5e7da9e41fcd37d63ae9483ee0b10bfac8e^

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

Вы можете отменить коммит с помощью git revert но он собирается добавить больше сообщений коммита в историю, что может быть нежелательно. Используйте параметр -n чтобы сказать Git, что не следует сразу же возвращать результат. Вы можете перебазировать в интерактивном режиме и раздавить их до предыдущего коммита, чтобы сохранить вещи в чистоте.

Если два коммита, с которыми вы работаете здесь, влияют на один и тот же файл (ы), вы можете увидеть конфликт слияния.

Сброс хранилища с помощью git reset --hard следует выполнять с осторожностью, поскольку его нельзя отменить.

Переписывать историю следует с осторожностью.

48

Это если с http://nakkaya.com/2009/09/24/git-delete-last-commit/ и у меня это сработало

Git Удалить последний коммит

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

Если вы совершили мусор, но не столкнулись,

git reset --hard HEAD~1

HEAD ~ 1 - это сокращение для коммита перед головой. В качестве альтернативы вы можете обратиться к SHA-1 хэша, который вы хотите сбросить. Обратите внимание, что при использовании --hard любые изменения в отслеживаемых файлах в рабочем дереве, начиная с фиксации перед заголовком, теряются.

Если вы не хотите уничтожать проделанную вами работу, вы можете использовать опцию --soft , которая удалит коммит, но оставит все ваши измененные файлы "Изменения будут зафиксированы", как будет указано в git status.

Теперь, если вы уже нажали, а кто-то нажал, что обычно является моим случаем, вы не можете использовать git reset. Вы можете, однако, сделать мерзавец,

git revert HEAD

Это создаст новый коммит, который перевернет все, что было введено случайным коммитом.

8

Нету. git-reset --hard вернет вас в историю. То, что вы ищете, это git revert, который отменит любой коммит.

5

Я только что сделал это:

git rebase -i HEAD^^

Я облажался, так что я сделал

git rebase --abort

Затем сделал это снова. Тогда я должен был толкать так:

git push origin master -f

И это уничтожило коммиты более новые, чем коммит, к которому я откатился. Работал отлично.

4

Что касается комментария jtimberman о git reset --hard быть отменяемым, это не совсем верно. Смотрите здесь: https://stackoverflow.com/questions/5473/undoing-a-git-reset-hard-head1

4

Нет, git reset --hard baf8d5e удалит коммит 3368e1c а HEAD впоследствии будет на baf8d5e .

Если вы хотите сохранить коммит 3368e1c и удалить коммит bad8d5e самое простое решение - выполнить « git rebase -i HEAD~2 » (т.е. интерактивный перебаз двух последних коммитов). Эта команда запустит ваш редактор сообщений о коммите, и вы увидите одну строку для каждого из двух последних коммитов. Там вы просто удаляете строку фиксации bad8d5e и сохраняете. git перезапишет вашу историю, и второй коммит исчезнет.

Есть и другие полезные команды, которые вы можете использовать в редакторе сообщений фиксации, такие как squash , edit и т.д. Интерактивная перебазировка ОЧЕНЬ мощна!

Не делайте этого, если кто-то уже видел эти коммиты (нажмите или потяните из вашего репозитория)!

2
git checkout <treeish> -- /path/to/dir

Это вернет каталог из указанного «дерева» для /path /to /dir

1
git reset --hard {ref}

это единственный способ отменить коммит, если в репо есть только один коммит (например, начальный коммит и еще 1). Остальные способы (revert, rebase) отказываются работать, по крайней мере, с git 1.7.5.1.

Если вы выполните git reset с помощью git gc то git фактически полностью удалит старые данные коммита из репозитория.

0

Я заставил это работать, вручную отредактировав хэш-коды последних коммитов из HEAD-файлов внутри папки репозитория:

"centralRepository\refs\heads\master"
"centralRepository\refs\heads\branch2"

До этого мне никогда не удавалось заставить UNMERGE выполнять операции, которые я выполнял локально. Он продолжал говорить, что "не смог подтолкнуть некоторые ссылки" в Центральный репозиторий.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .