JavaRush /Курсы /C++ SELF /Инструменты профессионала и решение проблем

Инструменты профессионала и решение проблем

C++ SELF
36 уровень , 4 лекция
Открыта

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

1. Rollback — откат локальных изменений до коммита

Сценарий: вы изменили файл, но поняли, что все ваши правки неверны, и хотите быстро вернуть файл к тому состоянию, в котором он был сохранен в последнем коммите.

Используйте функцию Rollback:

  1. Откройте вкладку Commit на левой панели.
  2. Найдите в списке измененный файл (или выделите несколько файлов), который вы хотите "откатить".
  3. Щелкните по нему правой кнопкой мыши и выберите Rollback (или нажмите иконку закругленной стрелочки).

IDE предупредит вас, что не сохраненные изменения будут утеряны. Согласитесь, и файл мгновенно вернется к своей последней "чистой" версии из Git. Это самый простой и безопасный способ отменить локальные эксперименты.

2. Магия "Amend": как дополнить последний коммит

Сценарий: вы только что нажали кнопку Commit и тут же осознали, что забыли прикрепить один важный файл (например, обновленный тест) или сделали нелепую опечатку в сообщении коммита. Делать новый коммит с сообщением "Добавил забытый файл" — дурной тон.

Вместо этого используйте функцию Amend (дополнить/исправить):

  1. В окне Commit внесите нужные исправления в забытый файл и поставьте напротив него галочку.
  2. В панели Commit Message найдите чекбокс Amend (или иконку шестеренки -> Amend Commit) и отметьте его.
  3. IDE подтянет сообщение вашего предыдущего коммита. Вы можете отредактировать его.
  4. Нажмите Commit.

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

Подробнее об этой функции читайте в официальном туториале JetBrains.

3. Undo Commit

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

Используйте функцию Undo Commit:

  1. Откройте историю, вкладка Git -> Log внизу.
  2. Щелкните правой кнопкой мыши по самому верхнему (вашему последнему) коммиту.
  3. Выберите Undo Commit.

Выберите список изменений (обычно Default Changelist) и нажмите OK. Коммит исчезнет из истории, а все ваши файлы вернутся в окно Commit со статусом измененных. Вы ничего не потеряли и можете спокойно продолжить писать код.

4. Reset — удаление локальной истории (Осторожно!)

Функция Reset Current Branch to Here... — это мощный инструмент, который перемещает указатель вашей ветки на любой выбранный коммит. В зависимости от ситуации, эта кнопка может как деликатно отменить последние действия, так и радикально стереть сломанный код.

Сценарий А: Отмена последних локальных коммитов

Вы сделали несколько коммитов локально (до Push) и поняли, что вся эта ветка развития была ошибочной.

  1. Откройте вкладку Git -> Log.
  2. Найдите последний "хороший" коммит, на котором вы хотите оказаться (тот, что был до серии ошибочных).
  3. Щелкните по нему правой кнопкой мыши и выберите Reset Current Branch to Here....

Сценарий Б: Сброс до состояния сервера

Вы экспериментировали локально, запутались в конфликтах, и проект перестал собираться. Вы хотите сказать: "Гит, удали всё, что я тут натворил, и сделай мою ветку точно такой же чистой, как она сейчас лежит на сервере GitHub".

  1. Откройте Git -> Log.
  2. Найдите в списке маркер удаленной ветки. Обычно это коммит с фиолетовым ярлыком origin/main (или origin/имя_вашей_ветки). Это последнее известное состояние кода на сервере.
  3. Щелкните по этому коммиту правой кнопкой мыши и выберите Reset Current Branch to Here....
Окно Reset Current Branch

Режимы сброса

В обоих сценариях IDE предложит вам выбрать режим сброса. Для новичков важно знать два из них:

  • Mixed / Soft: Безопасный режим. Коммиты удалятся из истории, но все изменения в файлах останутся у вас в редакторе (как большое Undo). Идеально подходит для Сценария А, если вы хотите пересобрать коммиты заново.
  • Hard: Радикальный режим. Безвозвратно удаляет и коммиты, и все незакоммиченные изменения в коде. Ваш проект полностью откатится к состоянию выбранного коммита. Именно этот режим нужен для Сценария Б, чтобы ваша локальная ветка стала точной копией сервера. Используйте его, только если на 100% уверены, что написанный локально код вам больше никогда не понадобится.

5. Что делать после Push?

Сценарий: вы сделали push, и только потом заметили в нем ошибку.

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

Правильное и безопасное решение:

Просто сделайте новый коммит, который исправляет ошибку, и отправьте его обычным push. Это абсолютно нормальная практика. Если ошибка связана с функциональностью или логикой кода, лучше написать исправление руками. Линейная история, где за ошибочным кодом идет понятный коммит с фиксом, делает эволюцию проекта прозрачной для всей команды.

В IDE также есть специальная функция Revert Commit. Если вы щелкните правой кнопкой мыши по ошибочному коммиту в логе Git -> Log и выберете Revert Commit, IDE автоматически создаст новый "анти-коммит", который делает ровно противоположное тому, что делал ошибочный (например, удалит добавленные строки).

