Давно не писал про phpstorm. Да и чего тут писать, казалось бы. Документация в публичном доступе, бесплатная версия доступна для скачивания, да и лицензия стоит не так дорого. Полно уже информации о том, что это наикрутейший инструмент, который есть сейчас на рынке для разработки приложений на php. Но все еще много сомневающихся, многих отталкивает его «монструозность», «тормознутость» (все познается в сравнении). Лично мне кажется, что дело не в перечисленных выше факторах, а в непонимании, как им пользоваться. Читать огромную доку - лень, изучать что-то новое - лень. Программисты - они вообще люди ленивые в большинстве своем.

Многие приходят ко мне на сайт в поисках информации о phpstorm. И этим постом я хочу начать новый цикл статей о phpstorm, который будет раскрывать наиболее полезные фичи этого наикрутейшего инструмента. В этой статье поговорим об интеграции с git.

Осторожно, под катом очень много картинок, гифок, и … текста …

Дисклеймер

Давайте сразу договоримся - есть крутые гуру, которые не признают GUI-вариант управления git репозиторием. Нравится - пользуйтесь дальше. Я понимаю, что в CLI возможности git’а раскрываются на 100%. Но есть такие сценарии, когда с git гораздо удобнее работать именно в GUI. Мы все это понимаем и осознаем, и спор об этом выходит за рамки данной статьи.

Информация о том, что такое git, зачем он нужен, как его установить, как им пользоваться в целом - все это тоже остается за пределами данного материала.

Еще я пишу все это на Maс, поэтому может возникнуть путаница с расположением пунктов меню и хоткеями. Но я постараюсь отдельно прописать это и для Windows, главное не забыть.

Для кого эта статья.

  • для начинающих разработчиков, которые сели за phpstorm и не знают с какой стороны к нему подступиться
  • для прожжёных старпёров, которые пользуются Notepad++/Sublime Text/Atom/Coda и иже с ними, а также используют git через cli на постоянной основе
  • для любителей Tortoise Git или SourceTree, или каких-то иных GUI; материал позволит вам сравнить ваш инструментарий с возможностями, предлагаемыми PhpStorm
  • для всех тех, кто хочет перейти на PhpStorm и кому еще недостаточно поводов это сделать
  • для меня, чтобы систематизировать и упорядочить, а также приумножить знания об этой замечательной IDE

Начало

После того, как git установлен в вашей ОС, нужно подключить его к PhpStorm. Сделать это можно в настройках IDE по адресу File | Default Settings … | Version Control | Git. Тут есть опция Path to Git executable, в которой нужно задать путь до исполняемого файла git. В 99% случаев он определится автоматически, но если вдруг у вас какой-то специфичный случай, нужно тут указать путь до бинарника с git. После указания нужно нажать на кнопочку Test, чтобы убедиться, что все ок.

Если вдруг вы не нашли этот пункт меню, то вероятно у вас не установлен плагин «Git Integration». Обычно он установлен и включен по-умолчанию в стартовой инсталляции PhpStorm, но мало ли.

Кстати, тут сразу можно обратить внимание, что PhpStorm даст фору любому GUI по количеству опций, которые можно настроить. Одних только дефолтных настроек 9 вкладок (которые будут работать во всех системах контроля версий, а не только в git). А есть еще специфичные для каждого проекта и vcs опции. А еще опции для разных частей интерфейса … впрочем, обо всем по порядку.

Подключение репозитория к проекту

Мне встречалось, как минимум, 3 способа подключения репозитория к проекту. Я разделяю их на основной и вспомогательные. Я считаю, надо описать основной, чтобы иметь возможность создать репозиторий всегда, а про вспомогательные я напишу мельком.

По-дефолту, PhpStorm ассоциирует корень репозитория с корнем проекта. Если ваш проект еще не содержит репозитория, то нужно зайти в меню VCS | Enable Version Control Integration, из него вывалится всплывашка, предлагающая выбрать систему контроля версий. Выбираем git и жмем Ok.

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

Если у вас уже есть репозиторий, то нужно его подключить к проекту. Для этого нужно проследовать в настройки проекта PhpStorm | Preferences | Version Control. При входе в это меню можно будет увидеть окно, которое показывает список соответствий между директориями проекта и репозиториями. PhpStorm использует модель версионирования на основе директорий, поэтому каждый репозиторий должен быть связан с какой-то директорией.

