Как стать автором
Обновить

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

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

Насчет rebase — почти всегда имеет смысл разделять rebase как «ребейз на свежий мастер» для обновления своей ветки и interactive rebase для причесывания истории своей ветки. В каждодневном флоу не вижу смысла «совмещать» их вместе, в реальной жизни это *разные* команды, использующиеся в *разное* время для разных целей, хоть и называются «rebase».

git pull-request


Сходил, я уж думал, неужели наконец GH придумал что-то стоящее. Но нет, «за кулисами» там простой curl, использующий API токен :( Для сравнения, как это сделано в Gitlab — обычными push options, которые гит поддерживает из коробки. git push ... -o merge_request.create -o merge_request.title="My Wonderful MR"

Ну а в целом алиасы — это примерно то, что в первую рабочую неделю новому разработчику показывается в рамках вводного тренинга по гиту: если чел уже все знает и у него свои алиасы устоявшиеся, то все ок, введем в курс тех, которые у нас в некотором смысле «общие», но никого не заставляем. Но обычно люди не знают гит на том уровне, на котором мы ведем разработку, поэтому предлагается взять наши командные алиасы как «основу» (естественно, с объяснениями, что магии там нет и что за ними стоит), а дальше отпускаем в вольное плавание.
НЛО прилетело и опубликовало эту надпись здесь
мега процессы
это процессы, в которых участвует не один разработчик.
НЛО прилетело и опубликовало эту надпись здесь
«не один» — это, конечно, фигура речи. Речь идёт о достаточно большом коллективе человек хотя бы десять-двадцать), где несколько групп разрабатывают несколько совместно поставляемых приложений. В таких случаях только простейшими операциями уже не обойтись.

Вместо того, чтобы границу в 1 человека переносить на коллектив из 10–20 людей (а в следующем комментарии — на компанию в 200+ человек), лучше бы рассказали welovelain про варианты использования, выходящие за пределы pull/add/commit/push/merge:


  • git stash для временного сохранения изменений
  • git rebase -i для причёсывания коммитов во время разработки
  • git reset во всех своих ипостасях (откат, разбиение коммитов, и т. д.)
  • git reflog для отката своего репозитория, если случайно ветку
  • git cherry-pick для бекпортирования отдельных изменений в долгоживущие ветки
  • git range-diff для ревью изменений между версиями ветки
  • git bisect для поиска коммита, вносящего баг
  • git revert для отката изменений, вносящих баги
  • git log -S для поиска коммита по диффу
  • git rerere для особо долбанутых мерджей с конфликтами
А мы в нашей команде используем git merge примерно никогда. Замените ваш merge на наш rebase — вот и получите флоу, которое описывал автор поста.

Разработка чего угодно больше одного коммита в своей ветке -> и вот и git rebase --interactive. За день используется несколько раз, когда активный кодинг идет.
Второй разработчик влил в мастер — вот и git rebase. Повторить каждое утро над своей фиче-веткой, над которой работаешь сейчас.
git graph как алиас — ну это просто по частоте используется даже чаще, чем git status.

А больше никакого рокет сайнса то вроде в статье и не описано? --force-with-lease иногда, когда знаешь, что не один над веткой работаешь и не уверен, не запушил ли товарищ что-то, пока ты думал. add -p — ну примерно раз в месяц использую, когда хочу изменения в одном файле разбить на два коммита.
Каждый раз при интерактивном ребейзе я не могу вспомнить, сверху самый первый коммит в списке или снизу. С этим что-нибудь можно сделать? Я вообще такой один?
Не один, у меня та же история каждый раз.

Смотрите на список не как на "список коммитов", а как на "список команд". Тогда будет понятно, что они расположены в "естественном" порядке, сверху вниз:


  • применить патч x
  • применить патч y
  • применить патч z

Меняем строчки местами — меняется порядок команд. Добавляем свои команды (например, exec), и они выполнятся в общем порядке.


И вообще, если не спешить и поглядывать в комментарии (по крайней мере, в консольном клиенте они есть), то можно заметить контекстную справку, в которой всё это написано:


pick ...
pick ...

# These lines can be re-ordered; they are executed from top to bottom.

Каждый раз перед глазами при ребэйзе.

"… git commit -a и git push --force ..." — вы, кажется, перепутали.
Имелся в виду git commit --amend.


git commit -a (он же --all) означает "сделать перед коммитом git add --update, то есть, внести все изменения отслеживаемых файлов в индекс.

Вы так пугаете людей, что если два человека вносили изменения в мастер из разных веток, то без ребейза вам придётся делать мердж-коммит.
А, хочу спросить, — если у вас только одна ветка, — вам что, не придётся делать мержд-коммит?!


