git 分支、标签、子仓库、自建远程托管仓库相关简单介绍
Git 的分支功能可以支持同时进行多个功能的开发和版本管理,多分支用于多人同时开发不同功能,在各自的平行空间写代码,互不干扰,最终合并。标签用于给特定提交打上不可变的版本标记(如 v1.0.0),记录项目的里程碑。子仓库用于在当前项目中嵌入另一个独立的 Git 仓库,实现公共代码的隔离与复用。
分支
查看分支情况
1 | # 查看当前分支和本地分支 |
创建本地分支
1 | # 创建本地分支 |
合并分支
使用如下命令合并分支,如果目前是在 main 分支,首先需要切换到 production 分支,然后再合并 main 分支到 production 分支
1 | git checkout production |
除了 merge 命令外,还有一种命令可以合并分支,那就是 rebase,更多内容可以查看:分支的合并
删除分支
1 | # 删除本地分支 |
注意:删除远程分支不使用 git branch -d,而是使用 git push origin --delete 命令
但是,当远程仓库没有该分支时,或者在本地使用 git branch -r 能够看到远程仓库名,但远程仓库却已经不存在时,使用上面删除远程分支,会出现如下错误:
1 | error: unable to delete 'xxx': remote ref does not exist |
这时候需要我们更新本地仓库的远程仓库列表信息,命令如下:
1 | git fetch --prune |
推送分支
1 | # production 表示本地分支 |
远程仓库信息查看
当从远程仓库克隆后,git 默认远程仓库名为 origin,并将远程的 main 分支与本地的 main 分支对应。查看远程仓库名称使用如下命令:
1 | git remote |
git remote -v 将显示更多信息,不仅有远程仓库名称,还有 fetch 和 push 的远程仓库地址。当没有 push 权限时,将不显示 push 地址。
多分支管理的一个例子
假设维护两个分支,一个是 main 分支,进行迭代开发,一个是production 分支,当 main 分支测试稳定后合并到 production 分支进行发布部署生产。
已知 main 分支已经进行了一轮迭代开发,测试稳定,需要投入到生产发布。接下来就是要进行 production 生产分支创建与推送。
首次创建并推送 production 分支(仅需做一次)
1 | # 1. 确保当前在 main 分支,且代码是最新的 |
日常迭代:代码稳定后同步到 production
以你一直留在本地 main 分支上开发。当 main 分支的代码再次开发测试稳定、准备上生产环境时,执行下面的四部日常发布命令:
1 | # 1. 切换到本地 production 分支 |
多人协作开发提交的例子
当克隆远程仓库到本地,一般是 main 分支或产品版本分支,该分支是主分支,时刻与远程仓库同步;除此之外,开发人员在本地还会创建 dev 分支、bug 分支和 feature 分支。其中 dev 分支是开发分支,团队开发人员开发分支,重大版本迭代时 merge 到主分支,一般也需要时刻与远程 dev 分支同步;bug 分支是本地修复 bug 的分支,一般不进行远程同步;feature 分支同步取决于团队需要。该小节可参考:多人协作
leader 或首位开发者在本地 main 分支外使用如下命令创建了 dev分支,并提交到远程 origin 仓库
1
2
3
4
5# 在本地创建 dev 分支,并切换到 dev 分支,进行开发
git checkout -b dev
# 推送本地 dev 分支到远程仓库 origin,并同时在远程仓库origin 创建 dev 分支
git push origin dev第二位开发人员首先克隆远程开发仓库到本地,然后在本地增加远程 origin/dev 分支到本地 dev 分支
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24# 克隆远程 origin 仓库到本地机器
git clone jinzhongxu@1.14.1.14:/home/jinzhongxu/monkey.git
# 查看分支情况,特别是远程,发现远程仓库 origin 除了有 main 分支,还有分支 origin/dev
git branch -a
//* main
// remotes/origin/HEAD -> origin/main
// remotes/origin/dev
// remotes/origin/main
# 将远程仓库 origin 的 dev 分支增加到本地,并切换到本地 dev 分支
git checkout -b dev origin/dev
# 查看本地分支信息
git branch
//* dev
// main
# 该开发人员进行了本地开发,并在 dev 分支增加部分代码,然后提交到远程仓库 origin 的 dev 分支
git status
git add .
git commit -m "repair bug"
git status
git push origin dev:dev第三位开发人员也同样和第二位开发人员一样,下载了远程仓库 origin 的 main 分支和 dev 分支,并同时进行开发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52克隆远程 origin 仓库到本地机器
git clone jinzhongxu@1.14.1.14:/home/jinzhongxu/monkey.git
查看分支情况,特别是远程,发现远程仓库 origin 除了有 main 分支,还有分支 origin/dev
git branch -a
//* main
// remotes/origin/HEAD -> origin/main
// remotes/origin/dev
// remotes/origin/main
将远程仓库 origin 的 dev 分支增加到本地,并切换到本地 dev分支
git checkout -b dev origin/dev
查看本地分支信息
git branch
//* dev
// main
该开发人员进行了本地开发,并在 dev 分支增加部分代码,然后提交到远程仓库 origin 的 dev 分支
git status
git add .
git commit -m "repair bug"
git status
但是,使用如下命令在提交时出现问题
git push origin dev:dev
// To 1.14.1.14:/home/jinzhongxu/monkey.git
// ! [rejected] dev -> dev (fetch first)
// error: failed to push some refs to 'jinzhongxu@1.14.1.14:/home/jinzhongxu/monkey.git'
// hint: Updates were rejected because the remote contains work that you do
// hint: not have locally. This is usually caused by another repository pushing
// hint: to the same ref. You may want to first integrate the remote changes
// hint: (e.g., 'git pull ...') before pushing again.
// hint: See the 'Note about fast-forwards' in 'git push --help' for details.
上面的错误提示很明白,那就是团队中已经有人提交的最新更新到远程 dev 分支,需要先 git pull,然后再 git push,使用如下命令解决
git pull # 如果失败,可能的原因是没有指定本地dev分支与远程origin/dev分支的链接,可使用右边命令设置dev和origin/dev的链接:git branch --set-upstream-to=origin/dev dev
成功后,出现如下提示,就是需要手动修改冲突,然后,再 git push
// remote: Counting objects: 5, done.
// remote: Compressing objects: 100% (3/3), done.
// remote: Total 3 (delta 1), reused 0 (delta 0)
// Unpacking objects: 100% (3/3), done.
// From 1.14.1.14:/home/jinzhongxu/monkey
// 4461cc8..7056c16 dev -> origin/dev
// Auto-merging main.py
// CONFLICT (content): Merge conflict in main.py
// Automatic merge failed; fix conflicts and then commit the result.
git status
git add main.py
git commit -m "repair bugs for xlabel and ylabel"
git push origin dev前面三个过程,特别是 2 和 3,是公司开发时常遇到,并且经常这样的迭代进行。特别是 3,我们要经常使用,要熟练掌握。
推送时忽略某些文件或文件夹
在仓库主目录下,编写
1 | vim .gitignore |
添加忽略的(或包含的)文件、文件夹。这里以 hexo 部署博客为例:
1 | .DS_Store |
如果出现 !db.json 即表示提交时包含 db.json.
标签
添加标签
首先运行如下命令,查看commit id,
1 | git log |
运行如下命令添加标签
1 | git tag v1.0.0 c584a15bd2 |
其中,v1.0.0 为标签,版本号,c584a15bd2 为 commit id,只要唯一即可。
查看本地标签
1 | git tag -n |
推送本地标签
1 | # 推送单个指定标签 |
删除本地标签
1 | git tag -d <tagname> |
删除远程仓库标签
1 | # 1. 先删除本地标签 |
自建 git 托管服务器
这里以 Ubuntu 为例。
首先,需要有一个 vps 服务器,假设 IP 地址是 1.14.1.14
其次,在服务器上增加用户和组,比如添加 jinzhongxu 用户
1 | adduser jinzhongxu |
然后,安装 git 命令
1 | sudo apt update && sudo apt install git |
最后,建立远程仓库
1 | git init --bare monkey.git |
把远程仓库克隆到本地
1 | git clone jinzhongxu@1.14.1.14:/home/jinzhongxu/monkey.git |
更改远程仓库的 URL
当远程仓库 IP 地址更改、SSH 和 HTTPS 切换等其他导致远程仓库的 URL 地址发生改变时,需要切换地址,才能够正确提交本地修改的代码等内容上传到远程仓库。
更改远程仓库的 URL 需要使用命令:git remote set-url
git remote set-url 命令使用两个参数:
现有远程仓库的名称。 例如
origin。一般有源仓库或上游仓库是两种常见选择。远程仓库的新 URL。 例如:
如果您要更新为使用 HTTPS,您的 URL 可能如下所示:
1
https://github.com/USERNAME/REPOSITORY.git
如果您要更新为使用 SSH,您的 URL 可能如下所示:
1
git@github.com:USERNAME/REPOSITORY.git
将远程 URL 从 SSH 切换到 HTTPS
打开 Terminal(终端)。
将当前工作目录更改为您的本地仓库。
列出现有远程仓库以获取要更改的远程仓库的名称。
1
2
3git remote -v
origin git@github.com:USERNAME/REPOSITORY.git (fetch)
origin git@github.com:USERNAME/REPOSITORY.git (push)使用
git remote set-url:命令将远程的 URL 从 SSH 更改为 HTTPS。
1
git remote set-url origin https://github.com/USERNAME/REPOSITORY.git
验证远程 URL 是否已更改。
1
2
3
4git remote -v
Verify new remote URL
origin https://github.com/USERNAME/REPOSITORY.git (fetch)
origin https://github.com/USERNAME/REPOSITORY.git (push)
下次对远程仓库执行 git fetch、git pull 或 git push 操作时,您需要提供 GitHub 用户名和密码。 When Git prompts you for your password, enter your personal access token (PAT) instead. Password-based authentication for Git is deprecated, and using a PAT is more secure. For more information, see “Creating a personal access token.”
You can use a credential helper so Git will remember your GitHub username and personal access token every time it talks to GitHub.
将远程 URL 从 HTTPS 切换到 SSH
打开 Terminal(终端)。
将当前工作目录更改为您的本地仓库。
列出现有远程仓库以获取要更改的远程仓库的名称。
1
2
3git remote -v
origin https://github.com/USERNAME/REPOSITORY.git (fetch)
origin https://github.com/USERNAME/REPOSITORY.git (push)使用
git remote set-url:命令将远程的 URL 从 HTTPS 更改为 SSH。
1
git remote set-url origin git@github.com:USERNAME/REPOSITORY.git
验证远程 URL 是否已更改。
1
2
3
4git remote -v
Verify new remote URL
origin git@github.com:USERNAME/REPOSITORY.git (fetch)
origin git@github.com:USERNAME/REPOSITORY.git (push)
更改远程仓库地址的方法还有另一种方法,那就是先删除已有远程仓库地址,然后再添加新的远程仓库地址:
1 | # 1. 删除旧的 origin 关联 |
为仓库添加子模块(子仓库)
当项目开发中遇到需要引用其他子仓库作为一个包时,可以将其作为子模块添加到现有项目中。
添加子模块
在该项目中添加子模块依赖,如 vendor、common 包。这里也 vendor 为例。
1 | git submodule add https://gitlab.mathscv.com/jinzhongxu/sub-repo.git vendor |
此时,主项目根目录下会自动生成一个 .gitmodules 文件,用来记录子模块的路径与仓库映射关系。其实,在当前项目的 .git/config 中也会有子模块信息。
提交并推送到主项目远程仓库:
1 | git add .gitmodules vendor |
子模块的修改单独进行推送。
克隆主项目
当添加子模块后,主项目的推送和克隆中子模块都是一个地址引用。对于新克隆,如果相应同时克隆子模块代码,那么需要执行下面命令:
1 | git clone https://gitlab.mathscv.com/jinzhongxu/main-repo.git |
更新子模块地址
当子模块的地址更改(导入内网 gogs 托管平台,或者使用其他更强大的同名子模块)后,可以采用如下的方法更新子模块地址。
修改配置文件
打开主项目根目录下的 .gitmodules 文件,找到对应子模块的 url 属性,将其修改为全新的远程仓库地址。
1 | [submodule "vendor"] |
同步配置到 Git 内部
运行以下命令,将 .gitmodules 中的新地址同步到 Git 的本地全局配置(.git/config)中:
1 | git submodule sync |
更新子模块的缓存(可选但推荐)
如果子模块已经被克隆到了本地,为了确保其内部的 .git 目录也指向新地址,请进入子模块目录并更新它的远程源:
1 | git submodule update --init --recursive --remote |
提交变更
将配置文件的修改提交并推送到主项目的远程仓库,以便团队其他成员可以同步:
1 | git add .gitmodules |
团队协同注意事项
当团队其他成员拉取(git pull)主项目的最新代码后,他们本地的子模块地址不会自动生效。他们需要在主项目根目录执行以下两行命令来激活新地址:
1 | git submodule sync |