PhpStorm довольно умный, и если он нашел репозитории внутри вашего проекта, он покажет их все. Вам останется только выбрать нужный репозиторий. Кроме этого он покажет отдельной строкой директорию , которая ассоциирована с корнем вашего проекта. Если ваш репозиторий находится в корне проекта, то просто ассоциируем с типом VCS - Git:

Если же ваш репозиторий находится глубже по уровню - выбираем найденный phpstorm’ом репозиторий и также нажимаем на плюсик.

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

Тут есть киллер фича, можно привязать несколько репозиториев к одному проекту, в том числе и с разными системами контроля версий. О нескольких репозиториях я расскажу позже.

Есть и другие способы прилепить репозиторий к проекту. Например, вы можете создать новый проект сразу же из репозитория, который у вас уже хранится где-нибудь на гитхабе. Для этого идем в VCS | Checkout from Version Control | Git (или Github). На стартовом экране PhpStorm тоже есть кнопка, которая вызывает аналогичное диалоговое окно.

Тут достаточно указать путь до репозитория, директорию для нового проекта и его имя. Запустится процесс создания проекта и репозиторий будет автоматом прицеплен к нему.
Еще бывает при входе в проект phpstorm может найти репозиторий, который находится внутри проекта, и может предложить сразу же его ассоциировать с проектом.

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

Инструменты работы с Git.

Чем чаще всего пользуются разработчики? git status/add/rm/commit/checkout/branch/merge/rebase/log/fetch/pull/push и т.д. Для всех этих консольных команд в PhpStorm есть отдельные инструменты, которые делают их работу более наглядной, а значит, и более эффективной.

Основная панель инструментов. Состояние файлов, git status

Примерно 50% времени всей работы с репозиторием в PhpStorm происходит внутри панели инструментов Version Control, которая включается в меню View | Tool Windows | Version Control (или по хоткею Command + 9). Эта панелька содержит 3 вкладки - Local Changes, Log и Console. Последняя показывает просто список всех консольных команд, которые были выполнены самим PhpStorm’ом со всеми параметрами. А вот на первых двух остановимся поподробнее.

Local changes

Если сравнивать gui и cli, то это прям «git status на стероидах». Основой работы этой вкладки являются Change-листы. Это такая небольшая абстракция поверх версионного контроля, которая позволяет прикрепить набор редактируемых файлов к какому-то списку, что помогает изолировать код, относящийся к разным фичам друг от друга. Вообще говоря, сценариев использования change-листов огромное множество. В phpstorm поддержка этих change-листов довольно широка. Например, он может формировать чейнжлисты на основе задач из багтрекера сам, а при переключении веток сохранять состояние чейнжлиста и переходить к другому чейнжлисту. Вы можете сами управлять чейнжлистами, создавать свои, перекидывать файлы из одного листа в другой, коммитить эти листы отдельно друг от друга и т.д. и т.п. Если углубляться в эту тему, можно написать не одну статью в этом блоге 🙂 Поэтому я буду рассматривать работу только с одним-двумя чейнжлистами для упрощения.

По-умолчанию в PhpStorm уже есть один чейнжлист, который нельзя удалить, называется он Default. В этот лист попадают все те файлы, которые вы правите в рамках текущего репозитория. Хотя нет, на самом деле дефолтных листа - два, постараюсь показать на примере.

Если вспоминать теорию по git, то каждый файл может находиться в одном из нескольких состояний: untracked, unstaged, staged или commited. Узнать о том, в каком состоянии какой файл находится в данный момент, можно с помощью команды git status. Она покажет все те файлы, которые не являются commited. Для примера я взял три файла из тестового репозитория и ввел каждый из них в разное состояние, а на скрине ниже показал разницу между выводом cli и gui интерфейсов:

Слева в cli мы видим следующую картину:

  • файл app/basic.html находится в состоянии staged и если выполнить git commit, то он попадет в коммит
  • файл app/index.html находится в состоянии unstaged, на нем нужно сделать git add, чтобы перевести в состояние staged
  • файл inner.html находится в состоянии untracked, и нужно использовать команду git add, чтобы перевести его в состояние staged

Справа в gui мы видим только две категории (а точнее - два чейнжлиста). Если с листом Unversioned Files все относительно понятно - слова untracked и unversioned являются синонимами в контексте git, а значит в этом листе показываются те файлы, которые являются не добавленными в репозиторий. А вот с листом Default не понятно, там отображаются файлы, которые находятся в состоянии staged и unstaged, и никак не разделены между собой.

WAT?

