Это мой 15-й день в Gengwen Challenge, ознакомьтесь с подробностями события:Обновить вызов
Как самый мощный инструмент управления кодом в мире, Git, я полагаю, все знакомы с ним, но, насколько я знаю, большое количество людей остаются на стадии клонирования, фиксации, извлечения, отправки и т.д. не заинтересованы в перебазировании?В конце концов, только осмеливается использовать слияние?
Вы слепы, когда сталкиваетесь с откатами версий? Не спрашивайте меня, откуда я знаю, просто спросите: "Раньше я был таким~~".
В ответ на эти проблемы сегодня я поделюсь своими знаниями и пониманием Git за последние несколько лет и попытаюсь объяснить Git с точки зрения его сути, чтобы помочь вам шаг за шагом понять основные принципы Git. что после прочтения этой статьи вы можете С другой стороны, более кокетливо использовать различные команды Git.
1. Основные понятия
1.1 Преимущества Git
Git — это инструмент управления распределенным кодом, поэтому перед обсуждением распределенного неизбежно упомянем, что такое централизованный репозиторий управления кодом:
-
Централизованный: весь код хранится на центральном сервере, поэтому отправка должна полагаться на сеть, и каждая отправка будет доставляться в центральное хранилище.Если это совместная разработка, слияние кода может часто запускаться, что увеличивает стоимость и стоимость подчинение. Наиболее типичным является svn.
-
Распределенный: его можно отправить локально, не полагаясь на сеть, и каждая отправка будет автоматически резервироваться локально. Каждый разработчик может локально клонировать удаленный репозиторий и переносить с ним историю коммитов. Представитель Git.
Итак, какие преимущества у Git перед svn?
Например: «Балабара написал много кода, и вдруг обнаружил, что есть проблема с написанием, я хочу вернуться на час назад», преимущества Git в этом случае очевидны, потому что стоимость коммита относительно маленький и локальный будет Все коммиты сохраняются и их можно откатить в любой момент.
Это не значит, что svn не может этого сделать, просто альтернатива Git будет более элегантной. По сравнению с центральными инструментами у Git много преимуществ, поэтому я не буду перечислять их по отдельности, кому интересно, они сами разберутся.
1.2 Статус файла
В Git файлы условно делятся на три состояния: модифицированное, подготовленное и зафиксированное.
-
Модификация: Git может определить, какие файлы в рабочем каталоге были изменены, а затем добавить измененные файлы в измененную область.
-
Постановка: отправьте измененные файлы в рабочем каталоге в область подготовки с помощью команды добавления, ожидая фиксации.
-
Зафиксировать: зафиксировать файл промежуточной области в каталоге Git для постоянного хранения.
1.3 узел фиксации
Для простоты выражения я отправлю эту статью через коммит имени узла
В Git каждая отправка будет генерировать узел, и каждый узел будет иметь хеш-значение в качестве уникального идентификатора, а несколько представлений будут формировать линейную цепочку узлов (независимо от слияния), как показано на рисунке:
Над узлом находится хэш, рассчитанный SHA1.
Узел C2 содержит представление C1, а узел C3 также содержит представления C1 и C2.
1.4 HEAD
HEAD — очень важное понятие в Git, вы можете называть его указателем или ссылкой, он может указывать на любой узел, а узел, на который указывает, всегда является текущим рабочим каталогом, другими словами, текущим рабочим каталогом (то есть, код, который вы видите) — это узел, на который указывает HEAD.
На рис. 1-1 в качестве примера: если HEAD указывает на C2, рабочий каталог соответствует узлу C2. Как переместить HEAD в точку, мы обсудим позже, не беспокойтесь об этом здесь.
В то же время HEAD также может указывать на ветку, косвенно указывая на узел, на который указывает ветка.
1.5 Удаленный склад
Хотя Git сохранит код и историю локально, в конечном итоге они будут зафиксированы в удаленном репозитории на сервере. Через команду clone можно загрузить код удаленного хранилища на локальное, а также синхронизировать историю коммитов, ветку, HEAD и другие состояния на локальное, но эти состояния не будут обновляться в реальном времени, нужно вручную тянуть с удаленного склада, а когда и как тянуть будет обсуждаться в последующих главах.
Через удаленный репозиторий в качестве посредника вы можете разрабатывать совместно с вашими коллегами.После разработки новых функций вы можете подать заявку на отправку в удаленный репозиторий, а также вы можете получить код своих коллег из удаленного репозитория.
будь осторожен:
Поскольку вы и ваши коллеги будете использовать код удаленного хранилища в качестве эталона, вы всегда должны обеспечивать качество кода удаленного хранилища и помнить, что не следует отправлять непроверенный код на удаленное хранилище.
2. Филиал
2.1 Что такое филиал?
Ветвь также является очень важной концепцией в Git. Когда ветвь указывает на узел, содержимое текущего узла является содержимым ветки. Его концепция очень близка к HEAD и также может рассматриваться как указатель или ссылка. разница в том, что веток может быть несколько, а в HEAD только одна. Различные ветки обычно создаются на основе функций или версий.
Какая польза от этой ветки?
Например: ваше приложение прошло через неисчислимые трудности и, наконец, выпустило версию 1.0. Из-за срочного спроса, после запуска версии 1.0, оно безостановочно запускало версию 1.1. Как раз, когда ваша разработка была на Rise, QA студенты сказали, что пользователи дали отзывы Некоторые ошибки нужно исправить, а затем перевыпустить.Чтобы исправить v1.0, код должен быть основан на v1.0, но вы уже разработали часть v1.1.Что вы должны сделать сейчас?
Столкнувшись с вышеуказанными проблемами, их можно элегантно решить, введя концепцию ветвления, как показано на рис. 2-1.
Сначала посмотрите на схему слева, предполагая, что узел C2 является кодом версии v1.0, а новая ветка ft-1.0 будет создана на основе C2 после выхода в сеть.
Глядя на диаграмму справа, после выхода версии 1.0 в сеть вы можете разрабатывать контент версии 1.1 в ветке master.После получения отзывов от студентов QA отправьте узел генерации кода версии 1.1 C3, а затем Ветвь -1.0 для исправления ошибок.После завершения ремонта Отправьте код для создания узла C4, затем переключитесь на основную ветку и объедините ветку ft-1.0.На этом этапе мы решили проблемы, поднятые выше.
Кроме того, есть много вещей, которые можно сделать с помощью веток.Например, есть требование, что вы не уверены, выходить в интернет или нет, но вы должны сделать это в первую очередь.В это время вы можете создать отдельная ветка для разработки этой функции, а когда вам нужно выйти в интернет, вы можете напрямую слить ее в основную ветку. Есть много сценариев, где применимы ветки, поэтому я не буду перечислять их по одному.
будь осторожен:
Когда ветвь создается на узле, код, соответствующий узлу, не копируется, а новая ветвь указывает на узел, поэтому накладные расходы на пространство могут быть значительно уменьшены. Следует помнить, что будь то HEAD или ветка, они всего лишь ссылки и очень легкие по величине.
3 Детали команды
3.1 Связанные с отправкой
Как мы упоминали ранее, если вы хотите отправить код, вы должны сначала добавить его в тестовую область, В Git это реализуется командой add.
Добавьте файл в тестовую область:
git add 文件路径
Добавьте все файлы в тестовую область:
git add .
В то же время Git также предоставляет команды для отмены рабочей области и промежуточной области.
Чтобы отменить изменения рабочей области:
git checkout -- 文件名
Очистите промежуточную область:
git reset HEAD 文件名
представить:
После добавления файла изменений в промежуточную область его можно отправить. После отправки будет создан новый узел отправки. Конкретная команда выглядит следующим образом:
git commit -m "该节点的描述信息"
3.2 Связанные с отраслью
создать ветку
После создания ветки она будет указывать на тот же узел, что и HEAD.Популярно мнение, что новая созданная ветвь будет указывать на то, куда указывает HEAD.Команда выглядит следующим образом:
git branch 分支名
переключить ветку
При переключении ветвей HEAD будет указывать на текущую ветвь по умолчанию, то есть HEAD косвенно указывает на узел, на который указывает текущая ветвь
git checkout 分支名
При этом переключиться можно и сразу после создания ветки, команда следующая:
git checkout -b 分支名
удалить ветку
Чтобы ветки репозитория оставались чистыми, ветку следует удалять после того, как она выполнила свою работу. Например, как было сказано выше, для выполнения определенной функции открывается отдельная ветка, при объединении функции в основную ветку ветку следует вовремя удалить.
Команда удаления выглядит следующим образом:
git branch -d 分支名
3.3 Слияние
Команды для слияния являются самыми сложными для освоения и самыми важными. Мы обычно используем около трех команд слияния: слияние, перебазирование, выбор вишни.
merge
merge — наиболее часто используемая команда слияния, она может объединить код ветки или узла в текущую ветку. Конкретные команды следующие:
git merge 分支名/节点哈希值
Если объединяемая ветвь полностью опережает текущую, как показано на рис. 3-1.
Поскольку ветка ft-1 полностью ведет ветку ft-2, то есть ft-1 полностью содержит ft-2, то после того, как ft-2 выполнит «git merge ft-1», будет запущена быстрая перемотка вперед (fast merge), и две ветви указывают на один и тот же узел, это самое идеальное состояние.
Но в реальной разработке мы часто сталкиваемся со следующей ситуацией: Рисунок 3-2 (слева)
В этом случае его нельзя объединить напрямую.Когда ft-2 выполнит «git merge ft-1», Git объединит узлы C3 и C4, а затем сгенерирует новый узел C5 и, наконец, направит ft-2 на C5, как показано на рисунке. 3-2 (справа)
будь осторожен:
Если C3 и C4 изменяют один и тот же код в одном и том же файле одновременно, слияние в этот раз пойдет не так, потому что Git не знает, какой узел использовать в качестве стандарта, поэтому нам нужно вручную слить код самостоятельно в этот раз.
rebase
rebase также является командой слияния, командная строка выглядит следующим образом:
git rebase 分支名/节点哈希值
В отличие от слияния, слияние с перебазированием, по-видимому, не создает новые узлы (на самом деле это происходит, но только один раз скопировано), а непосредственно накапливает узлы, которые необходимо объединить, как показано на рис. 3-3.
Когда ft-1.0 на диаграмме слева выполняет git rebase master, он скопирует узел C4 в конец C3, то есть C4', C4 соответствует C4', но значение хеш-функции другое.
По сравнению со слиянием rebase является более линейным и чистым, что делает параллельный процесс разработки похожим на последовательный, что больше соответствует нашей интуиции. Поскольку rebase работает так хорошо, можем ли мы отказаться от слияния? На самом деле это не так.Ниже я перечислю некоторые преимущества и недостатки слияния и перебазирования:
Объедините преимущества и недостатки:
-
Преимущества: Каждый узел расположен строго в хронологическом порядке. Когда возникает конфликт при слиянии, необходимо только разрешить конфликт узлов, на которые указывают две ветви.
-
Недостатки: при слиянии двух веток велика вероятность того, что будет сгенерирована и разветвлена новая нода, а история коммитов со временем запутается
Преимущества и недостатки перебазирования:
-
Плюсы: Делает историю коммитов более линейной и чистой.
-
Недостаток: хотя коммиты кажутся линейными, на самом деле они не упорядочены в хронологическом порядке, как на рис. 3.3, независимо от того, был ли коммит C4 до или после C3, он в конечном итоге будет после C3. И когда возникает конфликт при слиянии, теоретически есть несколько узлов, которые перебазируются в целевую ветку для обработки нескольких конфликтов.
Для некоторых представлений в Интернете, которые используют только rebase, автор с этим не согласен.Если rebase используется для слияния разных веток, может потребоваться повторное разрешение конфликтов, что не будет стоить потерь. Но если он выталкивается локально на удалённый и соответствует той же ветке, rebase может быть отдан приоритет. Итак, моя точка зрения состоит в том, чтобы использовать слияние и перебазирование в разумной комбинации в соответствии с различными сценариями.Если вы думаете, что это работает, то сначала используйте перебазирование.
cherry-pick
Слияние вишневого выбора отличается от слияния и перебазирования, оно может выбирать определенные узлы для слияния, как показано на рис. 3-4.
Командная строка:
git cherry-pick 节点哈希值
Предполагая, что текущая ветвь является главной, после выполнения команд git cherry-pick C3 (значение хеш-функции) и C4 (значение хэш-значения) узлы C3 и C4 будут напрямую захвачены и размещены позади, что соответствует C3' и C4'.
3.4 Резервный вариант
отсоединить ГОЛОВУ
По умолчанию HEAD указывает на ветку, но вы также можете удалить HEAD из ветки и напрямую указать на узел.Этот процесс предназначен для отделения HEAD.Конкретные команды следующие:
git checkout 节点哈希值//也可以直接脱离分支指向当前节点git checkout --detach
Поскольку хеш-значение представляет собой длинную строку искаженных символов, очень проблематично использовать хеш-значение для разделения HEAD в реальной работе, поэтому Git также предоставляет HEAD для прямого указания на предыдущий или предыдущий N на основе специальной позиции (ветвь/ HEAD) Команда узла, то есть относительной ссылки, выглядит следующим образом:
//HEAD分离并指向前一个节点
git checkout 分支名/HEAD^
//HEAD分离并指向前N个节点
git checkout 分支名~N
Какая польза от разделения HEAD, чтобы указать на узел? Например: если процесс разработки обнаружит, что есть проблема с предыдущей отправкой, вы можете указать HEAD на соответствующий узел в это время и отправить его после модификации.В это время вы определенно не хотите создавать новый узел , но вам нужно отправить его только при отправке. Просто добавьте --amend, конкретная команда выглядит следующим образом:
git commit --amend
вернитесь
Сценарий отката довольно распространен в обычной разработке, например, вы пишете много кода и отправляете его, но позже обнаруживаете, что с написанием возникла проблема, поэтому вы хотите вернуть код к предыдущей отправке. можно решить с помощью сброса.Конкретные команды следующие:
//回退N个提交
git reset HEAD~N
reset похож на относительную ссылку, разница в том, что reset вернет ветку и HEAD вместе.
3.5 Дистанционная корреляция
Когда мы вступаем в контакт с новым проектом, первое, что нужно сделать, это удалить его код.В Git мы можем скопировать код из удаленного репозитория в локальный через клон.Конкретные команды следующие:
git clone 仓库地址
Как я упоминал в предыдущей главе, клонирование не только копирует код, но также удаляет ссылку (ветвь/HEAD) на удаленное хранилище и сохраняет ее локально, как показано на рис. 3-5:
Origin/master и origin/ft-1 являются ветвями удаленного хранилища, и эти удаленные эталонные состояния не будут обновляться до локального в режиме реального времени.Например, ветвь origin/master удаленного хранилища добавляет фиксацию и локальный не может воспринимать его в это время, поэтому локальная исходная/главная ветвь по-прежнему указывает на узел C4. Мы можем вручную обновить статус удаленного репозитория с помощью команды fetch.
намекать:
Удаленным складом можно назвать не только то, что есть на сервере, но и локальный склад можно клонировать как удаленный, конечно, в реальной разработке мы не можем рассматривать локальный склад как публичный Я говорю это только для того, чтобы помочь вам лучше понять распределенный склад.
fetch
Проще говоря, команда fetch представляет собой операцию загрузки. Она загрузит состояние недавно добавленных удаленных узлов и ссылок (ветвь/HEAD) на локальный. Конкретные команды следующие:
git fetch 远程仓库地址/分支名
pull
Команда pull может извлекать код из ссылки в удаленном репозитории. Конкретные команды следующие:
git pull 远程分支名
По сути, суть pull — это fetch+merge, который сначала обновляет все состояние удаленного хранилища до локального, а затем сливает его. После завершения слияния локальная ветвь будет указывать на последний узел.
Кроме того, команда pull также может быть объединена с помощью rebase.Конкретные команды следующие:
git pull --rebase 远程分支名
push
Команда push может передать локальную отправку на удаленный.Конкретные команды следующие:
git push 远程分支名
Если пушить напрямую, может не получиться, потому что могут быть конфликты, поэтому вы будете часто тянуть перед пушем, а если есть конфликт, то он будет решаться локально. После успешной отправки ссылка на локальную удаленную ветку будет обновлена, указывая на тот же узел, что и локальная ветка.
3 Подводя итоги
-
Будь то HEAD или ветка, это всего лишь ссылки.Ссылка + узел — это ключ к дистрибутиву Git.
-
Слияние имеет более четкую временную историю, чем перебазирование, а перебазирование делает коммиты более линейными и должно использоваться в первую очередь.
-
Вы можете просмотреть код, соответствующий каждой фиксации, переместив HEAD
-
clone или fetch сохранит все коммиты и ссылки удаленного хранилища в локальной копии
-
Суть pull на самом деле fetch+merge, можно еще добавить --rebase для слияния по rebase