ПШЕ AndroidStudio или как использовать VCS Tools по полной

  • Tutorial

ПШЕ AndroidStudio или как использовать VCS Tools по полной


- Все хорошо, только перед влитием обязательно засквошь коммиты.
- Заскво...Что?

Примерно такая реакция была у меня после получения апрува первого пул реквеста на первой неделе работы в одной крупной компании. Причина такой реакции весьма простая — далеко не каждый заказчик/работодатель может себе позволить такую роскошь как большая команда на одну платформу, в особенности это касается мобильной разработки. Из-за ненадобности и возможности быстрой коммуникации в своем мирке, далеко не все вещи, которые используют крупные мастера своего дела, обретают актуальность в небольших командах. Говоря проще — а на кой мне это надо, если мы и так хорошо без этого жили и хорошо справлялись?


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


Я постараюсь не обращать внимания на банальные вещи: init VCS; new/rename/push branch; rebase/merge onto branch; setup remotes e.t.c. Я постараюсь обратить внимание на те элементы, которые по боязни своего незнания, я долгое время избегал(и жалею).


Amend commit


В случае, когда Вы решили дополнить свои изменения к последнему коммиту, стоит воспользоваться следующей коммандой:


// Дополнит последний коммит изменениями без изменения сообщения
git commit --ammend
// Дополнит и изменит сообщение последнего коммита
git commit --ammend "New commit message"

А можно ускорить процесс:


image


Edit commit message


Допустим, Вы создали большой PR с большим количеством коммитов, да перед пушем заметили, что одно из сообщений некорректно и было бы неплохо его отредактировать, пока жесткий ревьювер не четвертовал Вас за такую оплошность:


image


Interactive rebase


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


Пачка была быстро собрана, коммиты получились хаотичные, да еще и на ревью получил порцию исправлений… Окей, не проблема.


Проверяем отставание наших изменений от ветки, в которую мы хотим вливаться.


//Покажет хеши и коммит мессаджи
git cherry master -v 
// Подсчитает нам количество отставших коммитов
git cherry master | wc -l 

Либо через GUIню:


image


Дальше скачем в tools:


image


Указываем количество коммитов, которые хотим отредактировать:


git-rebase-2

Или сразу укажем таргeт ветку:


image


Дальше определяемся что нам нужно сделать:


image


И редактируем:


image


Подробнее про команды:


# Commands:
#  p, pick = использовать коммит(оставить при своем)
#  r, reword = использовать коммит, но отредактировать его сообщение
#  e, edit = редактирование коммита, без возможности amend-а(без слияния)
#  s, squash = слить с предыдущим коммитом с возможностью редактирования итогового сообщения
#  f, fixup = аналог сквоша,без возможности редактирования сообщения(отбросит сообщение коммита который сливаем)

Коммиты отредактированы, осталось только подлить все на ремут сервер. Но ведь история изменена? И хэши явно не совпадают с тем, что находится на удаленной ветке.


image


Force push перезатрет нашу историю и примет новые изменения как родные.


Multiple remotes


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


image


Что это? В случае работы в 2 и более ремут хранилищах(актуально, когда доступ в основное хранилище по прямому запросу закрыт), быстрое переключение между удаленным ветками для пушей/пулов тоже упрощен:


image


Git blame


Полезный трюк для просмотра автора внесенных изменений:


image


Теперь про более эффективную работу. Если Вы не поленились и внесли правила ведения коммитов в Вашем проекте, стоит включть IssueNavigationLink:


//Пример паттерна формирования коммит мессаджа
<PROJECT_ID>-<TASK-ID>: <COMMIT MESSAGE>

(Кроме всего этого, Вы можете настроить проверку формирования коммит мессаджа с помощью git-hooks — https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)
Отредактируем файл project/.idea/vcs.xml:


image


Подбросим свою регулярку для анализа коммит месаджа:


<IssueNavigationLink>
    <!--Регулярное выражение в зависимости от Вашего паттерна-->
    <option name="issueRegexp" value="([A-Za-z]+\-)(\d+)" />
    <!--Адрес для подстановки Вашей задачи-->
    <option name="linkRegexp" value="https://github.com/IlyaPavlovskii/Android-Environments/issues/$2" />
</IssueNavigationLink>

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


image


Git cherry-pick


Не путать с командой cherry!


