35、Git远程仓库协作与工作树、子模块使用指南

Git远程仓库协作与工作树、子模块使用指南

在软件开发过程中,多人协作对远程仓库进行修改是常见的场景。同时,为了更高效地管理项目,Git 提供了工作树(worktrees)和子模块(submodules)等功能。本文将详细介绍如何模拟多人协作修改远程仓库,以及如何使用工作树和子模块。

模拟多人协作修改远程仓库

在这个模拟实验中,我们将模拟两个用户对同一个远程仓库进行修改,并处理可能出现的冲突。

实验前提
  • 具备互联网访问权限。
  • 完成了设置 GitHub 账户并克隆仓库的操作。
  • 在之前克隆仓库时使用的目录下进行操作。
操作步骤
  1. 切换到模拟用户一的目录 :在之前的实验中,我们从 GitHub 克隆了仓库到本地的两个不同目录: calc2 calc_other 。现在切换到 calc_other 目录,模拟用户一的操作。
$ cd calc_other
  1. 查看计算器现有功能 :在浏览器中打开 calc.html 文件,查看计算器现有的基本算术功能,如加法、减法、乘法和除法。
  2. 创建本地特性分支 :我们要从 features 分支引入一些新功能到计算器程序中。首先,创建一个本地 features 分支,跟踪远程 features 分支。
$ git branch features origin/features
  1. 查看可用功能 :使用以下命令查看 features 分支上可用的功能。
$ git log --oneline features
  1. 创建临时分支 :为了引入这些功能,创建一个新的临时分支 cpick ,并切换到该分支。
$ git checkout -b cpick
  1. 引入 max 函数 :从步骤 4 的历史记录中找到 max 函数的 SHA1 值,然后使用 cherry-pick 命令将该函数添加到当前分支。
$ git cherry-pick d003b91
  1. 验证 max 函数 :运行以下命令查看当前分支的日志,确认 max 函数已被合并到分支中。
$ git log cpick --oneline

在浏览器中打开或刷新 calc.html 文件,验证 max 函数是否可用。点击两个数字输入字段之间的下拉菜单,确保 max 作为可用操作出现。
8. 使用变基引入 exp min 函数 :从日志中找到 exp 函数的 SHA1 值,使用 rebase 命令将 exp min 函数合并到当前分支。

$ git rebase 3753e5a
  1. 验证变基结果 :运行以下命令查看当前分支的日志,确认历史记录已更新。在浏览器中打开 calc.html 文件,验证 exp min 函数是否可用( exp 函数显示为 “**”)。
$ git log --oneline
$ <start|open> calc.html
  1. 合并到主分支 :将 cpick 分支合并到 master 分支。
$ git checkout master
$ git merge cpick
  1. 推送到远程仓库 :将合并后的更改推送到远程仓库。
$ git push
  1. 切换到模拟用户二的目录 :模拟用户一的操作完成后,切换到 calc2 目录,模拟用户二的操作。
$ cd ../calc2
  1. 创建本地 ui 分支 :用户二要将 origin/ui 分支的 UI 工作合并到 master 分支。首先,创建一个本地 ui 分支,跟踪远程 ui 分支。
$ git branch ui origin/ui
  1. 合并 ui 分支到 master 分支 :将 ui 分支合并到 master 分支。
$ git merge ui
  1. 推送到远程仓库 :将合并后的更改推送到远程仓库。
$ git push origin master
  1. 处理推送被拒绝的情况 :由于用户一之前的推送更改了相同的提交,Git 无法进行快进合并,因此拒绝了用户二的推送。我们可以尝试 Git 建议的操作,先拉取远程仓库的更新,看是否可以干净地合并。
$ git pull origin master
  1. 处理合并冲突 :拉取更新后,可能会出现合并冲突。我们可以选择手动编辑文件解决冲突,也可以使用合并策略强制选择一个版本。这里我们选择使用变基来解决冲突。首先,中止当前的合并操作。
$ git merge --abort
  1. 获取更新内容 :使用 fetch 命令获取远程仓库的更新内容,但不进行本地合并。
$ git fetch
  1. 执行变基操作 :尝试执行变基操作,将本地分支基于远程 master 分支进行变基。
$ git rebase origin/master
  1. 处理变基冲突 :变基过程中可能会再次出现冲突。由于添加功能和更改 UI 功能的更改不同,我们可以选择保留当前更改,应用其他更改。使用 -Xours 选项告诉 Git 在冲突时保留我们的更改。
$ git rebase --abort
$ git rebase -Xours origin/master
  1. 验证变基结果 :运行以下命令查看当前分支的日志,确认提交记录是否正确。
$ git log --oneline
  1. 再次推送到远程仓库 :将处理后的更改推送到远程仓库。
$ git push
工作树(Worktrees)

Git 在 2.5 版本正式引入了工作树功能,允许我们同时在多个独立的工作目录中处理不同的分支,而无需频繁切换分支或创建多个克隆。

工作树命令语法
git worktree add [-f] [--detach] [-b <new-branch>] <path> [<branch>]
git worktree list [--porcelain]
git worktree prune [-n] [-v] [--expire <expire>]

工作树命令有三个子命令: add list prune 。任何选项都必须在子命令之后使用。

添加工作树

使用 add 子命令可以为特定分支添加一个新的工作树。

$ git worktree add <path> [<branch>]

例如,我们有一个项目有一个 docs 分支,我们想在一个名为 tmparea 的独立目录中处理该分支,可以使用以下命令:

$ git worktree add ../tmparea docs

如果要在另一个目录中处理同一个分支,默认会报错。可以使用 --force 选项强制添加。

$ git worktree add --force ../tmparea2 docs

还可以基于现有分支创建一个新的分支,并在新的工作树中处理该分支。

$ git worktree add -b fixdocs ../tmparea3 docs

如果不指定分支名称,工作树命令会创建一个与目标目录同名的新分支,基于主工作树的当前分支。

$ git worktree add ../tmparea5

如果想在分离头指针模式下工作,可以使用 --detach 选项。

$ git worktree add --detach ../tmparea6
列出工作树

使用 list 子命令可以列出当前仓库中所有活动的工作树的详细信息。

$ git worktree list

使用 --porcelain 选项可以以更详细的格式列出工作树信息,方便脚本处理。

$ git worktree list --porcelain
修剪工作树

使用 prune 子命令可以删除工作树信息,但需要先手动删除实际的工作树子目录。

$ rm -rf ../tmparea6
$ git worktree prune

prune 子命令有两个简单的选项:
- -n (--dry-run) :告诉 Git 不执行操作,只解释会做什么。

$ rm -rf ../tmparea4
$ git worktree prune -n
  • -v (--verbose) :让 Git 更详细地解释正在做什么。
$ git worktree prune -v
子模块(Submodules)

子模块允许我们在一个项目中包含另一个 Git 仓库作为子项目。这在包含项目依赖时非常有用。

子模块的基本概念

子模块是原仓库的一个子目录,包含另一个 Git 仓库的克隆。原仓库在其 Git 目录中存储有关子目录和仓库的元数据,以及克隆中的当前提交信息。原仓库也被称为超级项目。

子模块命令语法
git submodule [--quiet] add [-b <branch>] [-f|--force] [--name <name>]
              [--reference <repository>] [--depth <depth>] [--] <repository> [<path>]
git submodule [--quiet] status [--cached] [--recursive] [--] [<path>...​]
git submodule [--quiet] init [--] [<path>...​]
git submodule [--quiet] deinit [-f|--force] [--] <path>...​
git submodule [--quiet] update [--init] [--remote] [-N|--no-fetch]     
              [-f|--force] [--rebase|--merge] [--reference <repository>]
              [--depth <depth>] [--recursive] [--] [<path>...​]
git submodule [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]
              [commit] [--] [<path>...​]
git submodule [--quiet] foreach [--recursive] <command>
git submodule [--quiet] sync [--recursive] [--] [<path>...​]
子模块的管理

子模块不会在超级项目更新时自动更新。我们可以使用子模块命令更直接地管理子模块。Git 在仓库根目录创建并管理一个 .gitmodules 文件,用于跟踪子模块信息。该文件的条目格式如下:

[submodule <name>]
       path = <relative path>
       url = <url for cloning, updating, etc.>

需要注意的是,子模块与远程仓库不同。远程仓库是同一仓库的服务器端或公共副本,而子模块是我们想要使用或包含作为依赖的其他仓库。

通过以上步骤,我们可以模拟多人协作修改远程仓库,处理可能出现的冲突,并使用工作树和子模块更高效地管理项目。这些功能可以帮助我们更好地应对复杂的项目开发需求。

子模块的使用示例

为了更好地理解子模块的使用,下面通过一个简单的示例来演示如何添加、更新和管理子模块。

添加子模块

假设我们有一个主项目 main_project ,现在要将另一个 Git 仓库 sub_repo 作为子模块添加到主项目中。

# 进入主项目目录
$ cd main_project
# 添加子模块
$ git submodule add https://github.com/user/sub_repo sub_repo_path

执行上述命令后,Git 会在 main_project 中创建一个名为 sub_repo_path 的子目录,并将 sub_repo 仓库克隆到该目录下。同时,会在 .gitmodules 文件中添加子模块的相关信息。

初始化和更新子模块

当克隆一个包含子模块的项目时,子模块目录是空的,需要进行初始化和更新操作。

# 克隆包含子模块的项目
$ git clone https://github.com/user/main_project
$ cd main_project
# 初始化子模块
$ git submodule init
# 更新子模块
$ git submodule update

上述操作会将子模块的代码拉取到本地。

更新子模块

如果子模块的远程仓库有更新,我们可以使用以下命令来更新子模块。

# 进入子模块目录
$ cd sub_repo_path
# 拉取子模块的最新代码
$ git pull
# 返回主项目目录
$ cd ..
# 提交主项目中对子模块的更新引用
$ git add sub_repo_path
$ git commit -m "Update submodule"
$ git push

通过以上步骤,我们可以确保主项目引用的子模块是最新版本。

删除子模块

如果不再需要某个子模块,可以按照以下步骤删除它。

# 停止跟踪子模块
$ git submodule deinit sub_repo_path
# 删除子模块目录
$ rm -rf sub_repo_path
# 从 Git 索引中删除子模块记录
$ git rm sub_repo_path
# 提交删除操作
$ git commit -m "Remove submodule"
$ git push

多人协作中使用子模块的注意事项

在多人协作的项目中使用子模块时,需要注意以下几点:
1. 同步子模块信息 :每个开发者在克隆项目后,都需要执行 git submodule init git submodule update 来初始化和更新子模块。
2. 更新子模块引用 :当子模块有更新时,开发者需要在主项目中提交对子模块的更新引用,确保其他开发者可以获取到最新的子模块版本。
3. 避免冲突 :由于子模块的更新可能会导致主项目中的引用发生变化,因此在合并代码时需要特别注意,避免出现冲突。

总结

本文详细介绍了如何模拟多人协作修改远程仓库,处理可能出现的冲突,并使用工作树和子模块更高效地管理项目。具体内容如下:
1. 模拟多人协作修改远程仓库 :通过两个模拟用户的操作,展示了如何引入新功能、合并分支、处理推送被拒绝和合并冲突等情况。
2. 工作树(Worktrees) :允许同时在多个独立的工作目录中处理不同的分支,提高了开发效率。
3. 子模块(Submodules) :可以在一个项目中包含另一个 Git 仓库作为子项目,方便管理项目依赖。

通过合理使用这些功能,我们可以更好地应对复杂的项目开发需求,提高团队协作效率。

流程图总结

以下是模拟多人协作修改远程仓库的流程图:

graph TD;
    A[开始] --> B[用户一操作];
    B --> C[切换到 calc_other 目录];
    C --> D[查看计算器现有功能];
    D --> E[创建本地 features 分支];
    E --> F[查看可用功能];
    F --> G[创建临时分支 cpick];
    G --> H[引入 max 函数];
    H --> I[验证 max 函数];
    I --> J[使用变基引入 exp 和 min 函数];
    J --> K[验证变基结果];
    K --> L[合并到主分支];
    L --> M[推送到远程仓库];
    M --> N[用户二操作];
    N --> O[切换到 calc2 目录];
    O --> P[创建本地 ui 分支];
    P --> Q[合并 ui 分支到 master 分支];
    Q --> R[推送到远程仓库];
    R --> S[处理推送被拒绝];
    S --> T[处理合并冲突];
    T --> U[获取更新内容];
    U --> V[执行变基操作];
    V --> W[处理变基冲突];
    W --> X[验证变基结果];
    X --> Y[再次推送到远程仓库];
    Y --> Z[结束];

以下是子模块使用的流程图:

graph TD;
    A[开始] --> B[添加子模块];
    B --> C[初始化和更新子模块];
    C --> D[更新子模块];
    D --> E[提交主项目对子模块的更新引用];
    E --> F[删除子模块];
    F --> G[结束];

表格总结

功能 操作命令 说明
模拟用户一操作 cd calc_other 切换到模拟用户一的目录
git branch features origin/features 创建本地 features 分支
git checkout -b cpick 创建临时分支 cpick
git cherry-pick d003b91 引入 max 函数
git rebase 3753e5a 使用变基引入 exp 和 min 函数
git merge cpick 合并到主分支
git push 推送到远程仓库
模拟用户二操作 cd ../calc2 切换到模拟用户二的目录
git branch ui origin/ui 创建本地 ui 分支
git merge ui 合并 ui 分支到 master 分支
git push origin master 推送到远程仓库
处理冲突 git pull origin master 拉取远程仓库更新
git merge --abort 中止合并操作
git fetch 获取更新内容
git rebase origin/master 执行变基操作
git rebase -Xours origin/master 处理变基冲突
工作树 git worktree add <path> [<branch>] 添加工作树
git worktree list 列出工作树
git worktree prune 修剪工作树
子模块 git submodule add <repository> [<path>] 添加子模块
git submodule init 初始化子模块
git submodule update 更新子模块
git submodule deinit <path> 停止跟踪子模块
git rm <path> 从 Git 索引中删除子模块记录

通过以上的总结,我们可以更清晰地了解各个功能的操作步骤和注意事项,在实际开发中更好地运用这些技术。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值