Pull to refresh

О Git, начинающих и статьях о Git для начинающих

Reading time4 min
Views15K
Пятница тринадцатое отличный день для очередного holywar обсуждения «как я готовлю Git, и почему я готовлю его неправильно».
Итак, у каждого программиста будь то под Linux, будь то под Windows всегда найдётся кто-то, кто вращается соответственно в кругах программистов под Windows или Linux. Так и у меня есть программисты из мира Microsoft и Windows. Похвально, что такие люди начинают двигаться в сторону OpenSource и Git. Но сейчас не об этом.

При рассказе я иногда буду опираться на известную книгу Pro Git, написанную Скотом Чаконом (Scott Chacon).

Случай 1: чем плох git commit -m?



В одной из бесед в интернете была упомянута статья для начиниющих в Git, а именно вот эта. Также кто-то высказал мысль, что статьи «как я готовлю Git» содержат в себе нюансы, от которых трудно впоследствие избавиться, как от вредной привычки. Я всё же не поленился и прочитал статью. И смею согласиться с приведенным мнением.

По-порядку, что предлагается в статье помимо множества полезных советов? В частности такие моменты:
  1. git commit -m "Commit message"
  2. git reset --hard как средство прерывания неудачного git merge
  3. какое-то сложное представление git rebase bar, но об этом мы не будем рассуждать


Почему я считаю эти советы не очень хорошими, которые могут превратиться во вредные привычки со временем?

Во-первых, git commit -m "Commit message" бесспорно полезен для wip (work in progress) изменений (концепция хорошо прослеживается при использовании git stash), но вреден для реальных изменений в публичные бранчи, так как часто пытаются описать всё в одну строку. Как правило только по первой строке сообщения, которая часто ограничена 50-60 символами (а во многих случаях пользователю видна только первая строка, как-то git log --oneline), можно понять суть изменения. Если необходимо более развёрнутое описание, добавьте его пропустив одну строку после однострочного.

Вот примерный шаблон, как оформляются изменения:
Summary: короткое, обычно до 66 символов, пояснение, что делает это изменение
<пустая строка>
Description: подробное,
возможно многострочное
объяснение что именно делает изменение, с логами об ошибке и пр.
<пустая строка>
Tags: опциональные теги, типа
Signed-off-by: First Last <cool@email.com>
Reviewed-by: First Last <cool@email.com>


И вот соответствующая выдержка из книги
In general, it's very important to write a good commit message. For open source projects, it's generally a rule to write your message more or less in this format:

Short (50 chars or less) summary of changes

More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body. The blank
line separating the summary from the body is critical (unless you omit
the body entirely); some git tools can get confused if you run the
two together.

Further paragraphs come after blank lines.

— Bullet points are okay, too

— Typically a hyphen or asterisk is used for the bullet,
preceded by a single space, with blank lines in
between, but conventions vary here


В качестве примера откройте любой проект на GitHub, комментарии в котором сделаны в стиле git commit -m, в одну строку. Эту строку разрывает и уносит в тело сообщения, где подразумевается как раз детальное описание. То же самое касается и других утилит отображения репозиториев в web.

Во-вторых, многие команды командной строки Git имеют опцию --abort. Применять в таком случае git reset --hard, хотя результат и правильный, — равносильно стрельбе по воробьям.
git reset --hard чистит базы unstaged и staged, идёт по всему репозиторию и восстанавливает файлы из индекса, если были изменённые, затем сбрасывает указатель на указанный ID.
git merge --abort поступает проще, так как ему известно что менялось, где менялось и куда надо возвратится.

Обратимся к книге
The git merge --abort option tries to revert back to your state before you ran the merge. The only cases where it may not be able to do this perfectly would be if you had unstashed, uncommitted changes in your working directory when you ran it, otherwise it should work fine.

If for some reason you find yourself in a horrible state and just want to start over, you can also run git reset --hard HEAD or wherever you want to get back to. Remember again that this will blow away your working directory, so make sure you don’t want any changes there.


Случай 2: как сделать rebase на устаревший feature-branch?



На что ещё я обратил внимание, уже в беседе, которую я упомянул в начале статьи. Это процесс, которым люди пользуются, а именно вот такая последовательность действий:
# rebase myFeature относительно origin/master
# (оговаривается, что локальный master уже мог устареть)

git checkout master
git pull # предлагается также git rebase с нужными аргументами
git rebase origin/master myFeature

# решаем конфликты один за другим

git checkout master

git merge --no-ff myFeature
# утверждается, что конфликтов не будет


Теперь сравним с:
git remote update
git rebase --onto origin/master <our old origin>
# решаем конфликтыи и тестируем
git push myFeature:master
# повторяем, если master успел поменятся

Или:
git remote update origin
git merge origin/master
# решаем конфликтыи и тестируем
git push myFeature:master
# повторяем, если master успел поменятся


В первом случае необходимо иметь локальную копию master в рабочем дереве, переключение — checkout — дорогая операция, так как надо работать с файловой системой, представили уже репозиторий на пару десятков тысяч файлов, в котором, скажем, по шаблону что-то недавно изменили?

Второй способ позволяет обновить индекс, причём можно сразу для всех remote, затем в одну операцию обновить feature-branch, и третьей залить в master или ещё куда. В первом способе этого не было, кроме фактического обновления master.

Случай 3: в каких случаях целесообразен --squash?



Далее, некоторые команды разработчиков используют merge --squash дабы, как утверждается, не засорять общую историю личными изменениями. Но простите, если это идёт на публику (Open Source!), то все изменения общие, никаких личных ковыряний в носу. squash как и fixup полезен только при подготовке серии изменений для посылки.

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

Бонус



И в качестве бонуса такая команда (обратите внимание на опцию --list):
git branch -a --list myremote*

Полезность оцените сами, в частности, если положить в одно дерево сразу Linux kernel и несколько подсистем, как-то: linux-pm, linux-tty, …

Да, и Google закроет Google Code.
Tags:
Hubs:
Total votes 49: ↑21 and ↓28-7
Comments17

Articles