Минимальный жизнеспособный Git для разработки на основе магистрали
Чем меньше, тем лучше, когда речь идет о таком мощном и слишком сложном инструменте, как Git.
Эли является соучредителем и со-генеральным директором trunk.io . Он занимал руководящие должности инженеров в Microsoft, Uber и Google (которая приобрела стартап, соучредителем которого он является). Его основная задача — помочь командам быстрее создавать лучшее программное обеспечение.

Разработка в среде для совместной работы — это сложная операция, которая включает в себя отслеживание и координацию работы нескольких разработчиков. Многие из нас используют Git для управления версиями, чтобы контролировать все эти изменения. Но, по словам самого Линуса , Git — это «информационный менеджер из ада». Он предлагает так много опций и странных состояний, что вы можете легко оказаться в плохом положении до такой степени, что вам нужно повторно клонировать с нуля, даже если вы не сделали ничего плохого.
Многие из нас знают, что один разработчик изучил refspec Git и базовое дерево Меркла, на котором оно основано, но быть специалистом по Git, вероятно, не входит в ваши должностные обязанности. Я могу отлично водить машину, не понимая, как на самом деле работает трансмиссия, и, в конце концов, Git — это просто средство для достижения цели.
Чтобы получить максимальную отдачу от Git, вы должны использовать его как можно меньше , когда речь идет о разработке на основе магистралей. Ограничьте количество используемых команд, своевременно обновляйте свою ветку функций и стандартизируйте использование в команде. В индивидуальном порядке вы можете наслаждаться свободой делать все, что захотите. Но в команде за свободу приходится платить трениями.
Ограничьте свои действия с Git
Самый простой способ добиться максимальной эффективности Git — придерживаться подмножества команд. Git может делать многое, но подавляющее большинство его возможностей существует только для того, чтобы помочь вам выбраться из ужасных ситуаций. Количество команд, которые позволяет Git, по сравнению с количеством команд, которые вы действительно должны когда-либо вызывать, сильно различаются.
Однажды технический директор попросил меня провести курс по продвинутому git для его инженерной команды. Мой ответ был прост:
к моменту, когда понадобится продвинутый гит — колеса уже оторвутся от машины. вместо этого давайте сосредоточимся на правильном использовании ядра git.
Вот 10 git-команд, которые я использую, чтобы выполнить свою работу и свести к минимуму количество попаданий в Git-ад:
Управление филиалом
git checkout -t -b {branch-name}
Создайте ветку, установите восходящий поток на текущую ветку и переключитесь на нее. Вы также можете сделать это с помощью команды `git branch`, но для этого потребуется несколько команд. Так как я всегда хочу переключиться на ветку при ее создании, эта команда более краткая. Создайте и проверьте ветку одним махом. Обычно я называю все свои ветки eli/{work-being-done}
.
git checkout {branch-name}
Переключитесь на ветку.
git branch -vv
Просмотрите свои текущие ветки и их восходящие потоки.
git branch -D {branch-name}
Удалите локальную ветку, обычно для очистки устаревших/объединенных веток.
Толкание и вытягивание
git fetch origin main:main
Вставьте пульт main
в свой локальный main
, даже если вы сейчас не в main
ветке! Это ; очень полезно, когда вы пытаетесь слить последнюю main
версию в ветку PR.
git push origin
Отправьте мой код на пульт; вероятно, раскрутил много машин в CI, чтобы проверить мою работу.
git pull
Обновите мою локальную ветку с помощью пульта с таким же именем.
Совершение
git add -A .
Добавить все, над чем я работаю (новые и отредактированные файлы).
git commit -am "work"
См. здесь для глубокого погружения в мои мысли о сообщениях локальных коммитов
git merge main
Подробнее об этом ниже. Я прагматичен, а не ребазер, и рад замутить свою локальную ветку происходящим из main
.
Держите свою ветку функций в актуальном состоянии должным образом
В моей последней части я обсуждал, как управлять посадочным кодом на main
. Но часто во время разработки и, конечно же, перед слиянием вам необходимо быть в курсе последних изменений, main
потому что:
- Вам нужна какая-то функция, которая приземлилась,
main
чтобы выполнить вашу функцию. - Что -то
main
изменилось, и если вы этого не поймете, вы сломаете его, когда попытаетесь загрузить свой код. - Вы просто хотите оставаться свежим, потому что вы инженер и любите блестящие новые вещи.
Дверь 1: слияние git
Это моя стратегия слияния. Он простой, надежный и без излишеств. Базовый git merge
берет все произошедшие изменения main
и объединяет их вместе как коммит вместе с вашими изменениями. Вы можете до тошноты читать о недостатках этого решения без излишеств, но я, честно говоря, просто пожимаю плечами и говорю: «Меня это не волнует». Если вы объедините свои рабочие ветки main
, то вся эта ерунда о загрязнении git-log станет просто так.
Честно говоря, на самом деле не имеет значения, как/почему/что попало в мою рабочую ветку. Важно то, строится ли он, работает ли он и делает ли код то, что я хочу? Остальное академично.
На практике, а я очень практичный инженер, git merge
позволяет вам аккуратно справляться с конфликтами слияния и возвращаться к построению. Вы разрешаете любые конфликты слияния один раз — и все готово. Это лучший вариант для начинающих, занятых продвинутых пользователей и тех из вас, кто не мечтает стать гуру Git.
Дверь 2: git rebase
Это худший вариант на сегодняшний день. Хорошо, я знаю; есть практически целое поколение, которое рассматривает перебазирование и слияние чего-то вроде вкладок и пробелов. Но в «реальных» проектах, где одна или несколько команд ежедневно объединяются в репозиторий, rebase требует разрешения n конфликтов слияния вместо одного с помощью слияния или сквоша (подробнее об этом ниже).
Кроме того, любое перебазирование перезаписывает историю Git, а это означает, что если у вашей ветки есть удаленный аналог, вам нужно git push --force
топать ее историю новой перебазированной историей вашей ветки. Теоретически это хорошо, но существует вероятность того, что ваша предыдущая работа будет случайно удалена, и восстановить ее будет крайне сложно. Это просто намного опаснее, чем слияние, и, честно говоря, у меня голова болит от одной мысли об этом.
Для целей этой статьи я попытался перебазировать, просто чтобы напомнить себе, как сильно я не люблю этот рабочий процесс. Посмотрите, что выводит на мой терминал простая команда rebase:

С этим терминалом столько всего не так. Я получаю заметки о хэшах коммитов — не хочу их видеть. Я получаю четыре строки желтых подсказок, чтобы напомнить мне, как все это работает. И сейчас я нахожусь в каком-то рабочем процессе, чтобы получить код из main
своей ветки. Дерево решений глупо сложно; git rebase --skip
- что это?! Почему можно пропустить коммит? Знаешь что? Не говорите мне, потому что у меня есть работа.
Дверь 3: git squash rebase
Вам определенно не нужно то, что находится за дверью № 2, но некоторые люди являются несгибаемыми ребакерами. Мой соучредитель, со-генеральный директор Дэвид Апирян, показал мне свой секретный вход за кулисы в rebase, и это довольно круто. Мы назовем это перебазированием сквоша .
Я неоднократно подчеркивал важность простоты Git, но с таким подходом вы можете и перебазировать, и съесть его. Вы получаете волшебное многоуровневое перебазирование без безумия стандартного потока перебазирования. С помощью перебазирования сквоша вы можете:
- Посмотрите различия ваших локальных коммитов, прежде чем отправлять их на GitHub.
- Легко отменить последнюю фиксацию.
- Не загрязняйте представление GitHub о вашем запросе на вытягивание кучей небольших локальных коммитов.
Шаг 1 — раздавить все ваши локальные коммиты:
git reset --soft $(git merge-base HEAD main) &&
git commit -am "" --allow-empty-message
git rebase main
Вы можете объединить все это в одну убер-команду, чтобы получить последний основной файл, сжать все ваши коммиты и перебазировать последний основной файл:
git reset --soft $(git merge-base HEAD main) &&
git commit -am "" --allow-empty-message &&
git fetch origin main:main &&
git rebase main
[alias]
smartcommit = !git add -A . && git commit -am "" --allow-empty-message
squash = !git reset --soft $(git merge-base HEAD main) && git commit -am "" --allow-empty-message
squashrebase = !git squash && git fetch origin main:main && git rebase main
smart = !git smartcommit && git squashrebase
Один из самых крутых аспектов постоянного раздавливания ваших локальных коммитов заключается в том, что в верхней части ваших коммитов git log
находится вся работа, которую вы проделали в ветке. Ваша локальная работа теперь больше похожа на то, как будет выглядеть объединенный PR в сквоше, когда он попадет в main
.
Вы можете в любой момент вытащить последний коммит из HEAD в свою локальную ветку и увидеть всю работу, которую вы проделали из main
. Это похоже на подробное представление изменений, которое GitHub предоставляет вам, но позволяет вам оставаться в своем терминале и избегать путаницы при переключении между двумя разными пользовательскими интерфейсами.
Должен признаться, что когда Дэвид впервые показал мне этот рабочий процесс, я был впечатлен. Он в основном убил rebase
дракона, и возможность локального просмотра всех файлов, которые вы изменили в своей ветке, очень крутая.
В то время как сквош-перебазирование помогает вам поддерживать лучшее состояние потока, подавляющее большинство разработчиков предпочитают просто слияние. Неправильное использование rebase или squash rebase приводит к трениям, которые убивают производительность.
Подводные камни справки ветки GitHub
GitHub предлагает этот параметр ☝️, чтобы предлагать main
автоматическое слияние с вашей веткой, если она устарела. Этот параметр часто контрпродуктивен. Я хочу, чтобы моя локальная ветка была единственным источником правды для моего пиара, и никто другой (включая GitHub) не должен на это напирать. Работа с GitHub в моей личной ветке должна быть улицей с односторонним движением. Я кодирую локально и нажимаю.
Если вы настроите GitHub так, чтобы он начал отправлять обновления в вашу рабочую ветку, вы просите, чтобы трафик начал двигаться в неправильном направлении. И это рецепт боли.
Эта проблема также возникает, когда рецензенты кода оставляют вам небольшие предложения по коммитам в вашем запросе на включение, и вы беспечно их применяете. Если вы затем проделаете какую-либо работу в своей локальной ветке, прежде чем вытаскивать эти изменения … вы откроете небольшой мешок git с болью.
Я часто обнаруживаю, что случайно сделал это с собой, когда пытаюсь отправить свои обновления обратно на удаленный компьютер, а git сообщает мне, что я не синхронизирован. В этот момент у меня есть два варианта:
git push --force
и сдуйте все на удалении, а не в вашей локальной ветке. Обычно все, что связано со словом сила, разрушительно и обескураживает.git merge origin/{my-work-branch}
чтобы объединить удаленные изменения с локальным представлением ветки.
Этот параметр GitHub ️☝️ требует, чтобы PR были обновлены main
перед слиянием с ним. Обычно это «решает» возможность поломки main
; однако он работает только с репозиториями с очень низкой скоростью. Как только несколько разработчиков пытаются объединить несколько PR в день, они вступают в гонку за слияние main
— или иным образом обнаруживают, что постоянно выполняют слияние/перебазирование main
в свою ветку, чтобы снова быть «актуальными», и в основном соревнуются со своими коллегами. быть первым, чтобы слиться. Болезненный. Как правило, если вам нужна эта функция, но вы не являетесь разработчиком-одиночкой, вам, вероятно, вместо этого нужна очередь слияния — это масштабируемый способ добиться отсутствия поломки основного. Это то, что мы сочли достаточно важным для реализации с помощью Trunk Merge .
Минимизируйте Git для получения максимальной выгоды
Максимально упрощая использование Git, вы даете разработчикам меньше веревки, на которой можно повеситься, и больше времени для выполнения действительно важной работы по разработке. Заставьте Git играть вспомогательную роль, а не стать главным героем. Чтобы поддерживать разумную и совместную среду разработки, не забудьте:
- Выберите наименьшую поверхность Git для использования и придерживайтесь ее.
- Всегда управляйте своими исходными изменениями одним и тем же способом.
- Стандартизируйте методы работы в своей команде, чтобы ваши коллеги тоже не сбились с пути.