Или вы предлагаете просто каждый раз переназначать голову мастера на голову вашей ветки?


Плюсы такого подхода: исключительно линейная история.
Минусы:


  • заставляете всех разработчиков всегда ребейзиться на голову мастера
  • если не было явных конфликтов при ребейзе, то теряется история разработки: кажется, что человек внёс правки относительно самого свежего на тот момент состояния мастера
  • откатывать ветку становится весёлой затеей (вместо отката одного мердж-коммита)
  • в мастере будут не только совершенные коммиты, но и всякий хлам — очепятки, забытые файлы и тому подобное; нельзя просто так взять и встать на произвольный коммит, чтоб не получить дурацкие проблемы
  • из-за этого ломается бисекция какого-нибудь бага: нет такого, что "до некоего коммита всё хорошо, потом всё плохо"; наверняка там будет "хорошо… не компилируется… не работает… не компилируется… хорошо… плохо… хорошо… не компилируется… плохо".
  • внесение изменений из мастера в продуктовую ветку — вместо черри-пика одного мердж-коммита потребует черри-пик пачки коммитов от и до (и смотрите, не ошибитесь, где рабочая ветка началась и где закончилась).

В общем: умные люди зачем-то сделали функцию мердж-коммита, а вы оказались умнее и отказались от неё.


Вот делать pull с мерджем (если вы работаете в одной ветке в нескольких локальных репозиториях, например), — это да, сделает вам адок в истории. Тут ребейз пригодится.


Или если мердж с конфликтами. Лучше потратить время и сделать ребейз (то есть, по-новой внести исправления), чем воевать между старыми исправлениями и новыми условиями.

Или вы предлагаете просто каждый раз переназначать голову мастера на голову вашей ветки?

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


Кроме того, сохраняется плюшка, что все изменения идут одним куском. Из других преимуществ подхода: rebase почти никогда не нужен. Конфликты с master? Мерджишь master к себе, решаешь их — один раз — и всё.


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


заставляете всех разработчиков всегда ребейзиться на голову мастера

CI-сервис сделает это автоматически. Только в случае конфликтов надо теребить человека, чтобы он их порешал.


если не было явных конфликтов при ребейзе, то теряется история разработки

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


откатывать ветку становится весёлой затеей (вместо отката одного мердж-коммита)

внесение изменений из мастера в продуктовую ветку — вместо черри-пика одного мердж-коммита

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


в мастере будут не только совершенные коммиты, но и всякий хлам

из-за этого ломается бисекция какого-нибудь бага

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


И опять же, в случае сквоша — неревантно, там будет один ровно коммит, сколько бы хлама в ветке не было.


В общем: умные люди зачем-то сделали функцию мердж-коммита, а вы оказались умнее и отказались от неё.

У умных людей из Linux немного другой процесс: с тысячами разработчиков, иерархией репозиториев и ответственности. Не у всех так же, не всем нужен этот оверхед, и не все привыкли делать так. А когда привыкаешь — переучиваться сложно. Особенно если тебе надо будет переучить ещё и свою команду, а вы все работаете за деньги на кого-то другого, и совсем не очевидно, зачем тратить деньги сейчас на «идеологически правильный» процесс, если и так всё работает.

И опять же, в случае сквоша — неревантно, там будет один ровно коммит, сколько бы хлама в ветке не было.

И в котором невозможно понять, что происходило и как. Команде же (возможно, тем же людям) придётся уже через пару месяцев разбираться, что же они меняли и почему.


Я не представляю себе, кому и как может сойти такой стиль, кроме как "мы свои $0.05 вложили, а там хоть трава не расти, мы уже все перейдём в соседний проект на +500".


Не у всех так же, не всем нужен этот оверхед, и не все привыкли делать так. А когда привыкаешь — переучиваться сложно.

