Привет, мне показалось хорошей идеей начать переводить не только релизные посты из блога ГитЛаба. Для разминки я взял этот пост почти наугад, так что не судите строго. Буду рад, если поможете определиться с выбором статьи для перевода, выбрав один из вариантов в опроснике




Git – это система контроля версий с огромным количеством возможностей. Пытаться изучить их все довольно утомительно, поэтому большинство пользователей ограничивается использованием лишь базового набора команд. В этой статье представлены несколько советов по работе с Git, о которых вы, возможно, не знали. Эти советы помогут вам оптимизировать ваш процесс разработки.



Алиасы


Одним из лучших способов упрощения работы с Git является использование алиасов для часто используемых команд. Это поможет сохранить время при наборе команд в терминале.


Например, алиасы для команд checkout, commit и branch можно создать следующим образом:


git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch

Теперь вместо git checkout master достаточно ввести git co master.


Также можно изменять и добавлять алиасы напрямую редактируя файл ~/.gitconfig:


[alias]
    co = checkout
    ci = commit
    br = branch

Скрытие (stashing) изменений до коммита


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


При помощи команды git stash можно временно отменить внесенные изменения, не удалив их окончательно:


$ git stash

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


Чтобы вернуть скрытую функциональность, достаточно ввести:


$ git stash pop

Если же скрытая функциональность больше не нужна, ее можно удалить с помощью:


$ git stash drop

Сравнение коммитов из командной строки


Быстрым и легким способом сравнения изменений между коммитами или версиями одного и того же файла является использование команды git diff.


Для сравнения состояний одного и того же файла между коммитами нужно ввести:


$ git diff $start_commit..$end_commit -- path/to/file

Для сравнения изменений между двумя коммитами:


$ git diff $start_commit..$end_commit

Эти команды выведут результат в текстовом виде прямо в окно терминала. Для более наглядного результата можно использовать git difftool. Данная команда запускает специальную программу для сравнения изменений. Одной из таких программ является Meld.


Для настройки Meld введите:


$ git config --global diff.tool git-meld

Теперь ее можно использовать:


$ git difftool $start_commit..$end_commit -- path/to/file
# или
$ git difftool $start_commit..$end_commit

Откат изменений


Иногда при работе над кодом становится понятно, что внесенные изменения оказались ненужными/неверными и их необходимо откатить. Вместо того, чтобы делать undo по каждому изменению, достаточно сделать reset файлов на HEAD-коммит ветки:


$ git reset --hard HEAD

Или, для одного конкретного файла:


$ git checkout HEAD -- path/to/file

Далее, если ненужные изменения уже были закоммичены, для их отката нужно ввести:


$ git reset --soft HEAD~1

Более эффективное использование Git blame


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


$ git blame -w  # игнорировать знаки табуляции
$ git blame -M  # игнорировать перемещения текста
$ git blame -C  # игнорировать перемещения текста в другие файлы



Помимо описанных выше советов по работе с командами, существует несколько общих советов по работе с Git.


Делайте пулл часто


Если вы используете GitLab Workflow, значит вы работаете в ветках для выделенной функциональности (feature branches). Пока вы работаете над фичей в отдельной ветке, в мастер-ветке может произойти множество изменений, некоторые из которых могут конфликтовать с добавленными фичами.


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


Частые коммиты, редкие пуши


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


Пуш только после тестирования изменений


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

Что еще перевести?
24%
(41)
GitLab CI: Run jobs sequentially, in parallel or build a custom pipeline — https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/
16%
(28)
Comparing Confusing Terms in GitHub, Bitbucket, and GitLab — https://about.gitlab.com/2016/01/27/comparing-terms-gitlab-github-bitbucket/
5%
(9)
Building an Open Source Company: Interview with GitLab's CEO — https://about.gitlab.com/2016/07/14/building-an-open-source-company-interview-with-gitlabs-ceo/
5%
(8)
GitLab Container Registry — https://about.gitlab.com/2016/05/23/gitlab-container-registry/
47%
(82)
GitLab Flow — https://about.gitlab.com/2014/09/29/gitlab-flow/
3%
(5)
Свой вариант в комментариях

Проголосовало 173 человека. Воздержалось 150 человек.

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

Поделиться с друзьями
-->