Допустим, Вы работаете над фичей/фиксом, во время работы заметили блокирующий Вас баг и поправили его, да всю свою работу не закончили и в рабочую ветку не влились. Ваши компаньоны отрепортили, что проблема блокирует не только Вас, но и кого-то другого, и было бы неплохо поделиться им. Но Вы все еще работаете над своей задачей, а отвлекаться нет желания… В таком случае, будет проще всего забрать Ваш 1 коммит в другую ветку и экстренно вмержить его в рабочую (фризную ветку). Как это сделать?


image


image


Готово:


image


Заключение


В заключении хотелось бы сразу вспомнить вечный холивар на тему: терминал или GUI редактор для работы с VCS? Тут дело вкусовщины. Понятно дело, что CLI GIT-а более мощный инструмент и для спецефичных задач без него никуда. Но для ежедневных задач встроенный пакет утилит для работы с системами контроля версий в AS — просто must have и сократит время разработки в разы.
Надеюсь, что Вы нашли что-то новое в этой статье и помог облегчить Ваши трудовые будни.

Комментарии 30

    +9

    Описывать флоу по скриншотам одной IDE — плохая идея (тем более, что в статье даже не упоминается, что это за IDE). Такая статья должна называться "Работа с git в webstorm" или вроде того.

      +3

      Пардон, название IDE со второй попытки отыскал, но статью все равно лучше переименовать :)

        0
        Да, Вы правы, спасибо. Исправил, совсем забыл про смежные продукты.
      –7
      Вы создали большой PR с большим количеством коммитов, да перед пушем заметили, что одно из сообщений некорректно и было бы неплохо его отредактировать, пока жесткий ревьювер не четвертовал Вас за такую оплошность

      Э… Если код ревьювер докопается до моего коммита с комментарием "#ля, очепятка", я приложу все усилия, чтобы его гнали ссаными тряпками.
        +5

        Из чего я делаю вывод, что вы никогда не работали в крупных проектах и тем паче в opensource-проектах. Попросить поправить history в PR — элементарно. У ansible, например, есть даже спецпроверка, чтобы не присылали PR из 100500 коммитов "typo" или "pleasing ci".

          +1

          Commit, push, сборка упала, commit "typo fix" ещё раз — разве так не бывает?

          • НЛО прилетело и опубликовало эту надпись здесь
              0

              Конечно, бывает. В вашем личном бранче/репе — да. А когда вы приходите в большой проект с тысячами коммитеров и десятками тысяч коммитов в месяц, никому ваши typo не нужны. Присылаете код на PR, вам указывают на недостатки, устраняете, воююете с CI, ублажаете linter'ов, выполняете капризы reviewer'ов. После этого идёте и делаете умный rebase в один-два-три коммита, каждый из которых содержит 5-10 строк описания. Пушаете с форсом (можете старую историю сохранить для истории где-то в другом бранче), после этого оно мержится в основной апстрим.

              –1
              Из чего я делаю вывод, что вы никогда не работали в крупных проектах

              Неправильный вывод :)
              и тем паче в opensource-проектах

              Это да, то есть не имел дело настолько серьёзно.

              Правка истории коммитов, IMHO, порочная практика. Она маскирует реальную картину происходящего. Коммент коммита поправить — да, но и только.
                0

                Из этого я делаю вывод о том, какой проект вы считаете "крупным". Ваши локальные корпоративные 300к строк js фронт/бэкэнда — это не крупный проект.


                Условный — postgres, ansible, react — это крупные проекты.

                  0
                  $ find . -name '*.[cpp|h]' | wc -l 
                  14330
                  $ find . -name '*.[cpp|h]' | xargs cat | wc -l                                                        
                  5282953
                  


                  Это прошлый. Нынешний поскромней, примерно вот такой:

                  $ find . -name '*.[c|h]' | wc -l                                                                       
                  12290
                  $ find . -name '*.[c|h]' | xargs cat | wc -l 
                  1374514
                  
                    0

                    И в этом замечательном проекте у вас коммиты вида 'typo'? Ух. А сколько у вас коллег в git'е? И сколько PR'ов за последний месяц было смержено?

                      0
                      В обоих проектах структура тянется давно. В первом с 1994, во втором с 1979 :) Конечно, не всегда был гит. Но были (и есть) подпроекты, у каждого своя команда. В данный момент в моём подпроекте 8 человек. Всего в проекте около 200. Тестировние, вливание «под» в общее целое — отдельный вопрос. Но никогда «вопрос typo» не стоял. Вплоть до того, что исправление одной циферки в копирайте делается отдельным коммитом уже после code review в PR (но до принятия, само собой). Без правки истории.
                        0

                        Циферка в копирайте вполне тянет на отдельный коммит. А вот исправление pritnf на printf в свежем PR — нет.


                        История неизменна в master и прочих shared branches. А вот в личной песочнице (т.е. до мержа PR) нужно и можно ребейзить, сквошить и приводить историю в такой вид, с которым можно работать.

                          0
                          print не прорвётся через unit-тест, мимо.
                          нужно и можно

                          Можно. Но живы же как-то до сих пор :) И нормально живём.
                  0
                  IMHO, порочная практика. Она маскирует реальную картину происходящего

                  Можете пояснить мысль?

                  У нас был спор, про обратную сторону. Поясню на грубом примере — Мы долгое время спорили, можно ли рабочий код и его тестирование разделять отдельными коммитами? Лучше так не делать. Когда вы решаете откатить фичу, то прыгая по хистори коммитов, очень легко погрязнуть в фантазии автора и забыть вырезать некоторые части. Те ваша функциональность и ее тестирование должны быть поданы одной неделимой частью.
                  А в тему реальной картине происходящего — тут скорее про правильную декомпозицию задач стоит вести речь.
                    0
                    можно ли рабочий код и его тестирование разделять отдельными коммитами?

                    Вот тут я совсем потерял мысль :) Есть юнит-тесты, в моём случае это CUnit на каждый чих (хоть и ненавижу эту бюрократию, но надо, и оно оправдывается — иногда такие банальные ляпы бывают). Вот буквально сегодня столкнулся с тем, что попросили поправить аж на уровне pull request. А коммиты… дело интимное. Ну, не на уровне Ctrl+S, но близко.
              +2
              Счастливчик… GIT… Раньше я не любил его. А потом поработал с перфорсом…
                0
                «сократит время разработки в разы» — пишу код 8 часов, commit/push 1 мин
                  0
                  В корне с Вами несогласен. Писать код/документацию/структурировать процесс и результат — это все есть результат вашей работы. Писать код — это одна часть повседневных будней.
                    0
                    Регулярно доводится работать с кодом таких писателей.
                    Как правило его просто выкидывают. Потому что без документации с говнокодом не может разобраться даже сам автор через пол года и не остается ничего кроме как выбросить код и написать заново.
                    Впрочем подавляющее большинство компаний вообще не выделяет время на написание документации и даже если ты нормальный программист — либо документируй за счет собственного времени, либо никак.
                      0
                      Компромисс — работай 8 часов, пиши код 4.
                    0
                    Отредактируем файл project/.idea/vcs.xml:

                    Зачем лезть в файлы, когда для этого есть настройка?


                      0
                      Да, Вы абсолютно правы.
                      Я лишь хотел обратить внимание на то, где хранятся такие настройки и что файл с настройками легко может попасть под юрисдикцию .gitignore
                      0

                      Rebase вы тоже как-то странно вызываете, когда есть меню:


                        +2

                        По работе с VCS в IDEA-образных могу отметить лишь удобное side-by-side разрешение конфликтов и diff при коммите, из которого можно достаточно удобно отделять нужные изменения от тех, которые либо должны уйти в другой коммит, либо и вовсе написаны для отладки.


                        В остальном интерфейс локализован довольно плохо относительно того, что git делает под капотом, местами неочевиден и ИМХО вообще вреден тем, кто не очень знаком с git.

                          0
                          — Заскво… Что?
                          после апрува пул реквеста
                          Тонкий юмор
                            0
                            Спасибо за статью, кое-что почерпнул для себя. Можно про git-hooks более подробно рассказать? ИМХО менее очевидная штука, чем IssueNavigationLink. Именно как настроить формирование commit-message по шаблону? И может ли сформированное сообщение появляться в окошке commit changes перед комитом?
                              0
                              Это больше на другую статью тянет. Проблема в том, что знакомые мне GUIни, не поддерживают форму работы с git hook-ами(хотя я и сам слабо представляю как это можно «продать» красиво). Подробно описано здесь.

                              Именно как настроить формирование commit-message по шаблону?

                              Подключите pre-commit hook, проанализируйте входящее сообщение и доработайте его. Пример можно найти здесь.

                              И может ли сформированное сообщение появляться в окошке commit changes перед комитом?

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

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

                            Самое читаемое