"Этʼ точно" ([Сухов]). :(

И в котором невозможно понять, что происходило и как.

Сквошить коммиты — это не означает, что надо делать один коммит в неделю с содержанием Моя работа с 1 по 5 марта. При сквош-мердже в итоговый комментарий можно добавить весь нужный контекст, с той красотой, которая нужна. История разработки этого коммита остаётся в «пулл-реквесте» или что там используется для ревью, если нужно уж прям закапываться. Если нужно ещё глубже — код обычно связан с каким-то тикетом в тикетнице, где можно найти ещё больше контекста.


Примеры:
https://github.com/cossacklabs/acra/commit/c9c8825abe247b8f674917bc493dc7f072fe2549
https://github.com/cossacklabs/acra/pull/419


Конечно, если комментарии оставлять как попало, то там будет как попало:
https://github.com/cossacklabs/acra/commit/d35c6dc421cf8ef016d01afb07c480a2b5393e41


Я не представляю себе, кому и как может сойти такой стиль, кроме как "мы свои $0.05 вложили, а там хоть трава не расти, мы уже все перейдём в соседний проект на +500".

Вот об этом и говорю, упоминая политическую волю. Если у человека проект, с которого он может легко прыгнуть на +500, то в отсутствие внутренней мотивации «делать красиво», от толковых комментариев лично этому разработчику ни тепло ни холодно. И тут всё зависит от сопроводжающего проект, будет ли он настаивать на качественной истории, если для этого надо потратить N времени на её причёсывание и всё это «впустую». Потому что история коммитов — она как парашют: когда не нужна, то мешается и не помогает; но вот когда нужна, а её нет, то становится очень плохо.

Примеры:
https://github.com/cossacklabs/acra/commit/c9c8825abe247b8f674917bc493dc7f072fe2549

Ну вот это вы относительно хороший пример привели; и то, объём достаточно заметен, и при анализе "а что же это было?" сразу может возникать вопрос — а точно ли набор изменений в итоговом сжатом коммите соответствует исходному? это ещё проверить надо, если подозрение, что этот коммит вызвал проблему. При раздельных коммитах на подфичи такого вопроса не возникает. 200 строк изменений — ещё разумное предельное количество.


А вот второй пример на 2200 строк — это уже случай, не поддающийся визуальной верификации (кроме как если это результат какого-то легко воспроизводимого автоматического изменения).


А вот когда смешивается, например, перереформатирование всяких отступов и отделений (да, в Go это нетипично, но не он один), пара рефакторингов, и наконец финальная фича… и всё это потом склеено в один коммит — разбираться в полученной каше, мягко говоря, нереально. Мне приходилось спорить с категорическими сторонниками таких подходов, и я был слегка в ужасе (и рад, что они со мной не работают).


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

У меня практически нулевой опыт с "галерами": только продуктовые компании. В них нормально, что кто-то работает год-два, а кто-то и 20; в общем, peer review следит за тем, чтобы каждый отдельный коммит был понятным. Ну и нам помогает то, что ценность понимания тематики важнее ценности понимания инструментов. Для типовой аутсорс/аутстафф-галеры, вероятно, это и не так — там требуются суперусилия заставить людей грамотно делить и описывать, и обычно эти усилия не применяются, интересует только чтобы результат проходил тесты… :(


Потому я таки счёл нужным оставить свои аргументы в истории этого обсуждения.

Staging лучше переводить как индексацию, а не использовать кальку стейджинг.
Это нормально укладывается в остальную терминологию и отражает смысл. Staging area в Git называется Index.

Вот как раз слово index благодаря другим его привычным смыслам тут совершенно сбивает с толку, это явно рудимент первых версий, когда у Git вообще не было нормальных средств управления. А staging area - очевидно приемлемый термин.

(Вообще, то, что оно ещё и cache - в опциях типа --cached для git diff - совсем скручивает мозги. Лучше бы унифицировали.)

Понять индексирование проще, чем объяснять, зачем надо заново добавлять в staging area после каждого изменения. Тут скорее add и cached выглядят нелогичными рудиментами.

Понять индексирование проще

Каким образом? Для >90% ITшников "индексирование" это создание структуры данных для быстрого поиска. Какое отношение staging area имеет к этому?

зачем надо заново добавлять в staging area после каждого изменения.

Это одна из самых базовых вещей - и самых очевидных. Вы можете не пользоваться этим механизмом, вызывая что-то вроде `git commit .`, но если используете, то задача накопить комплект изменений и затем их зафиксировать - решается только так.

Тут скорее add и cached выглядят нелогичными рудиментами.

Это не рудименты. Это, наоборот, прогресс по сравнению со старым стилем, когда единственным вариантом было сказать `<tool> commit <список файлов и каталогов>`. Но кто не хочет, может не пользоваться (теряя массу возможностей).

Git, мощная штука, но действительно, на практике подавляющая часть его команд используется очень редко. А то что редко используется очень быстро забывается.
Когда мне нужно что-то отличное от commit pull push, приходится пользоваться шпаргалкой, но не всегда удается сделать задуманное без ошибок. Это под Linux.
Под виндой, к счастью, есть нормальные гуевые интерфейсы, типа GitExtensions.
Там, если я хочу посмотреть историю файла, создать новую ветку, удалить старую и т.д., мне достаточно воспользоваться контекстным меню.
Но изучить все команды git это обязательно. Иначе я бы не знал что искать в контекстном меню :)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий