Справочник по Git

Git

Введение

Давайте сначала поговорим о наиболее важном рабочем процессе Git: выгрузите код из удаленного репозитория в локальный репозиторий, извлеките ветку и разработайте в локальной рабочей области, отправьте код в репозиторий через промежуточную область и, наконец, отправьте в удаленное хранилище. Такой процесс несложно понять, но в реальном командном сотрудничестве часто задействованы такие операции, как слияние, разрешение конфликтов, отправка и откат ветвей собственной ветки, ветвей других участников и публичных ветвей. Для того, чтобы разобраться в различных операциях Git, эта статья будет собрана в руководство по эксплуатации в виде сценарий+решение, на которое вам удобно ссылаться в дальнейшем, а новые члены команды смогут быстро приступить к работе. .

2. Необходимые очки знаний

Основная концепция Git разделена на четыре блока, а именно: удаленное хранилище, локальный репозиторий, область временного хранения и рабочее пространство.Следующее изображение может четко описать взаимосвязь между этими четырьмя блоками.

Git 核心区块

Глобальное описание: звездочка * после ветви обозначает текущую ветвь.

3. Вытягивайте статьи

Сцена 1.Предположим, есть две удаленные ветки, master и branchA, которые были подтянуты в локальный репозиторий.В это время коллега удалил ветку branchA в удаленном репозитории, но вы все еще можете видеть origin/branchA на своем компьютере.Как вы можете обновить репозиторий??

Решение:Получить новые ветки удаленных репозиториев и удалить удаленные ветки удаленных репозиториев (ветки в локальном репозитории)

git fetch -p  // --prune(修剪)的缩写

Сценарий 2.После локального добавления новой записи отправки она будет отправлена ​​с удаленного устройства до того, как будет готова к отправке на удаленное устройство.git pullИзвлеките код для обновления, предполагая, что другие коллеги в это время отправили новый код, почему в это время извлечение автоматически генерирует (на первый взгляд) бессмысленную запись фиксации и как сделать запись фиксации более интуитивно понятной и понятной?

исходная запись коммита

      C---D  origin/branchA
     /
A---B---E  branchA*

После git pull есть еще одна запись коммита.Merge branch "XXX" into XXX, что является точкой F в следующем примере

      C---D  origin/branchA
     /     \
A---B---E---F  branchA*

Решение:

git pull --rebase
      origin/branchA
            |
A---B---C---D---E  branchA*

git pull = git fetch + git merge // извлечение в локальный репозиторий + слияние в локальную рабочую область
git pull --rebase = git fetch + git rebase // Извлечь в локальный репозиторий + перебазировать рабочую область в последний репозиторий

4. Филиалы

Сцена 1.Как создать ветку из указанной ветки?

Решение:

// 从目标分支创建本地分支,如果没有指定目标分支,默认为当前分支
git branch <name> [<targetBranch>]

// 创建并切换到该分支
git checkout -b <branchname> [<tragetBranch>]

Сценарий 2.Как связать локальную ветку с указанной удаленной веткой?

Решение:

git branch --set-upstream-to=<origin/branchname>
// 或者
git branch -u <origin/branchname>

Сценарий 3.Как отменить связь между локальной веткой и удаленной веткой?

Решение:

git branch --unset-upstream [<origin/branchname>]

Сценарий 4.Как просмотреть сведения о ветке и связанной с ней удаленной ветке?

Решение:

git branch -vv

Сценарий 5.Как удалить локальную ветку?

Решение:

git branch -D <branchname>

Сцена 6.Как удалить удаленную ветку?

Решение:

git push -d origin <branchname>
// 或者
git push origin :branchname

Сцена 7.Как переместить/переименовать ветки?

Решение:

// 将目标分支 移动/重命名 到新分支
git branch -m <branchname> [<targetBranch>]

Сцена 8.Как объединить ветки?

Решение:mergeсливаться

git merge <branchname>

Случай 1: Исходная запись коммита

      C---D  feature
     /
A---B  master*

Случай 1: Коммиты после слияния

A---B---C---D  master*、feature

Случай 2: Исходная запись коммита

      C---D  feature
     /
A---B---E  master*

Случай 2: фиксация записей после слияния

      C---D  feature
     /     \
A---B---E---F master*

В сценарии совместной разработки с несколькими людьми операция слияния склонна к замыканию петель между ветвями, что делает информацию о представлении ветки неясной и не способствует сопровождению ветки.

Сцена 9.Как объединить указанную запись фиксации указанной ветки?

Решение:cherry-pickвыбор

// 合并指定提交记录
git cherry-pick <commit>

// 合并多个提交记录
git cherry-pick <commit1> <commit2> <commit3>

// 若提交记录在同一分支上,则可以采用区间形式(start, end],commit1不包含,commit3包含
// 等价于合并了 commit2、commit3
git cherry-pick <commit1>..<commit3>

// 若省略了区间形式的起点,则起点默认为两个分支的交点
git cherry-pick ..<commit3>

исходная запись коммита

      C---D  feature
     /