Тут надо понимать, что отображаемые два чейнжлиста - это дефолтные листы. Поэтому следует принимать то поведение, которое было в них заложено. Если подумать, то так ли нам важно, находится файл в состоянии staged или unstaged? Очень часто бывает так, что после выполнения команды «git add .» которая помечает все файлы репозитория меткой staged, приходится еще что-то подправлять. После таких правок очень легко забыть повторно добавить файлы в индекс (вызвав команду git add . снова, или применив её на какой-то конкретный файл). Чаще всего нам важно понимать лишь разницу между теми файлами, которые мы хотим добавлять в репозиторий, и теми, которые не хотим добавлять.

Так вот PhpStorm старается по-умолчанию разделять файлы на те, которые есть в репозитории и те, которых нет в репозитории. А те файлы, которые есть в репозитории он делит только на измененные и не измененные. Если вы изменили какой-то файл, находящийся под контролем версий, он просто показывается в чейнжлисте Default (или в том чейнжлисте, с которым вы этот файл ассоциировали) и он же автоматически будет готов к коммиту. На уровне git все файлы, которые вы меняете с помощью phpstorm, будут находиться в состоянии unstaged. Этого достаточно, чтобы понять, что файл изменен. А уже когда вы фиксируете правки, phpstorm сам добавляет их в индекс (git add).

На мой взгляд, такая система на порядок проще для начинающих. Когда я учился, мне было тяжело поначалу ориентироваться в состояниях файлов. Чем меньше состояний - тем проще для освоения. Так вот в phpstorm этих состояний минимум, а значит и начать с этим работать - проще, имхо.

Основные возможности вкладки Local Changes

Помимо просмотра статуса репозитория и работы с change-листами, панель имеет ряд дополнительных возможностей. Стоит обратить внимание на панельку инструментов с иконками слева от списка измененных файлов.

При наведении на каждую иконку показывается название инструмента, хоткей. Тут есть такие полезные штуки, как сворачивание/разворачивание списка файлов и чейнжлистов (очень полезно, когда измененных файлов очень много). Есть возможность группировки файлов по директориям - в чейнжлистах будет светиться не просто список файлов, но и директории, в которых эти файлы находятся.

Довольно удобной фичей тут является возможность предпросмотра diff для каждого файла сразу же после выбора их в спике. После включения вся панель инструментов делится на две части, слева будет оставаться также список файлов, а справа - diff файла, выбранного слева. И в нем можно даже сразу редактировать. Diff можно открыть в отдельном всплывающем окне, если неудобно смотреть его в маленьком окошке.

Также тут присутствуют кнопки для управления чейнжлистами, которые позволяют добавлять/удалять их, выбирать активный чейнжлист, перемещать файл между чейнжлистами (что можно делать и с помощью Drag’n’Drop).

Отсюда же можно произвести отмену сделанных изменений в файле (операция Revert). Если вы изменили файл, который уже был в репозитории, то PhpStorm отменит все сделанные в нем изменения и приведет его к состоянию в HEAD метке репозитория, выполнив команду git checkout HEAD - file. Если же файла нет в репозитории, то команда вернет файл в список Untracked.

В общем - пробуйте. Возможностей у этой панельки - хоть отбавляй.

Фиксация правок, git commit

Сделать коммит можно тоже множеством способов. Есть хоткеи (Command + K или Ctrl + K), есть кнопочки в интерфейсе и контекстных меню - используйте любой удобный. Самое важное тут понимать - в коммит попадет только то, что вы непосредственно укажете, независимо от того, что сейчас находится в индексе гита. Выбрали только один файл, в коммит попадет только он. Выбрали директорию - попадут все измененные файлы этой директории. Выбрали чейнжлист - попадут файлы из него. Ну вы поняли 🙂

По-дефолту, в коммит попадают только те правки, которые находятся в листе Default. Когда вы запускаете операцию коммита, PhpStorm показывает вам большущее диалоговое окно, в котором можно очень много всего сделать.

Тут можно еще раз проверить, какие именно файлы попадут в коммит. Будет выведено все дерево измененых файлов с группировкой по директориям и деревом вложенности (если выбран этот режим отображения). Также тут можно нужно задать сообщение для коммита и на всякий случай проверить diff.

Помимо таких типовых операций можно попросить PhpStorm сделать такие вещи, как проверка синтаксиса на корректность, или проверить TODO в файлах, предназначенных для коммита. Если будут найдены проблемы, то он любезно сообщит о них и предложит либо исправить, либо закоммитить так как есть.

Просмотр истории репозитория, git log

