> *Полетные правила* - это с большим трудом полученный запас знаний, записанный в форме инструкций, в которых указан последовательный порядок действий в разных ситуациях и сказано, почему нужно делать именно так. По сути это крайне подробный, стандартный план действий в ситуациях, развивающихся по прописанным сценариям. [...]
> ВНАСА фиксируют все наши промахи, аварии и методы решения проблем с начала 1960 хгг., когда наземные группы проекта Mercury начали составлять сборник "выученных уроков". Теперь в этом сборнике перечислены тысячи сложных ситуаций и их решения – от отказа двигателей, поломки ручек люка до проблем с компьютером.
Для наглядности во всех примерах в этом документе используется измененное приглашение командной строки, чтобы показать текущую ветку и есть ли подготовленные изменения. Ветка заключена в кавычки, а символ `*` после ветки означает подготовленные изменения.
[](https://gitter.im/k88hudson/git-flight-rules?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
- [Что я только что сохранил?](#%D0%A7%D1%82%D0%BE-%D1%8F-%D1%82%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE-%D1%87%D1%82%D0%BE-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D0%BB)
- [Я неправильно написал сообщение коммита](#%D0%AF-%D0%BD%D0%B5%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE-%D0%BD%D0%B0%D0%BF%D0%B8%D1%81%D0%B0%D0%BB-%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%B0)
- [Я сделал коммит с неправильным именем автора и адресом электронной почты](#%D0%AF-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BB-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82-%D1%81-%D0%BD%D0%B5%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D1%8B%D0%BC-%D0%B8%D0%BC%D0%B5%D0%BD%D0%B5%D0%BC-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B0-%D0%B8-%D0%B0%D0%B4%D1%80%D0%B5%D1%81%D0%BE%D0%BC-%D1%8D%D0%BB%D0%B5%D0%BA%D1%82%D1%80%D0%BE%D0%BD%D0%BD%D0%BE%D0%B9-%D0%BF%D0%BE%D1%87%D1%82%D1%8B)
- [Я пытаюсь опубликовать исправленный коммит, но получаю сообщение об ошибке](#%D0%AF-%D0%BF%D1%8B%D1%82%D0%B0%D1%8E%D1%81%D1%8C-%D0%BE%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-%D0%B8%D1%81%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82-%D0%BD%D0%BE-%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B0%D1%8E-%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BE%D0%B1-%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B5)
- [Я случайно сделал жесткий сброс (--hard) и теперь хочу вернуть свои изменения](#%D0%AF-%D1%81%D0%BB%D1%83%D1%87%D0%B0%D0%B9%D0%BD%D0%BE-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BB-%D0%B6%D0%B5%D1%81%D1%82%D0%BA%D0%B8%D0%B9-%D1%81%D0%B1%D1%80%D0%BE%D1%81---hard-%D0%B8-%D1%82%D0%B5%D0%BF%D0%B5%D1%80%D1%8C-%D1%85%D0%BE%D1%87%D1%83-%D0%B2%D0%B5%D1%80%D0%BD%D1%83%D1%82%D1%8C-%D1%81%D0%B2%D0%BE%D0%B8-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F)
- [Я случайно опубликовал ненужное слияние](#%D0%AF-%D1%81%D0%BB%D1%83%D1%87%D0%B0%D0%B9%D0%BD%D0%BE-%D0%BE%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%BE%D0%B2%D0%B0%D0%BB-%D0%BD%D0%B5%D0%BD%D1%83%D0%B6%D0%BD%D0%BE%D0%B5-%D1%81%D0%BB%D0%B8%D1%8F%D0%BD%D0%B8%D0%B5)
- [Я случайно закоммитил и опубликовал файлы с конфиденциальными данными](#%D0%AF-%D1%81%D0%BB%D1%83%D1%87%D0%B0%D0%B9%D0%BD%D0%BE-%D0%B7%D0%B0%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%B8%D0%BB-%D0%B8-%D0%BE%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%BE%D0%B2%D0%B0%D0%BB-%D1%84%D0%B0%D0%B9%D0%BB%D1%8B-%D1%81-%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B4%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%BC%D0%B8-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%BC%D0%B8)
- [Мне нужно изменить содержимое коммита, который не является последним](#%D0%9C%D0%BD%D0%B5-%D0%BD%D1%83%D0%B6%D0%BD%D0%BE-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B8%D1%82%D1%8C-%D1%81%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B8%D0%BC%D0%BE%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%B0-%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D0%B9-%D0%BD%D0%B5-%D1%8F%D0%B2%D0%BB%D1%8F%D0%B5%D1%82%D1%81%D1%8F-%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BD%D0%B8%D0%BC)
- [Подготовка изменений (staging)](#%D0%9F%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BA%D0%B0-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9-staging)
- [Мне нужно добавить подготовленные изменения в предыдущий коммит](#%D0%9C%D0%BD%D0%B5-%D0%BD%D1%83%D0%B6%D0%BD%D0%BE-%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B2-%D0%BF%D1%80%D0%B5%D0%B4%D1%8B%D0%B4%D1%83%D1%89%D0%B8%D0%B9-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82)
- [Я хочу подготовить только часть файла, а не весь файл целиком](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%B8%D1%82%D1%8C-%D1%82%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE-%D1%87%D0%B0%D1%81%D1%82%D1%8C-%D1%84%D0%B0%D0%B9%D0%BB%D0%B0-%D0%B0-%D0%BD%D0%B5-%D0%B2%D0%B5%D1%81%D1%8C-%D1%84%D0%B0%D0%B9%D0%BB-%D1%86%D0%B5%D0%BB%D0%B8%D0%BA%D0%BE%D0%BC)
- [Я хочу добавить изменения одного файла в два разных коммита](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BE%D0%B4%D0%BD%D0%BE%D0%B3%D0%BE-%D1%84%D0%B0%D0%B9%D0%BB%D0%B0-%D0%B2-%D0%B4%D0%B2%D0%B0-%D1%80%D0%B0%D0%B7%D0%BD%D1%8B%D1%85-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%B0)
- [Я подготовил слишком много правок и теперь хочу разделить их на несколько отдельных коммитов](#%D0%AF-%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%B8%D0%BB-%D1%81%D0%BB%D0%B8%D1%88%D0%BA%D0%BE%D0%BC-%D0%BC%D0%BD%D0%BE%D0%B3%D0%BE-%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D0%BA-%D0%B8-%D1%82%D0%B5%D0%BF%D0%B5%D1%80%D1%8C-%D1%85%D0%BE%D1%87%D1%83-%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D0%B8%D1%82%D1%8C-%D0%B8%D1%85-%D0%BD%D0%B0-%D0%BD%D0%B5%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE-%D0%BE%D1%82%D0%B4%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D1%85-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%BE%D0%B2)
- [Я хочу подготовить свои неподготовленные правки и убрать из подготовки то, что уже подготовлено](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%B8%D1%82%D1%8C-%D1%81%D0%B2%D0%BE%D0%B8-%D0%BD%D0%B5%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B8-%D0%B8-%D1%83%D0%B1%D1%80%D0%B0%D1%82%D1%8C-%D0%B8%D0%B7-%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BA%D0%B8-%D1%82%D0%BE-%D1%87%D1%82%D0%BE-%D1%83%D0%B6%D0%B5-%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%BE)
- [Я хочу переместить мои неподготовленные правки в новую ветку](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D0%B8%D1%82%D1%8C-%D0%BC%D0%BE%D0%B8-%D0%BD%D0%B5%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B8-%D0%B2-%D0%BD%D0%BE%D0%B2%D1%83%D1%8E-%D0%B2%D0%B5%D1%82%D0%BA%D1%83)
- [Я хочу переместить неподготовленные правки в другую существующую ветку](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D0%B8%D1%82%D1%8C-%D0%BD%D0%B5%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B8-%D0%B2-%D0%B4%D1%80%D1%83%D0%B3%D1%83%D1%8E-%D1%81%D1%83%D1%89%D0%B5%D1%81%D1%82%D0%B2%D1%83%D1%8E%D1%89%D1%83%D1%8E-%D0%B2%D0%B5%D1%82%D0%BA%D1%83)
- [Я хочу отменить некоторые неподготовленные изменения](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BE%D1%82%D0%BC%D0%B5%D0%BD%D0%B8%D1%82%D1%8C-%D0%BD%D0%B5%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D0%B5-%D0%BD%D0%B5%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F)
- [Я хочу отбросить неподготовленные изменения в некоторых файлах](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BE%D1%82%D0%B1%D1%80%D0%BE%D1%81%D0%B8%D1%82%D1%8C-%D0%BD%D0%B5%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B2-%D0%BD%D0%B5%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D1%85-%D1%84%D0%B0%D0%B9%D0%BB%D0%B0%D1%85)
- [Я хочу получить список всех веток](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA-%D0%B2%D1%81%D0%B5%D1%85-%D0%B2%D0%B5%D1%82%D0%BE%D0%BA)
- [Создать ветку на определенном коммите](#%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D1%82%D1%8C-%D0%B2%D0%B5%D1%82%D0%BA%D1%83-%D0%BD%D0%B0-%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%BC-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%B5)
- [Я стянул изменения (pull) из неправильной ветки или в неправильную ветку](#%D0%AF-%D1%81%D1%82%D1%8F%D0%BD%D1%83%D0%BB-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-pull-%D0%B8%D0%B7-%D0%BD%D0%B5%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9-%D0%B2%D0%B5%D1%82%D0%BA%D0%B8-%D0%B8%D0%BB%D0%B8-%D0%B2-%D0%BD%D0%B5%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D1%83%D1%8E-%D0%B2%D0%B5%D1%82%D0%BA%D1%83)
- [Я хочу отменить локальные коммиты, чтобы моя ветка стала такой же как на сервере](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BE%D1%82%D0%BC%D0%B5%D0%BD%D0%B8%D1%82%D1%8C-%D0%BB%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D1%8B-%D1%87%D1%82%D0%BE%D0%B1%D1%8B-%D0%BC%D0%BE%D1%8F-%D0%B2%D0%B5%D1%82%D0%BA%D0%B0-%D1%81%D1%82%D0%B0%D0%BB%D0%B0-%D1%82%D0%B0%D0%BA%D0%BE%D0%B9-%D0%B6%D0%B5-%D0%BA%D0%B0%D0%BA-%D0%BD%D0%B0-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B5)
- [Я сохранил коммит в ветку master вместо новой ветки](#%D0%AF-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D0%BB-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82-%D0%B2-%D0%B2%D0%B5%D1%82%D0%BA%D1%83-master-%D0%B2%D0%BC%D0%B5%D1%81%D1%82%D0%BE-%D0%BD%D0%BE%D0%B2%D0%BE%D0%B9-%D0%B2%D0%B5%D1%82%D0%BA%D0%B8)
- [Я хочу сохранить файл целиком из другого ref-ish](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D1%82%D1%8C-%D1%84%D0%B0%D0%B9%D0%BB-%D1%86%D0%B5%D0%BB%D0%B8%D0%BA%D0%BE%D0%BC-%D0%B8%D0%B7-%D0%B4%D1%80%D1%83%D0%B3%D0%BE%D0%B3%D0%BE-ref-ish)
- [Я сделал несколько коммитов в одной ветке, а нужно было сохранять их в разных ветках](#%D0%AF-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BB-%D0%BD%D0%B5%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%BE%D0%B2-%D0%B2-%D0%BE%D0%B4%D0%BD%D0%BE%D0%B9-%D0%B2%D0%B5%D1%82%D0%BA%D0%B5-%D0%B0-%D0%BD%D1%83%D0%B6%D0%BD%D0%BE-%D0%B1%D1%8B%D0%BB%D0%BE-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D1%8F%D1%82%D1%8C-%D0%B8%D1%85-%D0%B2-%D1%80%D0%B0%D0%B7%D0%BD%D1%8B%D1%85-%D0%B2%D0%B5%D1%82%D0%BA%D0%B0%D1%85)
- [Я хочу удалить локальные ветки, которые были удалены в upstream](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D1%83%D0%B4%D0%B0%D0%BB%D0%B8%D1%82%D1%8C-%D0%BB%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%B2%D0%B5%D1%82%D0%BA%D0%B8-%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D0%B5-%D0%B1%D1%8B%D0%BB%D0%B8-%D1%83%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D1%8B-%D0%B2-upstream)
- [Я хочу перейти на удаленную ветку, над которой работает кто-то еще](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BF%D0%B5%D1%80%D0%B5%D0%B9%D1%82%D0%B8-%D0%BD%D0%B0-%D1%83%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%BD%D1%83%D1%8E-%D0%B2%D0%B5%D1%82%D0%BA%D1%83-%D0%BD%D0%B0%D0%B4-%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D0%BE%D0%B9-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82-%D0%BA%D1%82%D0%BE-%D1%82%D0%BE-%D0%B5%D1%89%D0%B5)
- [Я хочу создать новую удаленную ветку из текущей локальной](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D1%82%D1%8C-%D0%BD%D0%BE%D0%B2%D1%83%D1%8E-%D1%83%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%BD%D1%83%D1%8E-%D0%B2%D0%B5%D1%82%D0%BA%D1%83-%D0%B8%D0%B7-%D1%82%D0%B5%D0%BA%D1%83%D1%89%D0%B5%D0%B9-%D0%BB%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9)
- [Я хочу настроить HEAD на отслеживание основной удаленной ветки](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B8%D1%82%D1%8C-head-%D0%BD%D0%B0-%D0%BE%D1%82%D1%81%D0%BB%D0%B5%D0%B6%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D0%BE%D0%B9-%D1%83%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9-%D0%B2%D0%B5%D1%82%D0%BA%D0%B8)
- [Я сделал изменения в неправильной ветке](#%D0%AF-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BB-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B2-%D0%BD%D0%B5%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9-%D0%B2%D0%B5%D1%82%D0%BA%D0%B5)
- [Я сделал перебазирование, но я не хочу делать принудительный push](#%D0%AF-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BB-%D0%BF%D0%B5%D1%80%D0%B5%D0%B1%D0%B0%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BD%D0%BE-%D1%8F-%D0%BD%D0%B5-%D1%85%D0%BE%D1%87%D1%83-%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C-%D0%BF%D1%80%D0%B8%D0%BD%D1%83%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9-push)
- [Мне нужно слить ветку в единственный коммит](#%D0%9C%D0%BD%D0%B5-%D0%BD%D1%83%D0%B6%D0%BD%D0%BE-%D1%81%D0%BB%D0%B8%D1%82%D1%8C-%D0%B2%D0%B5%D1%82%D0%BA%D1%83-%D0%B2-%D0%B5%D0%B4%D0%B8%D0%BD%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82)
- [Я хочу объединить только неопубликованные коммиты](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BE%D0%B1%D1%8A%D0%B5%D0%B4%D0%B8%D0%BD%D0%B8%D1%82%D1%8C-%D1%82%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE-%D0%BD%D0%B5%D0%BE%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D1%8B)
- [Мне нужно прервать слияние](#%D0%9C%D0%BD%D0%B5-%D0%BD%D1%83%D0%B6%D0%BD%D0%BE-%D0%BF%D1%80%D0%B5%D1%80%D0%B2%D0%B0%D1%82%D1%8C-%D1%81%D0%BB%D0%B8%D1%8F%D0%BD%D0%B8%D0%B5)
- [Проверить, что все коммиты ветви были слиты](#%D0%9F%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%B8%D1%82%D1%8C-%D1%87%D1%82%D0%BE-%D0%B2%D1%81%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D1%8B-%D0%B2%D0%B5%D1%82%D0%B2%D0%B8-%D0%B1%D1%8B%D0%BB%D0%B8-%D1%81%D0%BB%D0%B8%D1%82%D1%8B)
- [Возможные проблемы интерактивного перебазирования](#%D0%92%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D1%8B%D0%B5-%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D1%8B-%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B3%D0%BE-%D0%BF%D0%B5%D1%80%D0%B5%D0%B1%D0%B0%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)
- [Экран перебазирования говорит 'noop'](#%D0%AD%D0%BA%D1%80%D0%B0%D0%BD-%D0%BF%D0%B5%D1%80%D0%B5%D0%B1%D0%B0%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F-%D0%B3%D0%BE%D0%B2%D0%BE%D1%80%D0%B8%D1%82-noop)
- [Здесь были конфликты](#%D0%97%D0%B4%D0%B5%D1%81%D1%8C-%D0%B1%D1%8B%D0%BB%D0%B8-%D0%BA%D0%BE%D0%BD%D1%84%D0%BB%D0%B8%D0%BA%D1%82%D1%8B)
- [Отложенные изменения (stash)](#%D0%9E%D1%82%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-stash)
- [Отложить все правки](#%D0%9E%D1%82%D0%BB%D0%BE%D0%B6%D0%B8%D1%82%D1%8C-%D0%B2%D1%81%D0%B5-%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B8)
- [Я хочу найти строку в коммитах](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BD%D0%B0%D0%B9%D1%82%D0%B8-%D1%81%D1%82%D1%80%D0%BE%D0%BA%D1%83-%D0%B2-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%B0%D1%85)
- [Я хочу искать по автору или сохранившему изменения (committer)](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%B8%D1%81%D0%BA%D0%B0%D1%82%D1%8C-%D0%BF%D0%BE-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D1%83-%D0%B8%D0%BB%D0%B8-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D0%B2%D1%88%D0%B5%D0%BC%D1%83-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-committer)
- [Я хочу получить список коммитов, содержащих заданный файл](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%BE%D0%B2-%D1%81%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B0%D1%89%D0%B8%D1%85-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9-%D1%84%D0%B0%D0%B9%D0%BB)
- [Я хочу посмотреть историю коммитов для отдельной функции](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BF%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80%D0%B5%D1%82%D1%8C-%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D1%8E-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%BE%D0%B2-%D0%B4%D0%BB%D1%8F-%D0%BE%D1%82%D0%B4%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8)
- [Клонировать все субмодули](#%D0%9A%D0%BB%D0%BE%D0%BD%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-%D0%B2%D1%81%D0%B5-%D1%81%D1%83%D0%B1%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B8)
- [Экспорт репозитория в Zip-файл](#%D0%AD%D0%BA%D1%81%D0%BF%D0%BE%D1%80%D1%82-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D1%8F-%D0%B2-zip-%D1%84%D0%B0%D0%B9%D0%BB)
- [Как опубликовать ветку и метку, если они имеют одинаковые имена](#%D0%9A%D0%B0%D0%BA-%D0%BE%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-%D0%B2%D0%B5%D1%82%D0%BA%D1%83-%D0%B8-%D0%BC%D0%B5%D1%82%D0%BA%D1%83-%D0%B5%D1%81%D0%BB%D0%B8-%D0%BE%D0%BD%D0%B8-%D0%B8%D0%BC%D0%B5%D1%8E%D1%82-%D0%BE%D0%B4%D0%B8%D0%BD%D0%B0%D0%BA%D0%BE%D0%B2%D1%8B%D0%B5-%D0%B8%D0%BC%D0%B5%D0%BD%D0%B0)
- [Я хочу изменить регистр в имени файла, не меняя содержимое файла](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B8%D1%82%D1%8C-%D1%80%D0%B5%D0%B3%D0%B8%D1%81%D1%82%D1%80-%D0%B2-%D0%B8%D0%BC%D0%B5%D0%BD%D0%B8-%D1%84%D0%B0%D0%B9%D0%BB%D0%B0-%D0%BD%D0%B5-%D0%BC%D0%B5%D0%BD%D1%8F%D1%8F-%D1%81%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B8%D0%BC%D0%BE%D0%B5-%D1%84%D0%B0%D0%B9%D0%BB%D0%B0)
- [Я хочу переписать локальные файлы при выполнении git pull](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BF%D0%B5%D1%80%D0%B5%D0%BF%D0%B8%D1%81%D0%B0%D1%82%D1%8C-%D0%BB%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D1%84%D0%B0%D0%B9%D0%BB%D1%8B-%D0%BF%D1%80%D0%B8-%D0%B2%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D0%B8-git-pull)
- [Я хочу удалить файл из git, но оставить сам файл](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D1%83%D0%B4%D0%B0%D0%BB%D0%B8%D1%82%D1%8C-%D1%84%D0%B0%D0%B9%D0%BB-%D0%B8%D0%B7-git-%D0%BD%D0%BE-%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-%D1%81%D0%B0%D0%BC-%D1%84%D0%B0%D0%B9%D0%BB)
- [Я хочу откатить файл до заданной ревизии](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BE%D1%82%D0%BA%D0%B0%D1%82%D0%B8%D1%82%D1%8C-%D1%84%D0%B0%D0%B9%D0%BB-%D0%B4%D0%BE-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%BD%D0%BE%D0%B9-%D1%80%D0%B5%D0%B2%D0%B8%D0%B7%D0%B8%D0%B8)
- [Я хочу получить список изменений в заданном файле из разных коммитов или веток](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9-%D0%B2-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%BD%D0%BE%D0%BC-%D1%84%D0%B0%D0%B9%D0%BB%D0%B5-%D0%B8%D0%B7-%D1%80%D0%B0%D0%B7%D0%BD%D1%8B%D1%85-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%BE%D0%B2-%D0%B8%D0%BB%D0%B8-%D0%B2%D0%B5%D1%82%D0%BE%D0%BA)
- [Я хочу, чтобы Git игнорировал изменения в определенном файле](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D1%87%D1%82%D0%BE%D0%B1%D1%8B-git-%D0%B8%D0%B3%D0%BD%D0%BE%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B2-%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%BC-%D1%84%D0%B0%D0%B9%D0%BB%D0%B5)
- [Я хочу добавить псевдонимы для некоторых команд Git](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-%D0%BF%D1%81%D0%B5%D0%B2%D0%B4%D0%BE%D0%BD%D0%B8%D0%BC%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%BD%D0%B5%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D1%85-%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4-git)
- [Я хочу добавить в свой репозиторий пустую папку](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-%D0%B2-%D1%81%D0%B2%D0%BE%D0%B9-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D0%B9-%D0%BF%D1%83%D1%81%D1%82%D1%83%D1%8E-%D0%BF%D0%B0%D0%BF%D0%BA%D1%83)
- [Я хочу сохранить имя пользователя и пароль для репозитория](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D1%82%D1%8C-%D0%B8%D0%BC%D1%8F-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F-%D0%B8-%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8C-%D0%B4%D0%BB%D1%8F-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D1%8F)
- [Я хочу, чтобы Git игнорировал изменения разрешений и прав файлов](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D1%87%D1%82%D0%BE%D0%B1%D1%8B-git-%D0%B8%D0%B3%D0%BD%D0%BE%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BB-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D0%B9-%D0%B8-%D0%BF%D1%80%D0%B0%D0%B2-%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2)
- [Я хочу задать данные пользователя в глобальных настройках](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%B7%D0%B0%D0%B4%D0%B0%D1%82%D1%8C-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F-%D0%B2-%D0%B3%D0%BB%D0%BE%D0%B1%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0%D1%85)
- [Я хочу настроить цветовую схему для командной строки Git](#%D0%AF-%D1%85%D0%BE%D1%87%D1%83-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B8%D1%82%D1%8C-%D1%86%D0%B2%D0%B5%D1%82%D0%BE%D0%B2%D1%83%D1%8E-%D1%81%D1%85%D0%B5%D0%BC%D1%83-%D0%B4%D0%BB%D1%8F-%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%BD%D0%BE%D0%B9-%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8-git)
- [Я не представляю что я сделал неправильно](#%D0%AF-%D0%BD%D0%B5-%D0%BF%D1%80%D0%B5%D0%B4%D1%81%D1%82%D0%B0%D0%B2%D0%BB%D1%8F%D1%8E-%D1%87%D1%82%D0%BE-%D1%8F-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BB-%D0%BD%D0%B5%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D0%BE)
- [Сокращения для команд Git](#%D0%A1%D0%BE%D0%BA%D1%80%D0%B0%D1%89%D0%B5%D0%BD%D0%B8%D1%8F-%D0%B4%D0%BB%D1%8F-%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4-git)
- [Git Bash](#git-bash)
- [PowerShell в Windows](#powershell-%D0%B2-windows)
Чтобы клонировать (копировать) удаленный репозиторий, скопируйте адрес репозиторий и запустите:
```sh
$ git clone [url]
```
Git сохранит копию в папке с названием репозитория. Убедитесь, что уВас есть соединение с удаленным сервером, откуда Вы клонируете (в большинстве случаев это означает наличие выхода в Интернет).
Допустим, Вы не глядя сохранили изменения с помощью `git commit -a` и теперь не уверены что именно сохранили. В таком случае Вы можете просмотреть последний коммит в HEAD с помощью:
Если Вы уже сделали `push`, то Вы по-прежнему можете исправить коммит, но после этого придется делать `push`с принудительной перезаписью, что не рекомендуется.
Это особенно полезно, когда уВас открытый патч, а Вы сохранили ненужный файл и теперь нужно сделать принудительный `push` для обновления патча в удаленном репозитории. Опция `--no-edit` оставляет прежнее сообщение коммита без изменений.
Если хотите удалить опубликованные коммиты, воспользуйтесь приведенным ниже приемом. Однако, это бесповоротно изменит уВас историю Git, а также испортит историю Git у любого, что уже стянул (pull) изменения из репозитория. Короче говоря, никогда так не делайте, если не уверены.
Если Вы еще не опубликовали коммит, то просто сбросьте ветку в состояние перед Вашим последним коммитом (подготовленные изменения не пропадут):
```
(my-branch*)$ git reset --soft HEAD@{1}
```
Это работает, если Вы еще не сделали `push`. Если Вы уже сделали `push`, то единственный по-настоящему безопасный способ это `git revert SHAofBadCommit`. Это создаст новый коммит, который отменит все изменения предыдущего коммита. Или, если ветка, в которую вы делаете `push` безопасна для перезаписи (т.е. не предполагается, другие разработчики будут стягивать из нее изменения), то просто используйте `git push --force-with-lease`. Подробнее см. [в этом пункте выше](#delete-pushed-commit).
Напомним, что подобно перебазированию (см. ниже), исправление коммита (amend) **заменяет старый коммит новым**, поэтому Вы должны делать принудительный `push` (`--force-with-lease`) Ваших изменений, если хотите заменить уже опубликованные на удаленном репозитории коммиты. Будьте осторожны, когда так делаете –*всегда* проверяйте с какой веткой Вы проводите эти действия!
В общем, **избегайте делать принудительный push**. Лучше создать и опубликовать еще один коммит, чем переписывать измененные коммиты, т.к. это приведет к конфликтам истории у других разработчиков, которые работают с этой или дочерними ветками. `--force-with-lease` по-прежнему выдаст ошибку, если кто-то одновременно с Вами работает с данной веткой и Ваш принудительный push переписал бы чужие изменения.
Если Вы *абсолютно* уверены, что никто кроме Вас не работает с данной веткой или Вы хотите обновить вершину ветви в любом случае, то используйте `--force` (`-f`), но вообще этого следует избегать.
Замечание: Это относится только если ваша работа была сохранена, т.е. Вы сделали коммит или stash. `git reset --hard`*удалит* несохраненные изменения, так что пользуйтесь им с осторожностью. (Безопасная опция это `git reset --keep`.)
Если Вы случайно сделали слияние в основную ветку разработки до того, как были сделаны все необходимые изменения, Вы по-прежнему можете отменить слияние. Но есть одна загвоздка: Коммит слияния имеет более одного родителя (обычно два).
Команда для решения этой проблемы
```sh
(feature-branch)$ git revert -m 1 <commit>
```
где опция -m 1 говорит выбрать родителя номер 1 (ветка, в которую было сделано слияние) в качестве родителя для отката.
Заметка: номер родителя - это не идентификатор коммита. Допустим, коммит слияния имеет строчку `Merge: 8e2ce2d 86ac2e7`. Номер родителя - это порядковый номер (отсчет с 1) нужного родителя в этой строчке, первый идентификатор - номер 1, второй - номер 2 и т.д.
### Я случайно закоммитил и опубликовал файлы с конфиденциальными данными
Если Вы случайно опубликовали файлы, содержащие конфиденциальные данные (пароли, ключи и пр.), Вы можете изменить последний коммит с помощью amend. Помните, что как только Вы опубликовали коммит, то Вы должны считать всё его содержание скомпромитированны. С помощью дальнейших шагов можно удалить конфиденциальную информацию из публичного репозиторий или из Вашей локальной копии, вы **не сможете** удалить свою конфиденциальную информацию у людей, которые могли успеть скопировать себе её. Если Вы закоммитили пароль, то **незамедлительно поменяйте его**. Если Вы закоммитили ключ, то **незамедлительно сгенерируйте новый**. Изменения опубликованного коммита недостаточно, потому что кто-нибудь мог скопировать исходный коммит до того, как Вы успели его исправить.
Как только удалите конфиденциальные данные из файла, запустите
### Мне нужно изменить содержимое коммита, который не является последним
Пусть Вы сделали несколько (например, три) коммитов и после этого поняли, что упустили что-то, что по смыслу относится к первому из этих трёх коммитов. Вы могли бы сделать новый коммит, содержащий эти изменения, и тогда уВас была бы чистая кодовая база, но Ваши коммиты не были бы атомарными (т.е. связанные изменения не содержались бы в едином коммите). В такой ситуации Вы бы хотели изменить коммит, к которому относятся эти изменения, а следующие коммиты оставить как есть. В таком случае Вас может спасти `git rebase`.
Рассмотрим ситуацию, когда Вы хотите изменить третий с конца коммит.
```sh
(your-branch)$ git rebase -i HEAD~4
```
запустит интерактивный режим rebase, что позволит Вам отредактировать любые из Ваших последних трёх коммитов. Появится текстовый редактор с подобным содержанием:
```sh
pick 9e1d264 The third last commit
pick 4b6e19a The second to last commit
pick f4037ec The last commit
```
которое Вам нужно изменить так:
```sh
edit 9e1d264 The third last commit
pick 4b6e19a The second to last commit
pick f4037ec The last commit
```
Это говорит rebase, что Вы хотите изменить третий с конца коммит, а другие два оставить как есть. Теперь сохраните и закройте редактор. После этого Git начнет процедуру rebase. Он остановится на коммите, который Вы пометили для изменений, давая Вам возможность изменить этот коммит. Теперь Вы можете доделать то, что забыли первоначально. Отредактируйте и подготовьте изменения. После этого запустите
```sh
(your-branch)$ git commit --amend
```
это заставит Git пересоздать коммит, но оставить сообщение коммита прежним. После этого тяжелая часть работы завершена.
### Я хочу подготовить только часть файла, а не весь файл целиком
Обычно, если хотите подготовить часть файл, Вы запускаете:
```sh
$ git add --patch filename.x
```
`-p` - сокращение для `--patch`. Это откроет интерактивный режим. Вы сможете разбить коммит с помощью опции `s`, однако, если файл новый, то уВас не будет такой возможности. При добавлении нового файла делайте так:
```sh
$ git add -N filename.x
```
Затем используйте опцию `e` для ручного выбора строк. Запустив `git diff --cached` или
`git diff --staged`, Вы увидите какие строки вы подготовили по-сравнению с тем, что сохранено в рабочей копии.
### Я подготовил слишком много правок и теперь хочу разделить их на несколько отдельных коммитов
`git reset -p` откроет интерактивный диалог сброса. Это похоже на `git add -p`, за исключением того, что выбор "yes" уберёт правку из готовящегося коммита.
### Я хочу подготовить свои неподготовленные правки и убрать из подготовки то, что уже подготовлено
Это сложно. Лучшее, что я смог придумать это отложить (stash) неподготовленные изменения. Затем сделать сброс. После этого вернуть отложенные изменения и добавить их.
### Я сохранил коммит в ветку master вместо новой ветки
Создайте новую ветку, оставаясь на master:
```sh
(master)$ git branch my-branch
```
Сбросьте ветку master к предыдущему коммиту:
```sh
(master)$ git reset --hard HEAD^
```
`HEAD^` - это сокращение для `HEAD^1`. Это подставляет первого предка `HEAD`, подобно этому `HEAD^2` подставляет второго предка коммита (слияния могут иметь 2 предков).
Заметьте, что `HEAD^2` это **не** то же самое, что `HEAD~2` (для подробностей см. [эту ссылку](http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde)).
Если не хотите использовать `HEAD^`, то найдите хэш коммита, на который Вы хотите установить ветку (`git log` может помочь в этом). Затем сделайте сброс к этому хэшу. С помощью `git push` удостоверьтесь, что эти изменения отражены в удаленном репозитории.
К примеру, ветка master обязана находится на коммите с хэшем `a13b85e`:
### Я хочу сохранить файл целиком из другого ref-ish
Скажем, уВас рабочий spike (см. заметку) на сотни изменений. Всё работает. Теперь Вы сохраняете эту работу в другую ветку:
```sh
(solution)$ git add -A && git commit -m "Добавлены все изменения из этого рывка в один большой коммит."
```
Когда Вы хотите поместить его в ветку (например `feature` или `develop`), Вы хотите сохранять по целым файлам. А также Вы хотите разбить большой коммит на несколько небольших.
Вы можете выполнить это, перенеся содержимое файла в Вашу ветку:
```sh
(develop)$ git checkout solution -- file1.txt
```
Это скопирует содержимое данного файла из ветки `solution` в ветку `develop`:
```sh
# On branch develop
# Your branch is up-to-date with 'origin/develop'.
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: file1.txt
```
Теперь сделайте коммит как обычно.
Заметка: Spike-решения делаются для анализа или решения проблемы. Эти решения используют, чтобы оценить проблему, и отбрасывают сразу же, как только все получают ясное представление о проблеме. ~ [Wikipedia](https://en.wikipedia.org/wiki/Extreme_programming_practices).
### Я сделал несколько коммитов в одной ветке, а нужно было сохранять их в разных ветках
Скажем, Вы в ветке master. Запустив `git log`, Вы увидите, что сделали два коммита:
```sh
(master)$ git log
commit e3851e817c451cc36f2e6f3049db528415e3c114
Author: Alex Lee <alexlee@example.com>
Date: Tue Jul 22 15:39:27 2014 -0400
Bug #21 - Added CSRF protection
commit 5ea51731d150f7ddc4a365437931cd8be3bf3131
Author: Alex Lee <alexlee@example.com>
Date: Tue Jul 22 15:39:12 2014 -0400
Bug #14 - Fixed spacing on title
commit a13b85e984171c6e2a1729bb061994525f626d14
Author: Aki Rose <akirose@example.com>
Date: Tue Jul 21 01:12:48 2014 -0400
First commit
```
Обратим внимание на ссылки на каждый баг (`e3851e8` для #21, `5ea5173` для #14).
Во-первых, сбросим ветку master на правильный коммит (`a13b85e`):
```sh
(master)$ git reset --hard a13b85e
HEAD is now at a13b85e
```
Теперь, мы может создать новую ветку для бага#21:
```sh
(master)$ git checkout -b 21
(21)$
```
Теперь сделаем *cherry-pick* коммита для бага#21 на верх нашей ветки. Это значит, что мы помещаем этот и только этот коммит напрямую на вершину ветки, какой бы она ни была.
```sh
(21)$ git cherry-pick e3851e8
```
На этом этапе есть вероятность конфликтов. О том как разрешить конфликты см. в главе [**Здесь были конфликты**](#merge-conflict) в [разделе интерактивное перебазирование выше](#interactive-rebase).
Теперь давайте создадим новую ветку для бага#14, которая также основана на master
```sh
(21)$ git checkout master
(master)$ git checkout -b 14
(14)$
```
И наконец, сделаем cherry-pick коммита для бага#14:
Как только Вы слили пулл-реквест на GitHub, Вам предлагают удалить слитую ветку из Вашего форка. Если Вы не планируете продолжать работу в этой ветке, то для поддержания рабочей копии в чистоте Вы можете удалить локальные копии ненужных веток, чтобы не путаться в них.
Если Вы регулярно отправляете изменения в удаленное хранилище, большую часть времени Вы в безопасности. Но в один прекрасный момент Вы всё же можете случайно удалить Ваши ветки. Скажем, мы создали ветку и создали новый файл:
```sh
(master)$ git checkout -b my-branch
(my-branch)$ git branch
(my-branch)$ touch foo.txt
(my-branch)$ ls
README.md foo.txt
```
Давайте добавим его и сохраним.
```sh
(my-branch)$ git add .
(my-branch)$ git commit -m 'foo.txt added'
(my-branch)$ foo.txt added
1 files changed, 1 insertions(+)
create mode 100644 foo.txt
(my-branch)$ git log
commit 4e3cd85a670ced7cc17a2b5d8d3d809ac88d5012
Author: siemiatj <siemiatj@example.com>
Date: Wed Jul 30 00:34:10 2014 +0200
foo.txt added
commit 69204cdf0acbab201619d95ad8295928e7f411d5
Author: Kate Hudson <katehudson@example.com>
Date: Tue Jul 29 13:14:46 2014 -0400
Fixes #6: Force pushing after amending commits
```
Теперь мы переключаемся обратно на master и 'нечаянно' удаляем нашу ветку.
```sh
(my-branch)$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
(master)$ git branch -D my-branch
Deleted branch my-branch (was 4e3cd85).
(master)$ echo О, нет, моя ветка удалена!
О, нет, моя ветка удалена!
```
На этом этапе Вы должны быть знакомы с 'reflog' (расширенный журнал). Он хранит историю всех действий в репозитории.
```
(master)$ git reflog
69204cd HEAD@{0}: checkout: moving from my-branch to master
4e3cd85 HEAD@{1}: commit: foo.txt added
69204cd HEAD@{2}: checkout: moving from master to my-branch
```
Как мы можем видеть, у нас есть хэш коммита из удаленной ветки. Посмотрим, можем ли мы восстановить удаленную ветку.
В режиме `upstream` или в режиме `simple` (по-умолчанию в Git 2.0) параметра `push.default`, следующая команда отправит текущую ветку в удаленную ветку, которая была ранее зарегистрирована с помощью -u :
Вы можете слить/перебазировать Вашу ветку с неправильной веткой. А также бывают случаи, когда Вы не можете предугадать успешно ли завершится процесс перебазирования/слияния. Git сохраняет исходный указатель HEAD в переменную ORIG_HEAD перед тем как приступить к опасным операциям, так что вернуть ветку на состояние до перебазирования/слияния просто.
К сожалению, вы должны сделать принудительный push, если хотите, чтобы изменения были отражены на удаленной ветке. Это потому что у вас изменена история. Удаленная ветка не примет изменения, если не сделать принудительный push. Это одна из основных причин, по которым большинство людей основывает свой рабочий процесс на слиянии вместо перебазирования - большие команды могут столкнуться с проблемами, если разработчики будут делать принудительный `push`. Используйте это с осторожностью. Безопасный способ использовать перебазирование - это не отражать Ваши изменения напрямую на удаленную ветку, а вместо этого делать следующее:
Предположим, что Вы работаете в ветке, которая стала или станет пулл-реквестом в `master`. В простейшем случае когда всё, что Вы хотите сделать - это объединить *все* коммиты в один единственный коммит и Вам не важны временные метки, Вы можете сделать сброс и заново сделать коммит. Убедитесь, что ветка master обновлена и Ваши изменения сохранены, затем:
```sh
(my-branch)$ git reset --soft master
(my-branch)$ git commit -am "New awesome feature"
```
Если Вы хотите больше контроля, а также сохранить метки времени, Вам нужно сделать кое-что, называемое интерактивным перебазированием:
```sh
(my-branch)$ git rebase -i master
```
Если Вы не работаете с другой веткой, можете делать перебазирование относительно Вашей `HEAD`. Например, если Вы хотите объединить последние два коммита, Вам нужно делать перебазирование относительно `HEAD~2`. Для последних 3 - `HEAD~3` и т.д.
```sh
(master)$ git rebase -i HEAD~2
```
После того, как запустите интерактивное перебазирование, Вы увидите нечто подобное в Вашем текстовом редакторе:
```vim
pick a9c8a1d Some refactoring
pick 01b2fd8 New awesome feature
pick b729ad5 fixup
pick e3851e8 another fix
# Rebase 8074d12..b729ad5 onto 8074d12
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
```
Все строки, начинающиеся с`#` являются комментариями и не оказывают влияния на перебазирование.
Теперь замените команды `pick` на команды, перечисленные ниже. Также Вы можете удалить коммиты, удалив соответствующие строки.
Например, если Вы хотите **оставить только старейший коммит и объединить все последующие коммиты во второй коммит**, Вам нужно рядом с каждым коммитом кроме первого и второго вместо `pick` написать `f`:
```vim
pick a9c8a1d Some refactoring
pick 01b2fd8 New awesome feature
f b729ad5 fixup
f e3851e8 another fix
```
Если Вы хотите объединить эти коммиты **и переименовать коммит**, Вам нужно дополнительно добавить `r` рядом со вторым коммитом или просто используйте `s` вместо `f`:
```vim
pick a9c8a1d Some refactoring
pick 01b2fd8 New awesome feature
s b729ad5 fixup
s e3851e8 another fix
```
Теперь Вы можете переименовать коммит в следующем запросе, который появится.
```vim
Newer, awesomer features
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# rebase in progress; onto 8074d12
# You are currently editing a commit while rebasing branch 'master' on '8074d12'.
`--no-commit` производит слияние, но не делает коммит результата, давая пользователю возможность проверить и доработать результат слияния перед коммитом. `no-ff` сохраняет доказательства того, что когда-то существовала ветка feature, сохраняя цельность истории проекта.
#### Я хочу объединить только неопубликованные коммиты
Иногда уВас бывает несколько временных коммитов, которые Вы хотите объединить перед публикацией в upstream. Вы не хотите ненароком объединить свои коммиты с уже опубликованными, потому что кто-то уже мог работать с ними.
```sh
(master)$ git rebase -i @{u}
```
Это выполнит интерактивное перебазирование со списком еще не опубликованных коммитов и Вы сможете безопасно упорядочить/исправить/объединить коммиты из списка.
#### Мне нужно прервать слияние
Иногда слияние может создавать проблемы в некоторых файлах. В таких случаях мы можем воспользоваться опцией `abort` для прерывания текущего процесса разрешения конфликтов и попробовать вернуться к состоянию перед слиянием.
### Мне нужно обновить родительский коммит моей ветки
Скажем, у меня есть ветка master, ветка feature-1, выросшая из master, и ветка feature-2, выросшая из feature-1. Если я сделаю коммит в feature-1, тогда родительский коммит ветки feature-2 будет не тем, что нужно (это должна быть верхушка feature-1, поскольку мы ответвились от неё). Мы можем исправить это с помощью `git rebase --onto`.
```sh
(feature-2)$ git rebase --onto feature-1 <первыйкоммитизfeature-2,которыйВынехотитепереносить> feature-2
```
Это помогает в тех случаях, когда уВас одна функция основывается на другой функции, которая еще не слита, и все исправления feature-1 должны быть отражены в feature-2.
Это значит, что Вы пытаетесь сделать перебазирование в ветку, которая уже имеет идентичный коммит или она *впереди* текущей ветки. Вы может попробовать:
-Во время *перебазирования* используйте `--theirs` для сохранения изменений из локальной ветки или `--ours` для сохранения изменений из другой ветки. Для объяснения такого обмена см. [эту заметку в документации Git](https://git-scm.com/docs/git-rebase#git-rebase---merge).
Если слияние более сложное, можете воспользоваться визуальным редактором различий:
```sh
(master*)$ git mergetool -t opendiff
```
После разрешения всех конфликтов и тестирования кода подготовьте файлы, которые Вы изменили `git add`, а затем продолжите перебазирование с помощью `git rebase --continue`
```sh
(my-branch)$ git add README.md
(my-branch)$ git rebase --continue
```
Если после разрешения всех конфликтов, Вы получили точно такое же дерево, какое было перед коммитом, то вместо этого Вам нужно сделать `git rebase --skip`.
В любой момент Вы можете остановить перебазирование и вернуть ветку в начальное состояние, выполнив:
### Я хочу искать по автору или сохранившему изменения (committer)
Найти все коммиты по автору или сохранившему изменения:
```sh
$ git log --author=<nameoremail>
$ git log --committer=<nameoremail>
```
Не забывайте, что автор и сохранивший изменения - это не всегда один и тот же человек. `--author` - это тот, кто написал код, а`--committer` - тот, кто сохранил код, написанный автором.
### Я хочу посмотреть историю коммитов для отдельной функции
Для отслеживания эволюции отдельной функции Вы можете использовать:
```sh
$ git log -L :FunctionName:FilePath
```
Заметьте, что Вы можете добавить и другие опции команды `git log`, вроде [диапазона ревизий](https://git-scm.com/docs/gitrevisions) и [выборки коммитов](https://git-scm.com/docs/git-log/#_commit_limiting).
Если кто-то прислал Вам пулл-реквест на GitHub, но потом удалил свой форк, то вы не сможете клонировать его репозиторий или использовать `git am`, поскольку [.diff, .patch](https://github.com/blog/967-github-secrets) URL'ы становятся недоступными. Но Вы можете сделать `checkout` самого пулл-реквеста используя [специальные GitHub's refs](https://gist.github.com/piscisaureus/3342247). Для получения содержимого PR#1 в новую ветку с названием pr_1:
### Как опубликовать ветку и метку, если они имеют одинаковые имена
Если в удаленном репозитории есть метка с таким же именем, как и ветка <branch>, то после выполнения команды `$ git push <remote> <branch>` Вы получите следующую ошибку:
```sh
$ git push origin <branch>
error: dst refspec same matches more than one.
error: failed to push some refs to '<gitserver>'
```
Исправить это можно, указав Вы хотите опубликовать именно ветку.
```sh
$ git push origin refs/heads/<branch-name>
```
Если Вы хотите опубликовать метку с таким же названием, как у ветки, используйте сходную команду.
Обратите внимание, что это *не* удаляет файл из контроля версий - он всего лишь игнорируется локально. Чтобы отменить это и сказать Git снова отслеживать изменения, выполните обратную команду:
В OS X и Linux Ваш файл конфигурации Git хранится в `~/.gitconfig`. В качестве примера я добавил некоторые псевдонимы, которые сам использую для краткости (а также некоторые из моих типичных опечаток), в раздел `[alias]` как показано ниже:
УВас может быть репозиторий, требующий авторизации. В этом случае вы можете сохранить на время имя пользователя и пароль, и Вам не потребуется вводить их при каждом вызове push или pull. Помощник по учетным записям сделает это за Вас.
Итак, Вы в затруднении - Вы сбросили что-то или Вы слили неправильную ветку, или Вы отправили изменения с принудительной перезаписью и теперь Вы не можете найти свои коммиты. Вы знаете, что в какой-то момент было всё в порядке и Вы хотите вернуться к этому состоянию.
Как раз для этого и нужен `git reflog`. `reflog` отслеживает все изменения вершины ветки, даже если на эту вершину не указывает ни единая ветвь или метка. В принципе, всякий раз при изменении HEAD, в reflog добавляется новая запись. К сожалению, это работает только с локальными репозиториями и отслеживаются только движения (а не, например, изменения файла, которые не были никуда записаны).
```sh
(master)$ git reflog
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to master
c10f740 HEAD@{2}: checkout: moving from master to 2.2
```
reflog выше показывает переход с ветки master на ветку 2.2 и обратно. Затем происходит жесткий сброс на старый коммит. Самое последнее действие находится вверху с надписью `HEAD@{0}`.
Если Вы случайно переместитесь назад, то reflog будет содержать коммит (0254ea7), на который указывала ветка master до того, как Вы случайно выбросили 2 коммита.
С помощью `git reset` можно вернуть ветку master обратно на коммит, на котором она была прежде. Это обеспечивает безопасность при случайном изменении истории.
Как только Вы освоитесь с командами, описанными выше, возможно, Вам захочется написать сокращения для Git Bash. Это позволит Вас работать гораздо быстрее, выполняя сложные задачи с помощью весьма коротких команд.
```sh
alias sq=squash
function squash() {
git rebase -i HEAD~$1
}
```
Скопируйте эти команды в Ваш .bashrc или .bash_profile.
### PowerShell в Windows
Если Вы пользуетесь PowerShell на Windows, то и здесь Вы можете настроить псевдонимы и функции. Добавьте эти команды в Ваш профиль, путь к которому указан в переменной `$profile`. Узнать больше о профилях можно на портале документации Microsoft [About Profiles](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles).
- [Конструктивно о слиянии и перебазировании в Git](https://medium.com/@porteneuve/getting-solid-at-git-rebase-vs-merge-4fa1a48c53aa)
* [Git Commands and Best Practices Cheat Sheet](https://zeroturnaround.com/rebellabs/git-commands-and-best-practices-cheat-sheet) - Шпаргалка Git с подробными пояснениями
* [Git изнутри](https://codewords.recurse.com/issues/two/git-from-the-inside-out) - Учебник, погружающий во внутренности Git
- [git-workflow](https://github.com/asmeurer/git-workflow) - Руководство от [Aaron Meurer](https://github.com/asmeurer) по использованию Git в совместной разработке проектов с открытым исходным кодом
- [GitHub как рабочий процесс](https://hugogiraudel.com/2015/08/13/github-as-a-workflow/) - Интересный подход к использованию GitHub в качестве рабочего процесса, в частности с пустыми пулл-реквестами
- [Githug](https://github.com/Gazler/githug) - Игра для изучения более общих рабочих процессов Git
- [firstaidgit.io](http://firstaidgit.io/) Выборка наиболее частых вопросов и ответов по Git c поиском
- [git-extra-commands](https://github.com/unixorn/git-extra-commands) - сборник полезных дополнительных скриптов для Git
- [git-extras](https://github.com/tj/git-extras) - GIT utilities -- статистика репозитория, REPL, генерация журнала изменений, статистика по авторам изменений и многое другое
- [git-fire](https://github.com/qw3rtman/git-fire) - git-fire - это плагин для Git, который предупреждает при потенциально опасных действиях, таких как: добавление всех файлов из текущей папки, создание коммита и публикация измений в новую ветку (для предотвращения конфликтов при слиянии).
- [git-tips](https://github.com/git-tips/tips) - Краткие советы по Git
- [git-town](https://github.com/Originate/git-town) - Общая высокоуровневая поддержка рабочего процесса Git! http://www.git-town.com
- [GitKraken](https://www.gitkraken.com/) - роскошный Git-клиент для Windows, Mac и Linux
- [git-cola](https://git-cola.github.io/) - еще один Git-клиент для Windows и OS X
- [GitUp](https://github.com/git-up/GitUp) - новый графический клиент, имеющий весьма своеобразные методы работы со сложностями Git
- [gitx-dev](https://rowanj.github.io/gitx/) - еще один графический Git-клиент для OS X
- [Sourcetree](https://www.sourcetreeapp.com/) - Простота и мощь в красивом и свободном графическом Git-клиенте. Для Windows и Mac.
- [Tower](https://www.git-tower.com/) - графический Git-клиент для OS X (платный)
- [tig](https://jonas.github.io/tig/) - консольный текстовый интерфейс для Git
- [Magit](https://magit.vc/) - интерфейс для Git, реализованный в виде модуля Emacs.
- [GitExtensions](https://github.com/gitextensions/gitextensions) - расширение оболочки, плагин для Visual Studio 2010-2015 и автономный инструмент для управления репозиториями Git.
- [Fork](https://git-fork.com/) - быстрый и дружелюбный Git-клиент для Mac (бета)
- [gmaster](https://gmaster.io/) - Git-клиент для Windows с трехсторонним слиянием, обнаружением рефакторинга, семантическим сравнением и слиянием (бета)
- [gitk](https://git-scm.com/docs/gitk) - Git-клиент под Linux для просмотра состояния репозитория.
* [SublimeMerge](https://www.sublimemerge.com/) - Шустрый, расширяемый клиент для трехстороннего слияния, мощного поиска и подсветки синтаксиса. В активной разработке.