A---B---E  master*

git cherry-pick B..DЗаписи представления после выбора

      C---D  feature
     /
A---B---E---C'---D'  master*

Операция выбора вишни скопирует запись фиксации в текущую ветку, сделав информацию о фиксации текущей ветки более четкой.

Расширение:cherry-pickЕсли в операции возникает конфликт, поток обработки выглядит следующим образом.

  1. разрешить конфликт или хотите прервать операциюgit cherry-pick --abort(для прерывания не требуются последние два шага)
  2. добавить в зону подготовкиgit add .
  3. продолжать выбиратьgit cherry-pick --continue

Сцена 10.Проверьте ветку функций из общедоступной ветки для разработки новых функций и подготовьтесь к объединению ее обратно в общедоступную ветку после разработки.В настоящее время обнаружено, что кто-то еще отправил новую запись фиксации в общедоступную ветку.Как может Я обновляю функциональную ветку публичной веткой?

**Временное решение: **ПропуститьrebaseПеребазировать, переместить базовую точку текущей ветки в целевую ветку

// branchname 默认为当前分支,可省略
git rebase <targetBranch> [<branchname>]

// 等价于下面两条命令
git checkout <branchname>
git rebase <targetBranch>

исходная запись коммита

      C---D  feature
     /
A---B---E  master*

git rebase masterЗафиксировать запись после перебазирования

          C'---D'  feature*
         /
A---B---E  master

Операция перебазирования может обновить базовую точку (начальную точку) текущей ветки, чтобы текущая ветвь содержала новые записи фиксации в общедоступной ветке.Это имеет то преимущество, что в случае конфликта с основной веткой ее можно решен заранее в ветке функций.

Поскольку запись исторической фиксации изменена, текущая ветка будет несовместима с удаленной веткой после перебазирования, и для перезаписи удаленной ветки потребуется принудительная отправка (см. ниже).

Расширение:rebaseЕсли в операции возникает конфликт, поток обработки выглядит следующим образом.

  1. разрешить конфликт или хотите прервать операциюgit rebase --abort(для прерывания не требуются последние два шага)
  2. добавить в зону подготовкиgit add .
  3. продолжить перебазированиеgit rebase --continue

Сцена 11.Как объединить несколько записей фиксации?

Решение:git rebase --interactiveили сокращенная формаgit rebase -iИнтерактивная перебазировка

// commit 为需要处理的提交记录区间的父节点
git rebase -i <commit>

исходная запись коммита

A---B---C---D feature*

Нужно объединить C, D две записи фиксации,git rebase -i B

pick a0a6eba feat: 新增 C 功能
pick 95f09e5 feat: 新增 D 功能

Объедините запись фиксации D в C, поэтому поместите запись Dpickизменить наsquash, затем сохраните и выйдите

pick a0a6eba feat: 新增 C 功能
squash 95f09e5 feat: 新增 D 功能

Окончательная запись коммита, точка E, содержит все изменения C и D.

A---B---E feature*

Расширение: Режим редактирования vi будет автоматически введен во время интерактивного процесса перебазирования.Параметры объясняются следующим образом.

  1. р, выбрать выбранное
  2. r, выбрано переименование, и информация о представлении изменена
  3. e, выбрано редактирование, оно будет приостановлено во время перебазирования, что позволит вам изменить этот коммит.
  4. s, выбран сквош, текущая фиксация будет объединена с предыдущей фиксацией
  5. f, fixup, то же самое, что и squash, но не сохраняет информацию о текущем коммите
  6. x, exec выполняет другие команды оболочки

5. Представление

Сцена 1.Как исправить ошибку в информации о последней записи о подаче?

Решение:

git commit --amend -m '新的提交信息'

Сценарий 2.Недавняя фиксация и обнаружение отсутствия некоторых изменений?

**Временное решение: **Для обеспечения целостности информации о фиксации объедините отсутствующие изменения с этой фиксацией, не добавляя новую запись фиксации.

// 将遗漏的文件改动添加到暂存区
git add <filename>

// 将暂存区中的所有文件合并到最近一次提交中,
// 如果不带 --no-edit 参数,则在合并之后会进入提交信息修改面板
git commit --amend --no-edit

6. Пуш-статьи

Сцена 1.Как нажать на удаленную указанную ветку?

Решение:

// 推送到远程指定分支,并创建关联
git push -u origin <branchname>

// 若本地分支已经与远程分支关联,则可省略远程分支
git push

Сценарий 2.Как заставить нажать на удаленную ветку?

Решение:

git push -f // --force 的缩写

Если кто-то уже отправил в удаленную ветку во время процесса принудительной отправки, запись фиксации других будет потеряна.为了更安全的推送, вы можете использовать следующую команду.在他人推送了新的提交的情况下,强制推送会被拒绝.

git push --force-with-lease

Расширение: сценарии, требующие принудительного нажатия, могут быть следующими:

  • ветвьgit rebaseПосле перебазирования
  • Вы отправили код ошибки на удаленный компьютер и хотите удалить эту запись фиксации (рекомендуется использовать следующиеgit revertработать)