Комментарии (25)


  1. Delphinum
    10.08.2016 16:23
    +1

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

    А разве после пуша пачки коммитов, они каким то магическим образом будут сгруппированы?


    1. Mobyman
      10.08.2016 16:25
      +8

      Наверное, имеется в виду локальный rebase со squash коммитов в один.


      1. Delphinum
        10.08.2016 16:26

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


    1. withoutuniverse
      11.08.2016 13:39

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

      git merge --squash 1234567
      
      С этой командой все изменения можно будет как один коммит добавить.


  1. maxru
    10.08.2016 17:09

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

    Мне кажется лучшим решением было бы дополнительно к статье создать cheat sheet (на cheatography по git уже есть, но того, что описано в статье, там нет).


    1. saboteur_kiev
      10.08.2016 18:26
      +5

      Практически все 8 советов можно прочитать чуть ли не на первой страничке официальной документации по GIT.
      https://git-scm.com/doc

      Например Git cheat sheet: https://services.github.com/kit/downloads/github-git-cheat-sheet.pdf


  1. inoyakaigor
    10.08.2016 17:28

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

    Рекомендую использовать для этих целей worktree. Это куда удобнее бесконечных stash > checkout > checkout > stash pop. Единственное что GUI клиенты ещё не научились с этим корректно работать. SmartGit и gitg по крайней мере.


    1. develop7
      10.08.2016 18:49

      IDEA относительно недавно умеет worktree, и очень давно — «smart checkout» (stash > checkout > stash pop)


  1. NickKolok
    10.08.2016 20:58

    Чего действительно мне не хватает в stash — это возможности применять его к конкретным файлам, а в идеале — к частям файла, наподобие git add $filename -p.
    Сейчас приходится извращаться через коммит и его резет. Никто случайно не знает нормального пути?


    1. Falstaff
      10.08.2016 21:48
      +1

      Вроде git stash --patch будет эквивалентно add <file> -p, нет?


    1. crazylh
      10.08.2016 21:48

      Через консоль наверно такого нет, а вот SourceTree умеет частитчно патчить файлы из stash


    1. everyonesdesign
      10.08.2016 21:50
      +1

      Можно пользоваться git stash -p, правда, без указания имени файла, придется отбирать изменения через все файлы.


      1. NickKolok
        11.08.2016 17:40

        Помогло, спасибо! И не думал, что такая штука есть, если пофайлового сташа нет.


    1. Darkside73
      11.08.2016 09:44
      +1

      Еще можно добавить в индекс то, что не должно в stash попасть:


      git add files/to/not/stash
      git stash --keep-index


  1. domix32
    11.08.2016 00:49
    +2

    Писать алиасы для однословных комманд так себе план — автодополнение же есть. А вот для чего-нибудь вроде submodule update --init --checkout или rebase master --autostash уже намного более реалистично


    1. dshster
      11.08.2016 13:46

      Для checkout так себе автодополнение — там есть команда check, которая подставляется первой, поэтому co гораздо удобнее.


  1. darthandrew
    11.08.2016 12:42
    -2

    А еще более эффективная работа (если вы под виндой) — использование TortoiseGit, чтобы не страдать с командной строкой.


    1. aezhko
      11.08.2016 13:12
      +1

      Не соглашусь с вами:

      • GUI реализует не все возможности командной строки.
      • Работа с командной строкой — не страдание, если ты знаешь, что делаешь. Кроме того, есть штуки типо Oh-My-Zsh, которые делают процесс работы в командной строке еще более удобным.
      • Если говорить о разработке, GUI-интерфейсы интегрированы во все современные IDE.


      1. darthandrew
        11.08.2016 14:03

        Да, возможности может не все, но «минимально-рабочий набор» вам обеспечен. На личном опыте — мои коллеги крайне редко сидят в git в командной строке. Допустим подключается человек — технический писатель, с git ему работать надо, да его можно учить «знать что ты делаешь», но смысла нет. Конечно это дело вкуса, лично одного человека точно знаю кто любит именно командную строку, но вопрос не такой однозначный. Что используем мы: обновись, коммит, пуш, создай ветку. Мерж делают уже далеко не все — это забота тим-лида сложить все воедино. Git ведь дает много чего, когда первое время мы его внедряли — реально пугало сложностью, теперь уже все проще, но уверен что многие возможности ни я ни коллеги просто не знаем и не применяем, но и работать без них тоже можно.


      1. michael_vostrikov
        11.08.2016 19:46
        +1

        Тоже пользуюсь тортиллой. В консоли удобно делать повторяющиеся действия из нескольких команд, типа checkout/pull/checkout/rebase, можно названия веток вынести в переменные, и копи-пастить весь набор команд в консоль. Или разные хитрые вещи для управления репозиторием, которых нет в GUI.
        А вещи, которые требуют внимания, выбора, и работы с текстом, удобнее делать в GUI — diff файлов перед коммитом, разбиение/слияние коммитов, интерактивный rebase, разрешение конфликтов. Дело личных предпочтений, конечно, но при правильном применении GUI помогает сэкономить время.


      1. sumanai
        11.08.2016 20:15

        Не знаю как в Git, но интерфейс в TortoiseHg достаточно удобен, не представляю, как выборочно коммитить части файлов из командной строки, работать с очередями заплаток и тому подобное.


    1. dshster
      11.08.2016 15:24

      TortoiseGit? Пробираться через дебри вложенных меню так себе удовольствие. Тогда уж SmartGit, хотя всё это вкусовщина.


    1. Alexko
      11.08.2016 17:46

      А как же SourceTree? Хотя, на вкус и цвет…


  1. var_bin
    12.08.2016 13:28

    Добрый день! Спасибо за статью!


    Пробовал создавать алиасы через git config --global alias.co checkout, но они почему-то не сохраняются. И после каждого перезапуска терминала их нужно создавать заново. Поэтому использую для хранения алиасов файл ~/.bashrc. Но вариант с ~/.gitconfig тоже хорошо подходит, просто он у меня не прижился.


  1. rhrn
    15.08.2016 22:55

    git pull --rebase (удобный способ подтянуть обновление, что не нужно было делать дополнительные коммиты)
    git diff --staged (показать что пойдёт в коммит)
    git status (показать состояния файлов: новые, изменённые, добавленные для коммита)