Когда стоит применять Revert?

Хотя кнопка выглядит волшебной, использовать ее для сложного кода нужно с осторожностью. Когда история коммитов превращается в цепочку "Коммит -> Коммит -> Реверт -> Коммит", вашим коллегам при код-ревью можно буквально "сломать голову", пытаясь понять, что в итоге работает, а что отменено.

Зато Revert Commit работает идеально для изолированных текстовых правок. Например, маркетологи попросили обновить текст на главной странице. Вы сделали коммит и пуш, а через час бизнес передумал и попросил вернуть старый текст. В этом случае Revert в один клик вернет всё как было, сэкономив вам время и оставив абсолютно понятный след в истории.

6. Stash / Shelve: как временно спрятать изменения

Сценарий: вы активно пишете код новой фичи, все файлы красные и синие. Вдруг прибегает тимлид: "Бросай все, срочно нужно пофиксить баг в ветке main!". Вы не можете переключиться на main, потому что у вас есть незавершенные конфликтующие изменения. Делать коммит с наполовину недописанным кодом тоже нельзя.

Решение — временно "спрятать" вашу работу в виртуальную коробку. В Git это называется Stash, а в IntelliJ IDEA есть свой улучшенный аналог — Shelve (отложить на полку).

  1. Откройте окно Commit, выделите измененные файлы.
  2. Щелкните правой кнопкой мыши и выберите Shelve Changes... (или Git -> Stash Changes).
  3. Напишите понятное имя для этой "закладки" и нажмите Shelve.

Ваши файлы мгновенно вернутся к исходному состоянию. Теперь вы можете безопасно переключиться на main, исправить баг, сделать коммит и отправить его. Когда срочная задача будет выполнена, вернитесь в свою рабочую ветку, откройте вкладку Shelf (Полка), щелкните по вашим спрятанным изменениям правой кнопкой и выберите Unshelve. Ваш недописанный код вернется на место, и вы сможете продолжить работу!

7. Заглянуть в прошлое: продвинутая работа с логом

Мы уже знакомы с окном Git -> Log, но это не просто список коммитов, а мощный инструмент для расследований.

  • Хеш коммита: вы наверняка заметили в логе строку из букв и цифр, например a1b2c3d. Этот хеш — уникальный идентификатор каждого "снимка" вашего кода. Хеш коммита в логах
  • Вы можете фильтровать историю по ветке, автору, дате или даже по слову в сообщении коммита. Это помогает быстро найти, кто и когда работал над определенной частью функционала.
  • Хотите найти коммит, в котором была добавлена или удалена конкретная строка кода? В окне Log есть поле для поиска, которое ищет не только по сообщениям, но и по содержимому самих изменений.
  • Щелкните правой кнопкой мыши на полях редактора кода (там, где номера строк) и выберите Annotate with Git Blame. IDE покажет напротив каждой строки, кто и в каком коммите ее последний раз менял. Это невероятно полезно для понимания, почему код написан именно так.

8. Опасная зона: Force Push

Итак, мы установили, что изменять отправленные коммиты — плохая идея. Но что, если вы все-таки изменили свою локальную историю (например, с помощью Undo Commit или Amend), а на сервере уже лежит старая версия? При попытке сделать обычный push Git выдаст ошибку, защищая общую историю от перезаписи.

Для таких случаев существует опция — force push (принудительная отправка). Эта команда говорит серверу: "Забудь все, что у тебя было. Моя локальная версия истории — единственно верная. Замени свою историю моей".

ВНИМАНИЕ! В 99% случаев использование force push в командных проектах — это катастрофа. Это может безвозвратно удалить коммиты, которые ваши коллеги уже скачали и на основе которых они работают.

Когда категорически НЕЛЬЗЯ использовать force push:

  • На любые общие ветки: main, develop, master. Никогда.
  • На любую ветку, с которой работает кто-то еще кроме вас.

Единственный допустимый сценарий:

Вы работаете в своей личной feature-ветке, которую еще никто не видел и не скачивал. Вы сделали несколько "грязных" коммитов, отправили их на сервер, а потом решили их объединить или исправить опечатку через Amend. В этом случае вы можете сделать force push, чтобы обновить свою ветку на сервере перед созданием Pull Request.

В IDE эта опция обычно спрятана в выпадающем меню кнопки Push. Разработчики IDE сделали это намеренно, чтобы вы не нажали ее случайно.

Кнопка Force Push

Если вы не уверены на 100%, что делаете, — никогда не используйте force push. Безопаснее создать новый коммит с исправлениями (или использовать Revert).

9. Обновление проекта

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

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

10. Контекстное меню Git Log

Когда вы открываете вкладку Git -> Log и кликаете правой кнопкой мыши по любому коммиту, появляется огромное контекстное меню. Давайте разберем самые полезные команды сгруппировав их по задачам.

