можно ли удалить коммит 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 с сохранением изменений или без них. Как видите всё довольно просто. Будьте осторожны, и не сотрите ничего лишнего, чтобы не создать проблем коллегам и себе.

Источник

Как отменить 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, старайтесь декомпозировать задачи заранее, а то можете словить сюрприз. Сталкивались ли вы с такими ситуациям, и если да, то как выходили из них?

Источник

igorsmolin

Базовая работа с коммитами в Git.

Коллеги, приветствую. Сегодня мы немного поговорим о работе с коммитами в системе контроля версиями — Git.

Целью этой статьи является обзор популярных сценариев проблем и методов их решения. Мы узнаем о том, как можно решить проблемы связанные с человеческими ошибками при создании коммитов в Git, какой способ устранения ошибок лучше применять в конкретных ситуациях.

Возникающие проблемы

В ходе разработки каких-либо проектов в Git, мы можем столкнуться с различными ситуациями, такими как:

Безопасные изменения для локального репозитория

Изменить последний коммит

Давайте предположим, что мы работаем над каким-либо проектом локально.

Вдруг мы понимаем, что в момент создания сообщения для последнего коммита мы допустили ошибку, либо сообщение вовсе не подходит. В таком случае выполним команду:

Перед нами откроется текстовый редактор с предложением изменить сообщение. Также мы можем увидеть список файлов которые будут зафиксированы.

Изменим сообщение коммита, выйдем из текстового редактора и проверим историю. Для этого введем команду:

Но что делать, если мы забыли добавить или изменить какие-то файлы в наш последний коммит?

Для этого импортируем нужные файлы в наш проект или изменяем уже существующие и добавляем их в индекс.

Для теста я добавлю файл forgotten file.txt в проект. После этого еще раз выполним команду:

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

В случае необходимости удаления ненужного файла из последнего коммита, мы можем удалить его из проекта, добавить изменения в индекс и воспользоваться все той же командой:

Удалить коммит

Для того, чтобы удалить один или несколько коммитов, мы можем воспользоваться командой git reset. Существует два типа выполнения reset:

Сначала разберем soft reset. Возвращаемся к нашему проекту.

В один момент мы осознали, что допустили ошибку и хотели бы переделать последний коммит.

Для этого выполним команду:

Проверим историю коммитов. Мы можем убедится, что последний коммит был удален.

Файлы, которые были созданы или изменены в удаленном коммите, перешли в состояние рабочего каталога. Мы можем продолжить работу и, например, создать новый коммит на основе этих файлов.

Подобные действия мы можем выполнять для нескольких коммитов сразу. Для примера введем команду:

3 последних коммита пропали из истории.

Проверим состояние файлов, которых коснулась процедура удаления коммитов.

Мы можем полностью удалить коммиты без сохранения связанных с ними файлов. Для этого выполним процедуру hard reset:

И проверим состояние.

Массовое изменение коммитов

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

Для этой задачи хорошо подходит выполнение команды git rebase. Ее запуск в интерактивном режиме позволит нам последовательно сообщить Git’у как бы мы хотели выполнить оптимизацию.

Мы считаем, что 4 последних коммита можно смело объединить в один.

Для этого выполним команду:

Перед нами откроется текстовый редактор по умолчанию в котором мы будем выполнять изменения. Используем коммит с хэшем aab958a как начальный, путем указания команды pick напротив него и укажем напротив трех остальных команду squash. Как мы можем видеть ниже в описании, команда suqash объединит коммит с предыдущим в списке.

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

Теперь Git попросит от нас ввести сообщения коммитов. Просто для наглядности мы немного переименуем наш объединенный коммит. Также Git сообщит о том, какие файлы подвергнуться изменениям.

Снова выходим из текстового редактора.

Похоже, что наше объединение нескольких коммитов прошло успешно. Давайте проверим это командой:

Мы уже были готовы к публикации наших изменений, однако, посчитали, что необходимо объединить другие 3 коммита в 1 и изменить его сообщение. При этом, мы бы не хотели затрагивать уже объединенный.

Снова вводим команду:

В этот раз в качестве начального коммита будет использоваться с коммит хэшем 4c17043. Для его переименования укажем напротив команду reword. Затем объединяем с ним два последующих коммита командой squash. Последний коммит мы никак не изменяем.

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

Похоже, что нам удалось провести историю коммитов в порядок и теперь нет причин откладывать загрузку нашего проекта на удаленный репозиторий. 🙂

Безопасные изменения для удаленных репозиториев

До этого мы рассматривали случаи локальной разработки. По большому счету, пока мы не публикуем изменения, наши действия — не могут повлиять на деятельность наших коллег по проекту. Применение вышеописанных способов до публикации изменений на удаленном репозитории — вполне оправдано.

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

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

Снова вовзращаемся к исходному состоянию проекта.

Предположим, что изменения в коммите с хэшем и 5140d80 — лишние. Выполним команду:

Git сообщит нам об изменениях, после отката.

Проверим историю. Как мы можем убедиться, был создан новый коммит, «отменяющий» изменения ненужного.

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

Итоги

В этой статье мы узнали о четырех способах изменять коммиты:

Первые три команды — подойдут для использования в условиях локальной разработки.

Последняя команда — лучший способ, не создавать лишних проблем коллегам при совместной разработке.

Источник

Читайте также:  левофлоксацин при простуде можно пить
Строительный портал