В любом инструменте для работы с репозиториями через gui обязательно должно быть дерево коммитов. PhpStorm - не исключение. Найти его можно во вкладке Log панели Version Control. На первый взгляд - ничего необычного. Однако чем больше с ним работаешь, тем больше понимаешь, насколько это серьезный инструмент. Да, я согласен, тут может быть есть не все то, что нужно иногда (редко), но тем не менее, на мой взгляд, этот лог гораздо более функционален, чем лог в других gui’яx (слово-то какое!).

В верхней части находятся возможности по фильтрации дерева. Можно показать только те коммиты, которые в тексте описания содержат какую-то строку или регулярку. Можно показать коммиты конкретной ветки/тега. Можно показать коммиты конкретного пользователя, или показать коммиты с фильтром по дате. Что очень интересно - можно показать дерево одного репозитория, или же нескольких репозиториев сразу (на скрине как раз показано несколько деревьев сразу, выбранные в фильтре Paths)!

Само по себе дерево является интерактивным. Можно свернуть историю, если она линейна, нажав на ветвь истории. Каждый коммит в дереве кликабелен и имеет контекстное меню, через которое можно выполнить все базовые операциями над коммитами в истории. Например, если вы хотите отменить сделанный коммит, через контекстное меню надо нажать на Reset Current branch to here …, после чего будет вызван диалог, предлагающий выбрать тип reset’а - hard, soft или mixed с пояснением каждого из вариантов.

А еще можно назначать теги, переходить к коммиту на github, делать cherry-pick, создавать новые ветки из коммита, и даже менять сообщение коммита. В общем много всего.

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

В дополнение ко всему вышесказанному можно добавить приятную мелочь - интеграцию лога с таск-трекером. Для того, чтобы её настроить, нужно пойти в настройки по адресу Version Control > Issue Navigation, где добавить свои настройки для своего таск-трекера. В нашем случае оно выглядит вот так:

После сохранения этих настроек в логе коммитов гита (а на самом деле не только там, а много где) все подходящие под регулярку строки будут преобразованы в ссылки.

Просмотр изменений, git diff

В phpstorm ну очень много функциональности по части интеграции с гитом. Наверно самой удобной и нужной его частью является diff-viewer, который встроен в текстовый редактор phpstorm. Кстати, если у вас на примете уже есть какой-то другой diff-viewer, и вы им давно успешно пользуетесь, phpstorm дает возможность использовать его прямо в IDE (правда эта тема выходит за рамки статьи).

Сам по себе diff-viewer не является частью интеграции git в phpstorm. Это вполне обособленный инструмент, который можно использовать и в других сценариях. Например, можно сравнить содержимое двух файлов между собой (выделяем в дереве оба файла и жмем Ctrl+D или Command + D).

Этот инструмент разработчики JetBrains используют во всех своих IDE, поэтому он вылизан до безупречности, и его стараются использовать везде. Я уже писал выше, что при просмотре списка измененных файлов доступен предпросмотр diff, но полные его возможности раскрываются тогда, когда мы раскрываем полную его версию, либо занимаемся слиянием конфликтующих правок.

Если вам нужно просмотреть историю изменения какого-то файла и сравнить его с предыдущей версией этого же файла, то можно сделать следующее: достаточно вызвать контекстное меню конкретного файла (в дереве файлов или в редакторе) и выбрать опцию Git | Show History. В основной панели инструментов Version Control появится новая вкладка - History, в которой будут отражены все зафиксированные коммиты, в которых присутствовал этот файл. И вот тут как раз можно просмотреть разницу между разными версиями этого же файла с помощью соответствующей кнопки на панели (или шортката Ctrl + D или Command + D)

Нажав на эту кнопку вы увидите те правки, которые были сделаны в рамках этого коммита.

При просмотре diff’а можно настроить отображение окошка так, как душе угодно - можно просматривать в одной колонке, можно в двух; можно выделить изменения, которые были сделаны в рамках одной строки; можно показать файл целиком или показать только изменения + 5 строк сверху и снизу (при этом остальные строки файла будут просто в свернутом состоянии и к ним можно будет получить доступ, просто нажав на «плюсик» разворачивания кодового блока)

Ветки и состояние, git branch и снова git status

Все, что нужно знать о ветках, а также дополнительные сведения о текущем состоянии вашего репозитория (помимо файлов, о которых была речь чуть выше), находится в правом нижнем углу phpstorm. Если вы в данный момент находитесь на какой-то ветке, то будет отображено название ветки. Если вы «оторвались от головы» репозитория и перешли на какой-то коммит, то там будет короткий хеш коммита. Если вы находитесь в каком-то особом состоянии типа merge или rebase, то оно тоже будет там показано

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

