网站首页 > 技术文章 正文
块的问题
然而使用子模块还是有一些小问题。
切换分支
例如,使用 Git 2.13 以前的版本时,在有子模块的项目中切换分支可能会造成麻烦。 如果你创建一个新分支,在其中添加一个子模块,之后切换到没有该子模块的分支上时,你仍然会有一个还未跟踪的子模块目录。
$ git --version
git version 2.12.2
$ git checkout -b add-crypto
Switched to a new branch 'add-crypto'
$ git submodule add https://github.com/chaconinc/CryptoLibrary
Cloning into 'CryptoLibrary'...
...
$ git commit -am 'adding crypto library'
[add-crypto 4445836] adding crypto library
2 files changed, 4 insertions(+)
create mode 160000 CryptoLibrary
$ git checkout master
warning: unable to rmdir CryptoLibrary: Directory not empty
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
CryptoLibrary/
nothing added to commit but untracked files present (use "git add" to track)
移除那个目录并不困难,但是有一个目录在那儿会让人有一点困惑。 如果你移除它然后切换回有那个子模块的分支,需要运行 submodule update --init 来重新建立和填充。
$ git clean -fdx
Removing CryptoLibrary/
$ git checkout add-crypto
Switched to branch 'add-crypto'
$ ls CryptoLibrary/
$ git submodule update --init
Submodule path 'CryptoLibrary': checked out 'b8dda6aa182ea4464f3f3264b11e0268545172af'
$ ls CryptoLibrary/
Makefile includes scripts src
再说一遍,这真的不难,只是会让人有点儿困惑。
新版的 Git(>= 2.13)通过为 git checkout 命令添加 --recurse-submodules 选项简化了所有这些步骤, 它能为了我们要切换到的分支让子模块处于的正确状态。
$ git --version
git version 2.13.3
$ git checkout -b add-crypto
Switched to a new branch 'add-crypto'
$ git submodule add https://github.com/chaconinc/CryptoLibrary
Cloning into 'CryptoLibrary'...
...
$ git commit -am 'adding crypto library'
[add-crypto 4445836] adding crypto library
2 files changed, 4 insertions(+)
create mode 160000 CryptoLibrary
$ git checkout --recurse-submodules master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
当你在父级项目的几个分支上工作时,对 git checkout 使用 --recurse-submodules 选项也很有用, 它能让你的子模块处于不同的提交上。确实,如果你在记录了子模块的不同提交的分支上切换, 那么在执行 git status 后子模块会显示为“已修改”并指出“新的提交”。 这是因为子模块的状态默认不会在切换分支时保留。
这点非常让人困惑,因此当你的项目中拥有子模块时,可以总是使用 git checkout --recurse-submodules。 (对于没有 --recurse-submodules 选项的旧版 Git,在检出之后可使用 git submodule update --init --recursive 来让子模块处于正确的状态)。
幸运的是,你可以通过 git config submodule.recurse true 设置 submodule.recurse 选项, 告诉 Git(>=2.14)总是使用 --recurse-submodules。 如上所述,这也会让 Git 为每个拥有 --recurse-submodules 选项的命令(除了 git clone) 总是递归地在子模块中执行。
从子目录切换到子模块
另一个主要的告诫是许多人遇到了将子目录转换为子模块的问题。 如果你在项目中已经跟踪了一些文件,然后想要将它们移动到一个子模块中,那么请务必小心,否则 Git 会对你发脾气。 假设项目内有一些文件在子目录中,你想要将其转换为一个子模块。 如果删除子目录然后运行 submodule add,Git 会朝你大喊:
$ rm -Rf CryptoLibrary/
$ git submodule add https://github.com/chaconinc/CryptoLibrary
'CryptoLibrary' already exists in the index
你必须要先取消暂存 CryptoLibrary 目录。 然后才可以添加子模块:
$ git rm -r CryptoLibrary
$ git submodule add https://github.com/chaconinc/CryptoLibrary
Cloning into 'CryptoLibrary'...
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Unpacking objects: 100% (11/11), done.
Checking connectivity... done.
现在假设你在一个分支下做了这样的工作。 如果尝试切换回的分支中那些文件还在子目录而非子模块中时——你会得到这个错误:
$ git checkout master
error: The following untracked working tree files would be overwritten by checkout:
CryptoLibrary/Makefile
CryptoLibrary/includes/crypto.h
...
Please move or remove them before you can switch branches.
Aborting
你可以通过 checkout -f 来强制切换,但是要小心,如果其中还有未保存的修改,这个命令会把它们覆盖掉。
$ git checkout -f master
warning: unable to rmdir CryptoLibrary: Directory not empty
Switched to branch 'master'
当你切换回来之后,因为某些原因你得到了一个空的 CryptoLibrary 目录,并且 git submodule update 也无法修复它。 你需要进入到子模块目录中运行 git checkout . 来找回所有的文件。 你也可以通过 submodule foreach 脚本来为多个子模块运行它。
要特别注意的是,近来子模块会将它们的所有 Git 数据保存在顶级项目的 .git 目录中,所以不像旧版本的 Git,摧毁一个子模块目录并不会丢失任何提交或分支。
拥有了这些工具,使用子模块会成为可以在几个相关但却分离的项目上同时开发的相当简单有效的方法。
猜你喜欢
- 2024-10-07 如何编写gitignore文件(git怎么用)
- 2024-10-07 用git管理版本,你必须知道的事情
- 2024-10-07 详解Github的.gitignore忽略文件+.gitignore不生效解决+生产配置
- 2024-10-07 Git数据迁移:迁移代码到新仓库(git版本库迁移)
- 2024-10-07 收藏就行了:最全git总结(gitjournal)
- 2024-10-07 程序员必须掌握版本控制的工具 --- git(一)
- 2024-10-07 Github怎么上传超过100M的大文件?
- 2024-10-07 Git最全总结(git ci)
- 2024-10-07 Git使用的小技巧(git的使用超详细版教程)
- 2024-10-07 解决.gitignore不起作用的办法(gitbush)
- 1517℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 594℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 521℃MySQL service启动脚本浅析(r12笔记第59天)
- 489℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 489℃启用MySQL查询缓存(mysql8.0查询缓存)
- 477℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 456℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 454℃MySQL server PID file could not be found!失败
- 最近发表
-
- PS所有滤镜的说明(六)(ps滤镜详解)
- 5款小白也能用的在线图片编辑器!电商效率飙升就靠它!
- Java变量(java变量有什么作用)
- Java面试常见问题:Java注解(java中的面试题)
- Java编程入门第一课:HelloWorld(java编程从入门到实践)
- Java基础教程:Java继承概述(java里继承的概述)
- java基础之——访问修饰符(private/default/protected/public)
- 如何规划一个合理的JAVA项目工程结构
- 将机器指令翻译成 JavaScript -- 终极目标
- Web 服务器基准测试:Go vs. Node.js vs. Nim vs. Bun
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)