Одно из основных правил Git заключается в том, что, так как большую часть работы вы делаете в своем локальном репозитории, вы можете переписывать свою историю локально так, как вам хочется.
Однако, как только вы отправите свои наработки на удаленный сервер, то с этого момента их нужно рассматривать как финальные до тех пор, пока у вас не появится весомая причина что-то изменить.
Если коротко, то вы должны воздержаться от отправки своих изменений до тех пор, пока не будете полностью довольны и готовы поделиться ими со всем миром.
Изменение вашего последнего коммита, наверное, наиболее частое исправление истории, которое вы будете выполнять. С последним коммитом можно сделать две основные операции: изменить сообщение коммита или изменить только что сделанный снимок, добавив, изменив или удалив файлы. Это очень просто:
Вместо последнего коммита будет создан новый коммит (с новым Id), который содержит прежние и новые изменения и новое сообщение коммита.
Пример: Дополнить последний коммит.
Для изменения коммита, не являющегося последним, а расположенного где-то раньше в истории, нужно обратиться к более сложным инструментам. В Git отсутствуют инструменты для переписывания истории, но вы можете использовать перебазирование, чтобы перебазировать группу коммитов туда же на HEAD, где они были изначально, вместо перемещения их в другое место.
С помощью интерактивного перебазирования можно останавливаться после каждого нужного вам коммита и изменять сообщения, добавлять файлы или делать что-то другое, что вам нужно. Для этого нужно всего лишь выбрать в панели История тот самый коммит, который вы хотите изменить, и нажать в контекстном меню.
Например, у вас есть история коммитов.
В некоторый момент вы понимаете, что коммит «Добавил Сотрудники, изменил ПриходТовара» оказался «недоделан». То ли вы забыли дописать номер задачи в сообщение коммита, то ли забыли сделать изменения, а может быть и то и другое вместе. Чтобы исправить этот коммит, вы выделяете его в панели История и нажимаете в контекстном меню.
1C:EDT создает операцию интерактивного перебазирования, в которой для вашего коммита выбрано действие Редактировать, а остальные коммиты, следующие за ним, переносятся без изменений и изменить действие для остальных коммитов вы не можете.
При этом в панели Индексирование Git находится сообщение вашего коммита, вы можете его изменить. А кроме этого вы можете выполнить забытые изменения и добавить их к этому коммиту.
Допустим, вы добавили забытый реквизит к документу ПриходТовара, дописали к сообщению коммита номер задачи. Теперь вы можете нажать Фиксировать, чтобы изменить коммит, а затем Продолжить, чтобы закончить операцию интерактивного перебазирования.
В результате панель Interactive Rebase очистится, а в панели История вы увидите три новых коммита: один, который вы изменили, и два, следующих за ним, которые были перенесены без изменений.
О том, что это новые коммиты, вы можете судить по тому, что они имеют другие идентификаторы.
Допустим, вы имеете следующую историю коммитов.
В какой-то момент вы поняли, что сообщения коммитов недостаточно информативны. К ним нужно добавить номер задачи, в рамках которой были выполнены изменения. Для этого вы можете воспользоваться операцией интерактивного перебазирования.
В панели История выделите их родительский коммит («первый коммит») и в контекстном меню нажмите Interactive Rebase.
1C:EDT откроет панель Interactive Rebase, в которой будут содержаться все перебазируемые коммиты. Для каждого из них вы можете выбрать одно из действий, которые хотите с ними выполнить. В данном случае это будет действие Редактировать сообщение.
После того, как для каждого коммита выбрано нужное действие, можно нажать Старт.
1C:EDT начнет интерактивное перебазирование, остановится на первом коммите, который нужно изменить, и откроет диалог для изменения сообщения коммита. Допишите к сообщению номер задачи и нажмите Редактировать сообщение.
1C:EDT изменит этот коммит и остановится на следующем. Вы можете наблюдать процесс интерактивного перебазирования «в реальном времени». Для новых коммитов 1C:EDT создала новую ветку, добавила в нее первый измененный вами коммит и готова к изменению второго.
Когда интерактивное перебазирование завершится, панель Interactive Rebase очистится, а в панели История вы увидите новые коммиты с новыми сообщениями.
Вы также можете использовать интерактивное перебазирование для изменения порядка коммитов. Для этого используйте действия Выше и Ниже.
С помощью интерактивного перебазирования можно объединить несколько коммитов в один. При этом вы можете не вызывать собственно операцию интерактивного перебазирования, а воспользоваться более простым способом.
В панели История выделите коммиты, которые вы хотите объединить, а затем нажмите .
1C:EDT предложит вам написать новое сообщение для этого объединенного коммита. Стандартно она собирает в него все сообщения объединяемых коммитов.
Вместо такого «сборного» сообщения вы можете написать, например, что все эти изменения были выполнены в рамках одного эпика: Epic-27.
Если вы хотите избавиться от какого-либо коммита, то удалить его можно во время интерактивного перебазирования. Выберите для него действие Пропустить.
В результате выбранный вами коммит будет удален из истории, а вместо следующих за ним будут созданы новые коммиты.
Из-за того, как Git создает объекты коммитов, удаление или изменение коммита влечет за собой перезапись всех последующих коммитов. Чем дальше вы вернетесь в историю ваших коммитов, тем больше коммитов потребуется переделать. Это может вызвать множество конфликтов слияния, особенно если у вас много последующих коммитов, которые зависят от удаленного.
Если во время интерактивного перебазирования вы поняли, что это была не очень хорошая идея, то всегда можно остановиться. Просто нажмите Прервать в панели Interactive Rebase и ваш репозиторий вернется в то состояние, в котором он был до начала перебазирования.
Вы можете полностью отменить операцию перебазирования и вернуть все в то состояние, которое было «до этого».
Например, у вас была такая история.
Вы объединили три коммита в один и история приняла другой вид.
После раздумий вы решили, что объединить все в один коммит — это была не очень хорошая идея и хотите вернуть все обратно.
Это можно сделать, так как старые коммиты ветки все еще находятся в базе данных объектов, но больше не видны, поскольку они больше не доступны ни из одной ветки. Вы можете увидеть эти коммиты и использовать их для отмены перебазирования.
По материалам книги Pro Git (авторы Scott Chacon и Ben Straub, издательство Apress). Книга распространяется по лицензии Creative Commons Attribution Non Commercial Share Alike 3.0 license.