Как отменить commit и не облажаться
Возьмем простую ситуацию: разработчик решает реализовать математические функции. Но на половине пути понимает, что данную задачу было бы хорошо декомпозировать, допустим, на две подзадачи:
Проверять будет проще да и тестировать. Но он уже начал ее реализовывать, коммиты уже созданы, и что же делать? Не переписывать же!
git revert
Работа кипит и осталось дело за малым — смерджить мастер с данными ветками.
И что же мы получили? Ни класса Arithmetic, ни класса Numerical!
А все дело в том, что команда git revert создает новый коммит с отменой изменений и не удаляет из истории коммиты. И в нашем случае после слияния веток получается 4 коммита:
То есть вариант с отменой изменений с помощью команды revert вышел нам боком.
git reset
git rebase
Есть еще одно решение — использовать команду git rebase для отмены изменений.
Вернемся к моменту создания двух веток numerical и arithmetic и выполним
Теперь на уровне каждого коммита, который мы хотим отменить заменим pick на drop. И тогда выбранные нами коммиты сбросятся из истории. Например в ветке numerical :
Тогда в истории у нас останутся только нужные нам коммиты.
Теперь при слиянии веток в master получим оба класса.
Данный метод рабочий, только при условии работы в частной ветке, но если эти манипуляции провести в общей ветке, то при публикации ( git push ) git сообщает, что ветка устарела, так как в ней отсутствуют коммиты и отменяет публикацию.
Чтобы не бороться с git, старайтесь декомпозировать задачи заранее, а то можете словить сюрприз. Сталкивались ли вы с такими ситуациям, и если да, то как выходили из них?
Git для начинающих. Часть 9. Как удалить коммит в git?
Рассмотрим довольно важный вопрос: как удалить коммит в git? Начнем с вопроса отмены изменений в рабочей директории, после этого перейдем к репозиторию. В рамках этой темы изучим вопросы удаления и замены последнего коммита, работу с отдельными файлами и использование команд git revert и git reset.
Отмена изменений в файлах в рабочей директории
Если вы сделали какие-то изменения в файле и хотите вернуть предыдущий вариант, то для этого следует обратиться к репозиторию и взять из него файл, с которым вы работаете. Таким образом, в вашу рабочую директорию будет скопирован файл из репозитория с заменой. Например, вы работаете с файлом main.c и внесли в него какие-то изменения. Для того чтобы вернуться к предыдущей версии (последней отправленной в репозиторий) воспользуйтесь командой git checkout.
Отмена коммитов в git
Работа с последним коммитом
Для демонстранции возможностей git создадим новый каталог и инициализируем в нем репозиторий.
Добавим в каталог файл main.c.
Отправим изменения в репозиторий.
Внесем изменения в файл.
И сделаем еще один коммит.
В репозиторий, на данный момент, было сделано два коммита.
Теперь удалим последний коммит и вместо него отправим другой. Предварительно изменим содержимое файла main.c.
Отправим изменения в репозиторий с заметой последнего коммита.
Как вы можете видеть: из репозитория пропал коммит с id=d142679, вместо него теперь коммит с id=18411fd.
Отмена изменений в файле в выбранном коммите
Сделаем ещё несколько изменений в нашем файле main.c, каждое из которых будет фиксироваться коммитом в репозиторий.
Помните, что в предыдущем разделе мы поменяли коммит с сообщением “second commit” на “third commit”, поэтому он идет сразу после “first commit”.
Представим ситуацию, что два последних коммита были неправильными, и нам нужно вернуться к версии 18411fd и внести изменения именно в нее. В нашем примере, мы работаем только с одним файлом, но в реальном проекте файлов будет много, и после коммитов, в рамках которых вы внесли изменения в интересующий вас файл, может быть ещё довольно много коммитов, фиксирующих изменения в других файлах. Просто так взять и удалить коммиты из середины ветки не получится – это нарушит связность, что идет в разрез с идеологией git. Одни из возможных вариантов – это получить версию файла из нужного нам коммита, внести в него изменения и сделать новый коммит. Для начала посмотрим на содержимое файла main.c из последнего, на текущий момент, коммита.
Для просмотра содержимого файла в коммите с id=18411fd воспользуемся правилами работы с tree-ish (об этом подробно написано здесь)
Переместим в рабочую директорию файл main.c из репозитория с коммитом id=18411fd.
Мы видим, что теперь содержимое файла main.c соответствует тому, что было на момент создания коммита с id=18411fd. Сделаем коммит в репозиторий и в сообщении укажем, что он отменяет два предыдущих.
Таким образом мы вернулись к предыдущей версии файла main.c и при этом сохранили всю историю изменений.
Использование git revert для быстрой отмены изменений
Рассмотрим ещё одни способ отмены коммитов, на этот раз воспользуемся командой git revert.
В нашем примере, отменим коммит с id=cffc5ad. После того как вы введете команду git revert (см. ниже), система git выдаст сообщение в текстовом редакторе, если вы согласны с тем, что будет написано в открытом файле, то просто сохраните его и закройте. В результате изменения будут применены, и автоматически сформируется и отправится в репозиторий коммит.
Если вы хотите поменять редактор, то воспользуйтесь командой.
Обратите внимание, что в этом случае будут изменены настройки для текущего репозитория. Более подробно об изменении настроек смотрите в “Git для начинающих. Часть 3. Настройка Git”
Проверим, применялась ли настройка.
Посмотрим на список коммитов в репозитории.
Содержимое файла вернулось к тому, что было сделано в рамках коммита с >
Отмена группы коммитов
ВНИМАНИЕ! Используйте эту команду очень аккуратно!
Если вы не знакомы с концепцией указателя HEAD, то обязательно прочитайте статью “ Git для начинающих. Часть 7. Поговорим о HEAD и tree-ish“. HEAD указывает на коммит в репозитории, с которого будет вестись дальнейшая запись, т.е. на родителя следующего коммита. Существует три опции, которые можно использовать с командой git reset для изменения положения HEAD и управления состоянием stage и рабочей директории, сейчас мы все это подробно разберем.
Удаление коммитов из репозитория (без изменения рабочей директории) (ключ –soft)
Для изменения положения указателя HEAD в репозитории, без оказания влияния рабочую директорию (в stage, при этом, будет зафиксированно отличие рабочей директории от репозитория), используйте ключ –soft. Посмотрим ещё раз на наш репозиторий.
Содержимое файла main.с в рабочей директории.
Содержимое файла main.с в репозитории.
Теперь переместим HEAD в репозитории на коммит с id=dcf7253.
Получим следующий список коммитов.
Содержимое файла main.c в репозитории выглядит так.
В рабочей директории файл main.c остался прежним (эти изменения отправлены в stage).
Для того, чтобы зафиксировать в репозитории последнее состояние файла main.c сделаем коммит.
Посмотрим на список коммитов.
Как видите из репозитория пропали следующие коммиты:
Удаление коммитов из репозитория и очистка stage (без изменения рабочей директории) (ключ –mixed)
Если использовать команду git reset с аргументом –mixed, то в репозитории указатель HEAD переместится на нужный коммит, а также будет сброшено содержимое stage. Отменим последний коммит.
В результате изменилось содержимое репозитория.
Содержимое файла main.c в последнем коммите выглядит так.
Файл main.c в рабочей директории не изменился.
Отправим изменения вначале в stage, а потом в репозиторий.
Удаление коммитов из репозитория, очистка stage и внесение изменений в рабочую директорию (ключ –hard)
Если вы воспользуетесь ключем –hard, то обратного пути уже не будет. Вы не сможете восстановить данные из рабочей директории. Все компоненты git (репозиторий, stage и рабочая директория) будут приведены к одному виду в соответствии с коммитом, на который будет перенесен указатель HEAD.
Текущее содержимое репозитория выглядит так.
Посмотрим на содержимое файла main.c в каталоге и репозитории.
Содержимое файлов идентично.
Удалим все коммиты до самого первого с id=86f1495.
Состояние рабочей директории и stage.
Содержимое файла main.c в репозитории и в рабочей директории.
Т.к. мы воспользовались командой git reset с ключем –hard, то восстановить прежнее состояние нам не получится.
БУДЬТЕ ОЧЕНЬ АККУРАТНЫ С ЭТОЙ КОМАНДОЙ!
Git для начинающих. Часть 9. Как удалить коммит в git? : 2 комментария
Это отменяет последний коммит, но не возвращает файл в исходное состояние.
А в какой задаче это может быть полезно?
Эта команда перезаписывает последний коммит (т.е. последний удаляется и на его место встает новый), файл в исходное состояние не возвращается.
А в какой задаче это может быть полезно?
хм… хороший вопрос! Даже затрудняюсь на него ответить. Ну например, вы закоммитили какой-то “ужас” и не хотите, чтобы он стал достоянием общественности))
Как отменить коммит в Git
Иногда случаются ситуации, что вы закомитили что-то не то, не туда или не так. Такой коммит надо удалить или отменить. В этой небольшой статье мы рассмотрим как отменить коммит Git. Обратите внимание, что если вам надо внести изменения, то коммит не обязательно отменять, можно его поправить. Но об этом в следующей статье.
Как отменить коммит в Git
Бывает, что вы что-то закомитили, а потом решили, что часть изменений вносить не надо было или в коммит попали лишние файлы. Тогда можно отменить коммит и сделать его уже заново, но без ненужных данных. Сначала желательно посмотреть историю коммитов и текущий коммит, для того чтобы не откатить ничего лишнего. Для этого выполните:
Команда вернет список коммитов с их описанием и идентификаторами (хешами), которые можно использовать для того чтобы посмотреть подробную информацию о коммите с помощью команды show. По умолчанию команда показывает изменения в последнем коммите:
Теперь можно использовать идентификатор коммита для того чтобы его отменить.
1. Отменить коммит, но оставить изменения
. Таким образом ссылка на предыдущий коммит будет выглядеть как HEAD
2 и так далее. Для отмены последнего коммита достаточно выполнить команду:
Как видите, все файлы сохранились, а если посмотреть отличия HEAD и текущего состояния проекта, то будет видно, добавление файла file3:
Аналогичного результата можно добиться, передав идентификатор коммита, например, давайте отменим коммит, добавляющий file2. Для этого посмотрите идентификатор коммита перед ним, в данном случае, это «Inital Commit» с помощью следующей команды:
А затем передайте его в команду git reset. Например:
И снова все файлы на месте, а в HEAD теперь будет добавлено два файла: file2 и file3:
Таким образом вы можете отменить несколько коммитов за раз, надо только указать идентификатор самого раннего коммита.
Обратите внимание, что файлы, которые ранее были в коммите, сейчас всё ещё добавлены в индекс, поэтому вам не надо вызывать git add, можно сразу создавать новый коммит. Но у команды reset есть ещё одна опция: —mixed. Она используется по умолчанию. При использовании этой опции ваши изменения тоже сохраняются, но перед следующим коммитом их снова надо будет добавить в индекс с помощью git add. При выполнении команды git status эти файлы будут отображаться как не отслеживаемые:
2. Отменить коммит и удалить изменения
Отмена коммита git с удалением изменений работает аналогично. Только здесь необходимо вместо опции —soft указывать опцию —hard. Например, при той же структуре коммитов, можно удалить последний коммит с добавлением файла file3 вместе с этим файлом:
Теперь файла нет. Аналогично, вы можете указать идентификатор коммита, до которого надо отменить коммиты. Обратите внимание, что указывается не тот коммит, который надо отменить, а коммит перед ним. Ещё важно отметить, что это всё работает пока вы не отправили свои коммиты в удалённый репозиторий. Если коммиты уже отправлены, их идентификаторы сохранены там, а поэтому менять их нельзя, иначе могут возникнуть конфликты слияния, которые будет сложно решить. Теперь вы знаете отменить последний локальный коммит git.
3. Как вернуть отмененный коммит
Аналогично можно использовать адрес:
Срок хранения удалённых коммитов ограничен. Время от времени git удаляет мусор, так что если ждать слишком долго, то нужных данных уже может и не быть. Но найти удалённые коммиты, если git их ещё не удалил можно с помощью такой команды:
Затем просто используйте идентификатор коммита для того чтобы посмотреть какие в нём были изменения:
git show 8a996dd76fbacb05a2df91c0f2d19b1a3afd8451
Затем можно переключиться на этот коммит с помощью команды:
git rebase 8a996dd76fbacb05a2df91c0f2d19b1a3afd8451
Это всё тоже безопасно делать только с коммитами, ещё не отправленными в удалённый репозиторий.
4. Отменить изменения но не отменять коммит
Если вы уже отправили коммит в удалённый репозиторий, удалять его не желательно, потому что если кто-то успеет скачать репозиторий до отмены коммита, то потом у него возникнут проблемы. Однако изменения, сделанные в коммите можно отменить новым коммитом. Для того чтобы не делать это вручную существует специальная команда revert. Её уже нужно передать идентификатор именно того коммита, изменения из которого надо отменить. Для этого сначала найдите хэш коммита:
Затем выполните команду revert, например:
git revert 8a996dd76fbacb05a2df91c0f2d19b1a3afd8451
Команда предложит вам написать сообщение для отменяющего коммита, можно просто закрыть этот файл:
Затем изменения, которые были в коммите исчезнут и уже это можно будет снова пушить в удалённые репозиторий.
Выводы
В этой небольшой статье мы рассмотрели как отменить коммит git с сохранением изменений или без них. Как видите всё довольно просто. Будьте осторожны, и не сотрите ничего лишнего, чтобы не создать проблем коллегам и себе.
How can I remove a commit on GitHub? [duplicate]
The community reviewed whether to reopen this question last month and left it closed:
Original close reason(s) were not resolved
I «accidentally» pushed a commit to GitHub.
Is it possible to remove this commit?
I want to revert my GitHub repository as it was before this commit.
21 Answers 21
2 and delete the second line within the editor window that pops up.
Oh, and if your working tree is dirty, you have to do a git stash first, and then a git stash apply after.
That should «undo» the push.
For an easy revert if it’s just a mistake (perhaps you forked a repo, then ended up pushing to the original instead of to a new one) here’s another possibility:
Obviously swap in that number for the number of the commit you want to return to.
Everything since then will be deleted once you push again. To do that, the next step would be:
git log to find out the commit you want to revert
git push origin +7f6d03:master while 7f6d03 is the commit before the wrongly pushed commit. + was for force push
Here is a very good guide that solves your problem, easy and simple!
In case you like to keep the commit changes after deletion:
Note that this solution works if the commit to be removed is the last committed one.
You’ll need to clear out your cache to have it completely wiped. this help page from git will help you out. (it helped me) http://help.github.com/remove-sensitive-data/
Delete the most recent commit, keeping the work you’ve done:
Delete the most recent commit, destroying the work you’ve done:
Use git revert for reverting your push.
Revert the changes that the related patches introduce, and record some new commits that record them. This requires your working tree to be clean (no modifications from the HEAD commit).
Note: git revert is used to record some new commits to reverse the effect of some earlier commits (often only a faulty one). If you want to throw away all uncommitted changes in your working directory, you should see git-reset, particularly the —hard option.
To delete the commit from the remote repository:
In order delete the commit from your local repository:
You need to know your commit hash from the commit you want to revert to. You can get it from a GitHub URL like: https://github.com/your-organization/your-project/commits/master
Let’s say the hash from the commit (where you want to go back to) is «99fb454» (long version «99fb45413eb9ca4b3063e07b40402b136a8cf264»), then all you have to do is:
Find the ref spec of the commit you want to be the head of your branch on Github and use the following command:
git push origin +[ref]:[branchName]
In your case, if you just want to go back one commit, find the beginning of the ref for that commit, say for example it is 7f6d03, and the name of the branch you want to change, say for example it is master, and do the following:
git push origin +7f6d03:master
Как удалить коммиты в github?
Как удалить коммиты (commits) в github?
чтобы удалился коммит — нужно git gc.
Делает ли Github удаление мусора время от времени?
вроде да, но не помню, включено ли это по дефолту, и какой там интервал
У меня есть репозитарий в который код писал только я, ну может ещё один человек написал несколько строчек.
Коммиты у меня в основном вида «поставил запятую», в общем их много и содержания у отдельного коммита нет.
Можно схлопнуть историю изменений коммитов в один большой коммит?
Можно схлопнуть историю изменений коммитов в один большой коммит?
можно. даже без остальных двух условий.
Можно схлопнуть историю изменений коммитов в один большой коммит?
—force как раз удалит/затрёт коммиты. Если именно это нужно ТС.
Они не удалятся, но пропадут из истории указанной ветки. Их можно переиспользовать.
Никак. Что отправлено в интернет на сервер к дяде уже никак гарантированно не удалить.
Но гитхаб их радостно потрет
—force как раз удалит/затрёт коммиты. Если именно это нужно ТС.
Нда. Настолько не углублялся.
Я лично сталкивался с протухшими урлами на гитхабовые коммиты
GitHub периодически чистит висячие коммиты, но почему-то делает это не всегда. У меня есть которые уже 3 месяца висят, а некоторые удалились через неделю. Если надо гарантированно удалить (например, пароли засветились), придется удалить репозиторий и создать заново.
Главное — не делать так с публичными ветками, которые сдались кому-то кроме тебя, а то бывает крайне неприятно, когда локальная копия неконсистентна с тем, что лежит на сервере.
Не думаю что моим репозитарием кто либо кроме меня пользуется.
Но всё равно спасибо.
Я лично сталкивался с протухшими урлами на гитхабовые коммиты
а я лично сталкивался с непротухшими, поэтому и не факт.
Удалить коммит можно любой операцией перезаписи истории: reset,rebase. После того, как коммит «удалилися», он еще существует и к нему можно иметь доступ, к примеру, через хэш. И этот коммит будет существовать до тех пор, пока гит не сделает gc (garbage collection)





