Принудительное нажатие на удаленную ветку перезапишет удаленную.Если вы не знакомы с этой командой, используйте ее с осторожностью!

7. Отмена

Сцена 1.Как отменить изменения в файлах локальной рабочей области?

Решение:

// 丢弃工作区某个文件的改动
git checkout -- <filePath>

// 丢弃工作区所有文件的改动
git checkout -- .

После отмены изменений локальной работы файл будет откатан до самого последнего состояния фиксации или добавления.

Сценарий 2.Как отменить изменения в промежуточной области?

Решение:

// 当没有指定 filename 时,表示撤销暂存区中的所有文件
git reset HEAD <filename>

После отмены изменений в промежуточной области файл вернется в состояние рабочей области.

Сценарий 3.Как отменить изменения в локальном репозитории?

Решение:

// 回退到指定的提交记录
git reset [<mode>] [<commit>]

Указав параметр режима, сделать файл после отката в соответствующем состоянии:

  • --soft: сбросить текущую ветку на указанную, а измененные файлы между текущей версией и указанной версией находятся вкеш хранения, в ожидании статуса отправки.
  • --Аппаратный сброскеш храненияа такжеРабочее пространство, любые изменения в промежуточной области и рабочей области с моментавыбросить.
  • --mixed (по умолчанию): сбросить текущую ветку на указанную, а измененные файлы между текущей версией и указанной версией находятся вРабочее пространствосередина,'not staged'условие.

Расширение: HEAD можно понимать как указатель, который всегда указывает на последнюю запись коммита в текущей ветке. HEAD^ представляет последнюю запись фиксации, HEAD^^ представляет две последние записи фиксации, а HEAD~n представляет последние n записей фиксации.

           HEAD^/HEAD~1
                |
A---B---C---D---E---F  branchA
            |       |
    HEAD^^/HEAD~2   HEAD

Сценарий 4.Я торопливо запушил код на удаленный склад перед тем, как уйти с работы, а потом счастливый пошел домой, но на следующий день обнаружил ошибку при отправке удаленного кода (вручную забавно :p ), как отменить изменения в удаленный склад в это время?

Решение:revertОтмените модификацию, затем повторно отправьте ее и отправьте в удаленный репозиторий.

// 撤销修改
git revert <commit>
// 推送到远程仓库,实现远程仓库的撤销
git push

Расширение:revertа такжеresetразница

revertзаключается в добавлении новой записи фиксации, а ее измененное содержимое просто компенсирует указанные изменения, иresetЭффект отмены заключается в сбросе репозитория. Предполагая, что локальный репозиторий такой же, как удаленный репозиторий,resetКоммит был отозван, а локальный репозиторий отставал на одну версию от удаленного репозитория.git pushНажатие на удаленный терпит неудачу, в то время какrevertДобавлена ​​новая фиксация, и локальный репозиторий на одну запись опережает удаленный репозиторий.git pushЕго можно нажать на пульт в обычном режиме.

Восемь, журнальные статьи

Сцена 1.В настоящее время локальный коммит отправлен, но не отправлен на удаленный склад.git reset --hardКак восстановить утерянные записи отправки, если неправильная операция принудительно откатывается?

**Временное решение: **Пропуститьgit reflogПроверьте журнал ссылок, найдите запись коммита, которая была удалена по ошибке, а затем откатитесь к удаленной записи.

git reflog // Reference logs(引用日志),能记录 HEAD 和分支引用所指向的历史

Допустим было отправлено три общих коммита, тогда по недоразумению вынужден откатиться к первому представлению, в результате чего во втором, три представления все потеряно

// git reflog 引用日志输出格式如下
1c36188 HEAD@{0}: reset: moving to 1c36188
d921970 HEAD@{1}: commit: feature-3
1c002dd HEAD@{2}: commit: feature-2
1c36188 HEAD@{3}: commit (initial): feature-1

Найдите ошибочно удаленные записи коммитов feature-2 и feature-3

git reset --hard d921970

Девять, Статьи хранилища

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

Решение:

// 将全部未保存的代码添加到贮藏区,若未填写描述信息,则以上一次 commit 的信息记录
git stash [push [-m <message>]]

Сценарий 2.Как я могу просмотреть коды, сохраненные в области хранения?

Решение:

git stash list

// 若存在贮藏的代码,则输出格式如下
stash@{0}: On feature: 新功能开发未完成,先贮藏一下       // 添加了描述信息
stash@{1}: WIP on master: 8e50dc3a feat:添加新功能xxx  // 未填写描述信息

Сценарий 3.Как получить сохраненный код?

Решение:

// 恢复指定下标的贮藏代码,并删除对应的贮藏列表,index 默认为 0
git stash pop [index]

// 等价于下面两条命令
git stash apply [index] // 取出贮藏
git stash drop [index] // 删除贮藏列表

Сценарий 4.Как очистить список хранения?

Решение:

git stash clear