Видео может быть заблокировано из-за расширений браузера. В статье вы найдете решение этой проблемы.

Здравствуйте!

Сегодня мы продолжим знакомиться с возможностями команды git add.

При общем рассмотрении команды git add, я не рассматривал 3 очень полезные опции:

  • git add -p ...
  • git add -i ...
  • git add -e ...

В рамках данного урока мы познакомимся с данными опциями.

Обычно, при работе с git мы добавляем изменения при помощи команд git add ... или git rm .... Если в случае с git rm все сразу понятно, то при вызове git add весь контент файла, или проще говоря, текущее состояние файла добавляется в индекс. Очень часто бывает, что не все изменения необходимо вносить в одном коммите, а стоит разбить на 2 и более коммитов. Как поступать в данном случае? Никто не хочет постоянно держать в голове контекст изменения кода. Да и не представляется возможным такой подход. В данном случае на помощь приходит опция -p или -e при вызове команды git add. Эффект у этих опций примерно одинаков, за небольшим отличием, на котором я акцентирую внимание чуть позже.

git add -p ...

Давайте рассмотрим добавление изменений в репозиторий при помощи команды git add -p?

Все изменения, которые были выполнены и не добавлены в индекс, git интерпретирует как hunk (s) (небольшие, логические изменения кода). Даже, если изменений было много, git, насколько это возможно, представит эти изменения в виде множества, и вы сможете каждое изменеие рассмотреть в отдельности. Когда вы выполняете команду git add -p ... git показывает вам эти изменения и спрашивает, хотите ли вы добавить их в индекс? На данный вопрос возможны следующие варианты ответа:

  • y - Добавить показанный hunk в индекс
  • n - Пропустить показанный hunk, не добавлять его в индекс

Обычно двумя этими вараинтами все и ограничиваются :) Однако, оглашу весь список.

  • q - Отменить добавление hunk и выйти, то, что вы добавили в индекс будет отменено.
  • a - Добавить показанный hunk в индекс, а также все остальные hunk из рассматриваемого файла.
  • d - Не добавлять показанный hunk в индекс, и завершить рассмотрение всех остальных изменений в текущем файле.
  • g - Выбрать hunk, к которому стоит перейти
  • / - Поиск hunk по предоставленному regex выражению
  • j - не принимать решение по данному hunk, перейти к следующему не рассмотренному hunk
  • J - не принимать решение по данному hunk, перейти к следующему hunk
  • k - не принимать решение по данному hunk, перейти к предыдущему не рассмотренному hunk
  • K - не принимать решение по данному hunk, перейти к предыдущему hunk
  • s - Разделить текущий hunk на более мелкие hunk
  • e - Добавить показанный hunk с предварительным редактирование
  • ? - Отобразить справочную информацию

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

Мы видим часть изменений. Если мы укажем y, то все изменения будут добавлены и файл будет подготовлен к коммиту. При выполнении команды git diff --cached мы видим какие изменения были добавлены. В принципе, это то самое, что было отображено нам ранее при выполнении команды git diff.

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

При рассмотрении текущего hunk git не предлагает нам разбить его на более мелкие, он попросту не знает как это сделать. Однако мы видим часть кода, который не нужно добавлять в индекс. Давайте отредактируем этот hunk и добавим только нужные изенения в index. Для этого воспользуемся опцией e.

В показанном патче нам необходимо удалить 10 и 11 строки. Для этого просто удалим эти строки из патча, который нам привел diff и сохраним изменения. Теперь посмотрим, какие изменения были добавлены в виндек для последующего коммита. При выполнении команды git diff --cached мы видим, что не нужные нам строки не были добавлены в индекс. Для того, чтобы убедиться в корректности выполненной операции посмотрим на дифф файла, который не был добавлен в индекс. При выполнении команды git diff мы видим как раз те строчки, которые мы не хотели добавлять в индекс.

Важное замечание: данный режим работает только с файлами, которые находятся под версионным контролем. Если файл не добавлен под версионный контроль, и вы хотите добавить только часть файла в текущем коммите - то используйте опцию -N перед выполенение команды git add -p. В таком случае файл попадет под версионный контроль, но как-буд-то пустой, и вы сможете добавить только нужные изменения.

Таким образом в данном режиме добавления информации в индекс вы можете шаг за шагом добавлять именнно нужные для коммита части изменений и именно в том виде, который вам необходим (вплоть до редактирования конкретных строк). Складывается такое ощущение, что вы отправляетесь в прошлое, в тот самый момент, когда нужно было выполнить команду git add. Коммиты получаются чистыми, лаконичными и идеально правильными.

git all -e ...

В отличии от вызова git add -p ... при использовании опции -e вам отобразится весь дифф с возможностью отредактировать, что именно вы добавите в индекс.

git add -i ...

--interactive (или -i) это большой брат опции --patch. --patch ограничивается предоставлением информации по hunks из файла или фалов. --interactive предоставляет вам намного больше возможностей. Настолько больше, что у данного режима есть свое собственное меню:

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> 
  1. [s]tatus - Аналогично git status отобразит состояние индекса
  2. [u]pdate - Позволяет добавить данные в индекс. Можно провести аналогию с git add -u .... Фактически работает только с теми файлами рабочей директории, которые находятся под версионным контролем
  3. [r]evert - Отменяет изменения файлом до состояния HEAD. Действие аналогично команде git checkout path, или git reset --hard HEAD path
  4. [a]dd untracked - Добавление не отслеживаемых файлов в индекс
  5. [p]atch - Добавление части изменений. Аналогично команде git add -p path
  6. [d]iff - Отобразить дифф изменений между индексом и HEAD. Аналогично команде git diff --cached path
  7. [q]uit - Выйти из интерактивного режима индексирования
  8. [h]elp - Отобразить справочную информацию

Отличительная особенность этого режима в том, что вы можете указать какой именно файл(ы) обрабатывать.

Мы учим программированию с нуля до стажировки и работы. Попробуйте наш бесплатный курс «Введение в программирование» или полные программы обучения по Node, PHP, Python и Java.

Хекслет

Подробнее о том, почему наше обучение работает →