Откроется уже знакомый нам diff-viewer, который позволит просмотреть всю разницу между коммитами.

Слияние веток, git merge

Но это лишь возможности просмотра в diff-viewer’е. Настоящий бум начинается в те моменты, когда происходит слияние, или работа с откатом сделанных изменений.

Как известно, слияние может производиться с помощью разных стратегий и в разных ситуациях оно будет работать по разному. В случае слияния с fast-forward phpstorm ничего не предложит (вполне ожидаемо). А вот если назревает какой-то конфликт, то phpstorm любезно покажет вам диалоговое окно со всеми конфликтующими файлами:

Как и в cli, тут есть возможность принять чужие или свои изменения в приоритете. А есть кнопка Merge … открывающая diff-viewer, который поможет разрешить конфликт

На этот раз представлен трехсторонний diff. В левом окне - ваши правки. В правом - конфликтующие ветки. В середине - результат слияния. Красным помечены конфликтующие строки, изменения в которых были внесены с обоих сторон. Серым помечены удаления строк, а зеленым - добавления.

С помощью стрелок между окнами можно перемещать код из разных вариантов кода в результирующий вариант.

Все, что не является красным - phpstorm может обработать автоматически. Достаточно нажать кнопку Apply All Non-Conflicting Changes на верхней панели инструментов. Эта кнопка решает в ситуациях, когда изменений ну очень много, но при этом diff-viewer оставляет просмотр правок на ваше усмотрение.

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

Перебазирование, git rebase

Для того, чтобы начать rebase, нужно пойти в меню VCS | Git | Rebase … Откроется диалоговое окно, которое позволит задать параметры для перебазирования одной ветки на другую. Все довольно очевидно и понятно:

Выбираем репозиторий, ветку для перебазирования, новую базу и жмем Rebase. Если был выбран интерактивный режим, то откроется окошко со списком всех перебазируемых коммитов и всеми опциями изменения истории. В общем все так же, как в cli, только в одном месте

После запуска перебазирования phpstorm начнет по одному перекидывать коммиты. В зависимости от того, какие опции перебазирования были выбраны для веток, будут происходить разные действия. Например, если вы выбрали редактирование файлов в каком-то коммите, то phpstorm остановит процесс rebase’а на этом коммите и предложит вам отредактировать файлы, после чего - продолжить:

Если делаете слияние нескольких коммитов в один, то phpstorm любезно предложит ввести новое сообщение о коммите

По окончании операции будет сообщение об успешно завершенной операции

Если же был выбран не интерактивный rebase, то он будет произведен точно так же, как и в cli.

Работа с удаленными репозиториями, git fetch, pull, push & clone

Сделать fetch можно с помощью меню VCS | Git | Fetch. Возможно где-то в недрах конфигурации есть опция, которая бы автоматически выполняла эту команду, но мне удалось найти эту функцию только в стороннем плагине - GitToolbox,

Сделать pull можно с помощью меню VCS | Git | Pull … Откроется диалоговое окно, которое предложит выбрать репозиторий и ветку/ветки для слияния. Там же есть ряд наиболее часто используемых опций при слиянии

Если вдруг в процессе слияния обнаружатся конфликты, то будет предложено их слить с помощью diff-viewer’а, как и при обычном merge.

Для выполнения push нужно выбрать меню VCS | Git | Push … или воспользоваться хоткеем Command + Shift + K или Ctrl + Shift + K. Это тоже диалоговое окно, в котором нужно выбрать репозитории и ветки, в которые выполнить отправку новых коммитов

Прочее

Конечно же, это не все. Причем далеко не все. Я описал тут только те функции, которые наиболее часто востребованы, и немного коснулся менее используемых вещей. В phpstorm продуманы очень многие мелочи, которые в повседневной жизни упрощают работу с репозиторием многократно. Конечно же тут есть и cherry pick, и revert, и разные стратегии слияния веток, и много чего еще. Статья и без них уже получилась огромной, а если вы разберетесь с материалом этой статьи, то использовать все остальные фишки шторма не составит никакого труда.

Да, конечно, не все операции phpstorm позволит сделать с помощью GUI. Но подавляющее большинство операций - доступно. Да - это медленнее, чем через cli. Да - может быть это не «труъ». Но факт остается фактом - работать с гитом через GUI в шторме удобно и приятно, и что самое главное - продуктивно! Пользуйтесь дарами человечества и изучайте инструменты, с которыми работаете. Всем благ.