Комментарии 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 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 следит за тем, чтобы каждый отдельный коммит был понятным. Ну и нам помогает то, что ценность понимания тематики важнее ценности понимания инструментов. Для типовой аутсорс/аутстафф-галеры, вероятно, это и не так — там требуются суперусилия заставить людей грамотно делить и описывать, и обычно эти усилия не применяются, интересует только чтобы результат проходил тесты… :(
Потому я таки счёл нужным оставить свои аргументы в истории этого обсуждения.
[del]
Это нормально укладывается в остальную терминологию и отражает смысл. 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 <список файлов и каталогов>`. Но кто не хочет, может не пользоваться (теряя массу возможностей).
Когда мне нужно что-то отличное от commit pull push, приходится пользоваться шпаргалкой, но не всегда удается сделать задуманное без ошибок. Это под Linux.
Под виндой, к счастью, есть нормальные гуевые интерфейсы, типа GitExtensions.
Там, если я хочу посмотреть историю файла, создать новую ветку, удалить старую и т.д., мне достаточно воспользоваться контекстным меню.
Но изучить все команды git это обязательно. Иначе я бы не знал что искать в контекстном меню :)
Продвинутые функции гита, о которых вы, возможно, не знали