2

Вчера в истории появились коммиты которые не должны были попасть в git

Выглядит это так

введите сюда описание изображения

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

Чтоб это сделать выбрали этот метод

https://stackoverflow.com/a/23839198/5709159

и действительно все получилось. Но в итоге оказалось, что не все файлы которые были в .gitignore на самом деле должны были быть удалены.

Проблема в том, что теперь эти комиты запушены и их нужно удалить.

У кого какие идеи как это можно сделать?

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

P.S. Файлы были в истории, потом их удалили (хотя не нужно было) и запушили в гит. Теперь нужно эти файлы вернуть обратно.

Изменения нужно не просто откатить. А скажем были комиты A - B - C - D коммит A содержит нужные файлы, далее в коммите B эти файлы удаляют далее продолжают работать и делают уже нормальные комиты с нужными имплементациями C и D . Что получается. Нам нужно исключить коммит B тоесть нам нужно вернуть все файлы которые в нем были удалены из коммита A, но так же нам нужно оставить изменения C и D. В итоге должно выйти так A - C - D. Или можно сделать, что то вроде такого A - B - C - D - B

Sirop4ik
  • 10,954
  • 1
    если это было запушено, то после правки истории Вам нужно будет сделать форсированный пуш. Если Вы работаете не один над репозиторием, то коллегам это может сильно не понравиться – KoVadim May 14 '20 at 07:50
  • @KoVadim согласен, но это было только вчера так, что мне кажется, что еще не все успели обновиться. Но в любом случае пока у меня нет идеи как это сделать. – Sirop4ik May 14 '20 at 07:52
  • Вам нужна эта страница документации https://git-scm.com/book/ru/v2/%D0%98%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B-Git-%D0%98%D1%81%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D0%B8 - и команда filter-branch. Потом, когда локальная история будет выглядеть красиво, нужно будет сделать форсированный пуш и надеятся, что другие не обидятся – KoVadim May 14 '20 at 07:58
  • @KoVadim эта команда похоже может помочь удалить файл(ы) из всех истории. Но мне получается нужно не удалить, а вернуть из обратно. Они были в истории, потом из удалили (хотя не нужно было) и запушили. Теперь их нужно вернуть. Или я не так понял, что делает эта команда? – Sirop4ik May 14 '20 at 08:05
  • она может все делать, то есть, можно каждый коммит модифицировать так как нужно. Но если нужно просто откатить изменения, то это совсем другая задача – KoVadim May 14 '20 at 08:08
  • @KoVadim Дополнил вопрос – Sirop4ik May 14 '20 at 08:13
  • я бы открыл git reflog и посмотрел, не осталось ли там ветки в правильном состоянии, перед началом этих всех изменений. А потом просто поменять ветку на правильную и все будет ок. Но это при условии, что никто не запускал git gc или GUI тулу, которая может его запустить (source tree)/ – KoVadim May 14 '20 at 08:25
  • @AlekseyTimoshchenko я не могу понять нужно ли вам именно переписать историю (т.е. из истории A - B - C - D сделать A - C - D) или вы хотите просто отменить изменение сделанное в комите B (чтоб получилось A - B - C - D - E, где E - изменения обратные B)? – Roman-Stop RU aggression in UA May 14 '20 at 08:37
  • @RomanKonoval в целом мне кажется, что для меня это не имеет значения. Мне нужны те файлы которые были удалены в коммите В. Я вижу два пути, либо отменить этот коммит, либо взять удаленные файлы (как то) и добавить их снова как новый коммит. Значения не имеет, но мне нужны файлы. Мне кажется, что проще (как то) взять все файлы удаленные и закомитить их как новый коммит – Sirop4ik May 14 '20 at 08:55
  • Можно убирать коммит по его ID. Такой вопрос уже есть на Stackoverflow. – FeironoX5 May 14 '20 at 09:19
  • @FeironoX5 есть сслыка? – Sirop4ik May 14 '20 at 09:21
  • https://ru.stackoverflow.com/questions/740179/Удалить-ненужные-коммиты - Попробуйте это. – FeironoX5 May 14 '20 at 09:23
  • https://gist.github.com/vorozhba/b458077f396191a6105cf91e1739a313 – FeironoX5 May 14 '20 at 09:23
  • Последний способ удалит все изменения до указанного комита - это совсем не то, что нужно, т.к. потеряются более поздние изменения. – Roman-Stop RU aggression in UA May 14 '20 at 09:27

1 Answers1

4

Самый простой способ отменить изменения сделанные в комите это воспользоваться командой git revert:

git revert <commit-id>

Т.е. если есть история комитов A - B - C - D, то после команды:

git revert B

Будем иметь историю A - B - C - D - E, где в комите E - изменения обратные изменениям внесенным комитом B.

Если нужно отменить только часть изменений сделанных в комите, то можно добавить параметр --no-commit:

git revert --no-commit <B-commit-id>

В этом случае изменения комит E не будет создан автоматически, будут сделаны изменения обратные B в рабочей директории, которые можно вручную подправить и дальше уже использовать git add и git commit.

  • Я не уверен, что я правильно понял, git revert удаляет только указанный коммит или всю цепочку коммитов до указонного коммита? – Sirop4ik May 14 '20 at 09:53
  • 1
    revert не удаляет коммит. Он делает следующее - он берет diff коммита, дальше меняет + на минусы и наоборот. И потом его применяет как коммит. Другими словами - он пытается сделать компенсационные изменения, что бы откатить изменнения, внесенные коммитом. – KoVadim May 14 '20 at 10:00
  • @KoVadim прав. Я добавил более подробное объяснение, как работает revert. – Roman-Stop RU aggression in UA May 14 '20 at 10:29