Группа 1: Просмотр и анализ (Безопасные действия)

  • Copy Revision Number — копирует уникальный хеш коммита в буфер обмена. Полезно, если нужно скинуть ссылку на коммит коллеге в чат или указать его в задаче (Jira/YouTrack).
  • Compare with Local — позволяет сравнить состояние любого файла из того старого коммита с тем, что у вас сейчас не сохранено в редакторе (в рабочей директории). Отличный способ понять: "А как этот код выглядел месяц назад?".
  • Show Repository at Revision — открывает окно, где можно посмотреть структуру всех файлов проекта именно в том состоянии, в котором они были в момент этого коммита (при этом ваша текущая рабочая ветка не меняется).

Группа 2: Работа с ветками

  • New Branch... — создает новую ветку прямо от выбранного коммита в прошлом. Незаменимо, если вы ушли далеко вперед, поняли, что всё сломали, и хотите начать новую ветку от последнего "рабочего" места.
  • Checkout Revision — переключает ваш локальный проект на этот коммит. Вы окажетесь в состоянии "отсоединенной головы" (detached HEAD). Это значит, что вы можете запустить старый код, побродить по нему, но если начнете делать новые коммиты, они не привяжутся ни к какой ветке. Для возврата к нормальной работе просто сделайте Checkout вашей обычной ветки (например, main).

Группа 3: Изменение и перенос

  • Cherry-Pick (Вишенка на торте) — невероятно полезная команда! Позволяет "выдернуть" один конкретный коммит из чужой (или вашей другой) ветки и скопировать его в вашу текущую ветку. Например, кто-то в другой ветке пофиксил баг, который блокирует вашу работу — вы просто делаете Cherry-Pick этого коммита к себе, не сливая (merge) всю чужую ветку целиком.
  • Edit Commit Message... — если коммит еще не был отправлен на сервер (не было Push), вы можете быстро переименовать его сообщение. Гораздо удобнее, чем делать Amend, если нужно поменять только текст.

Группа 4: Отмена изменений

Эти команды мы подробно разобрали в предыдущих разделах:

  • Reset Current Branch to Here... — сдвигает вашу текущую ветку на этот коммит (с удалением истории впереди).
  • Revert Commit — создает "анти-коммит" для безопасной отмены на сервере.
  • Undo Commit... — разбирает локальный коммит обратно в окно изменений.

Группа 5: Переписывание истории

В меню также есть такие команды, как Squash Commits... (объединить несколько коммитов в один), Drop Commits (удалить коммит из середины истории) или Interactively Rebase from Here.... Это инструменты мощной хирургической работы над локальной историей (Interactive Rebase).

Совет:

Пока вы учитесь, старайтесь не использовать эти команды, так как они полностью переписывают историю. В реальной командной работе их применяют для "причесывания" своей черновой локальной ветки перед тем, как отдать ее на ревью (создать Pull Request).

11. Напутствие

Системы контроля версий могут показаться сложными: ветки, слияния, конфликты, пугающие хеши коммитов. Но помните главное: Git — это ваша страховочная сетка. Каждый Senior-разработчик когда-то в панике гуглил, как выйти из состояния "detached HEAD" или как отменить случайный пуш. Не бойтесь экспериментировать. Ошибаться локально — это абсолютно нормально, ведь теперь у вас есть полный арсенал инструментов IntelliJ IDEA, чтобы отменить, откатить и исправить любую оплошность до того, как ее увидит команда. Делайте коммиты часто, пишите понятные сообщения, всегда делайте Update Project по утрам, и вы станете надежным и профессиональным участником любого проекта.

12. Практическое задание со звездочкой

Предлагаем вам выполнить небольшое, но очень хитрое задание. С этой проблемой сталкивается 90% разработчиков, когда начинают работать на нескольких проектах.

Ваша задача:

  1. Зарегистрируйте второй аккаунт на GitHub с другим Email-адресом.
  2. Добавьте этот новый аккаунт в IntelliJ IDEA.
  3. Создайте новый репозиторий, склонируйте его, напишите пару строк кода и сделайте Commit и Push, выбрав ваш новый аккаунт.
  4. А теперь зайдите на страницу git-log и внимательно посмотрите на историю коммитов.

В чем подвох?

Скорее всего, вы с удивлением обнаружите, что автором коммита числится ваш первый (основной) аккаунт, хотя вы точно пушили от имени нового профиля!

Исследование:

Ваша цель — разобраться, почему так произошло. Подсказка: авторизация на сайте GitHub (чтобы иметь права на Push) и подпись автора внутри самого коммита — это не одно и то же. Найдите способ (через терминал?), как переключить user.name и user.email так, чтобы они применялись только к этому конкретному проекту, не ломая настройки вашего основного аккаунта. Сделайте новый коммит и добейтесь того, чтобы истории был коммит от аккаунта номер 2.

1
Опрос
Знакомство с Git и GitHub, 36 уровень, 4 лекция
Недоступен
Знакомство с Git и GitHub
Контроль версий: работа с Git и GitHub
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