Git : 分支管理和远程仓库
Git : 分支管理和远程仓库
- 一、分支管理
- 理解分支
- 创建分支 / git branch
- 切换分支 / git checkout
- 在 dev 分支上开发
- 分支切换效果
- 合并分支 / git merge
- 删除分支
- 合并冲突
- 示例
- 创建并切换分支
- master 上的修改
- 发生冲突
- 手动解决冲突并提交
- 合并模式
- 1. Fast Forward 模式
- 2. 非 Fast Forward 模式(--no-ff)
- 演示:
- ✅总结
- 分支管理策略
- 1. 基本原则
- 2. 工作流
- Bug 修复与分支管理
- 1. 场景
- 2. 解决方案:使用 `git stash`
- 3. 修复 bug 流程
- 4. 回到 `dev2` 分支继续开发
- 5. 同步 bug 修复到 `dev2`
- 6. ✅总结
- 强制删除分支
- 1. 场景
- 2. 创建 feature 分支并开发
- 3. 删除 feature 分支遇到的问题
- 4. 强制删除 feature 分支
- ✅ 总结
- 二、远程操作
- 理解分布式版本控制系统
- 远程仓库
- 创建远程仓库
- 初始化仓库选项介绍
- 设置模板选项介绍
- 选择分支模型
- 克隆远程仓库
- 使用 HTTPS 方式克隆
- 使用 SSH 方式克隆
- 第一步:创建 SSH Key
- 第二步:添加公钥到远程仓库
- 查看远程仓库信息
- 向远程仓库推送
- 新建文件
- 推送到远程仓库
- 拉取远程仓库
- 命令格式
- 配置 Git 忽略文件
- 为什么需要忽略文件?
- 使用 .gitignore
- 特殊情况
- 总结
- 三、Git 命令配置别名
- 1. 为什么要用别名?
- 2. 配置示例
- 3. 常见的别名推荐(可选)
- 四、标签管理
- 1. 什么是标签(Tag)?
- 2. 创建标签
- (1) 在最新提交上打标签
- (2) 在指定 commit 上打标签
- 3. 查看标签信息
- 4. 创建带说明的标签
- 5. 操作标签
- (1) 删除本地标签
- (2) 推送标签到远程
- (3) 删除远程标签
- 6. 小结
一、分支管理
理解分支
Git 的杀手级功能之一就是 分支。
分支就像科幻电影里的 平行宇宙:
-
在一个宇宙中,你正在学习 C++;
-
在另一个宇宙中,你正在学习 Java。
如果两个宇宙互不干扰,那对你没有影响;但如果在某个时刻它们合并了,那么结果就是:你既学会了 C++,又学会了 Java!
提交与分支的关系
在 版本回退 中,我们知道:
-
每次提交,Git 都会把它们串成一条时间线;
-
这条时间线就是一个 分支。
截止目前,只有一条时间线,这个分支叫 主分支,即 master
分支。
HEAD 与 master
-
HEAD 严格来说不是指向提交,而是指向 master;
-
master 才是指向某个提交的;
-
因此,HEAD 指向的就是当前分支。
每次提交时:
-
master 分支会向前移动一步;
-
随着不断提交,master 的线越来越长;
-
而 HEAD 始终跟随 master,就能定位到最新提交。
查看当前分支指向
通过查看 Git 仓库内部文件,可以更清楚理解:
# 查看 HEAD
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat .git/HEAD
ref: refs/heads/master
# 查看 master 指向的提交 ID
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat .git/refs/heads/master
fbeb09e0dd8481c9c0c7b93915a57b81187366d1
说明:
.git/HEAD 指向 refs/heads/master;
master 文件里保存着当前分支指向的提交哈希值。
创建分支 / git branch
Git 支持查看或创建分支。
- 查看当前本地所有分支:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git branch
* master
- 创建新分支
dev
:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git branch dev
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git branchdev
* master
此时,Git 新建了一个指针 dev,但 HEAD 依旧指向 master。
- 查看目录结构可以发现新分支:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ ls .git/refs/heads/
dev master
- 两个分支初始时指向同一个提交:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat .git/refs/heads/*
fbeb09e0dd8481c9c0c7b93915a57b81187366d1
fbeb09e0dd8481c9c0c7b93915a57b81187366d1
切换分支 / git checkout
- 切换到
dev
分支:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git checkout dev
M ReadMe
Switched to branch 'dev'
- 查看当前分支:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git branch
* devmaster
- 此时 HEAD 已指向 dev:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat .git/HEAD
ref: refs/heads/dev
在 dev 分支上开发
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat ReadMe
hello git
hello git
hello world
write something for new branch
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git add .
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git commit -m "modify ReadMe"
[dev 9ab19bf] modify ReadMe1 file changed, 2 insertions(+)
分支切换效果
- 切换回
master
分支:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git checkout master
Switched to branch 'master'
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat ReadMe
hello git
hello git
- 在
dev
分支上的修改在master
中不可见,这是因为两者指向的提交不同:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat .git/refs/heads/dev
9ab19bf18de8b64001aa27b0a3ea23f06f90c54f[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat .git/refs/heads/master
fbeb09e0dd8481c9c0c7b93915a57b81187366d1
合并分支 / git merge
为了让 master
拥有 dev
的提交,需要执行合并。
- 切换到
master
:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git checkout master
Already on 'master'
- 合并
dev
分支:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git merge dev
Updating fbeb09e..9ab19bf
Fast-forwardReadMe | 2 ++1 file changed, 2 insertions(+)[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat ReadMe
hello git
hello git
hello world
write something for new branch
此时 master 分支已经包含了 dev 的修改。
- Fast-forward(快进模式):
直接将 master 指针移动到 dev 当前提交,因此合并非常快。
删除分支
当某个功能分支合并到主分支后,该功能分支通常就没用了,可以删除掉。
- 注意:不能在当前分支下删除自己,比如:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git checkout dev
Switched to branch 'dev'
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git branch -d dev
error: Cannot delete the branch 'dev' which you are currently on.
- 要删除分支,需要先切换到其他分支,例如:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git checkout master
Switched to branch 'master'
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git branch -d dev
Deleted branch dev (was 9ab19bf).
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git branch
* master
此时分支 dev 已被成功删除。
由于 Git 中创建、合并和删除分支都非常快,所以 Git 鼓励使用分支进行开发,在分支上完成某个功能后再合并到主分支,然后删除分支。
这样做和直接在 master 上开发效果一样,但过程更加安全。
合并冲突
在分支合并时,并不是每次都能顺利合并成功,有时会遇到 代码冲突 的情况。
示例
创建并切换分支
- 使用
git checkout -b <branch>
可以一步完成 创建并切换:
git checkout -b dev1
- 切换后在 dev1 下修改 ReadMe 文件,并且提交 ,例如:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat ReadMe
hello git
hello git
hello world
write bbb for new branch // 将 aaa 改成 bbb[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git add .
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git commit -m " modify ReadMe"
[dev1 b4db7a9] modify ReadMe1 file changed, 1 insertion(+), 1 deletion(-)
master 上的修改
切回 master 分支,在 master 分支上修改同一行,并提交:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git checkout master
Switched to branch 'master'
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ vim ReadMe
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat ReadMe
hello git
hello git
hello world
write ccc for new branch
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git add .
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git commit -m "modify ReadMe"
[master cf1af53] modify ReadMe1 file changed, 1 insertion(+), 1 deletion(-)
发生冲突
- 当我们尝试合并
dev1
分支时:
这种情况下,Git只能试图把各字的修改合并起来,但这种合并就可能会有冲突
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git merge dev1
Auto-merging ReadMe
CONFLICT (content): Merge conflict in ReadMe
Automatic merge failed; fix conflicts and then commit the result.[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git status
# On branch master
# You have unmerged paths.
# (fix conflicts and run "git commit")
#
# Unmerged paths:
# (use "git add <file>..." to mark resolution)
#
# both modified: ReadMe
#
no changes added to commit (use "git add" and/or "git commit -a")
- 查看冲突内容:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat ReadMe
hello git
hello git
hello world
<<<<<<< HEAD
write ccc for new branch
=======
write bbb for new branch
>>>>>>> dev1
手动解决冲突并提交
- 手动调整后内容如下,并再次提交:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ cat ReadMe
hello git
hello git
hello world
write bbb for new branch
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git add .
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git commit -m "merge ReadMe"
[master d01c986] merge ReadMe
- 查看合并历史:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git log --graph --pretty=oneline --abbrev-commit
* d01c986 merge ReadMe
|\
| * 435faa3 modify ReadMe
* | 30e26a5 modify ReadMe
|/
* 045e91a modify readme
- 删除已用完的分支:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git branch -d dev1
Deleted branch dev1 (was 435faa3).
合并模式
1. Fast Forward 模式
-
Git 在合并分支时,如果可能,会采用 Fast forward 模式。
-
特点:
- 合并后不会产生新的提交(commit)。
- 删除分支后,查看历史时,看不出来该提交是来自合并,还是普通提交。
示例:Fast forward 合并后
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git log --graph --abbrev
* commit d8710e0f1d6dbcea000dd0f5f7e7c3c6c8074be0
| Author: R.L <2512485314@qq.com>
| Date: Mon Sep 15 16:59:35 2025 +0800
|
| modify ReadMe
|
* commit 5a0f0d154f8e4f3141cafc002f4aa804e40b00de
| Author: R.L <2512485314@qq.com>
| Date: Mon Sep 15 16:58:33 2025 +0800
|
| modify ReadMe
|
* commit 57655210b0201b29ed402a8a25080156777ee346
- 历史记录中无法清晰看出分支被合并的痕迹。
- 但在合并冲突部分,我们也看到通过解决冲突问题,会再进行一次新的提交,得到的最终状态为:
那么这就不是 Fast forward
模式了,这样的好处是,从分⽀历史上就可以看出分⽀信息
2. 非 Fast Forward 模式(–no-ff)
-
在合并冲突并解决后,Git 会产生一次新的提交,这种情况 不是 Fast forward。
-
好处:
-
历史中可以清晰看出分支合并的痕迹。
-
即使删除分支,也能从历史中看出 master 是由其他分支合并而来。
-
禁用 Fast forward 的方式
- 使用
--no-ff
参数:
git merge --no-ff -m "" [分支]
--no-ff 表示禁用 Fast forward 模式。
-m 用于添加合并提交的说明。
演示:
- 创建并切换分支,修改并提交
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git checkout -b dev2
Switched to a new branch 'dev2'
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ echo "write ddd for new branch" >> ReadMe
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git add .
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git commit -m "modify ReadMe"
[dev2 07244a7] modify ReadMe1 file changed, 1 insertion(+)
- 回到 master 并合并,合并结果
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git checkout master
Switched to branch 'master'
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git merge --no-ff -m "merge with no-ff" dev2
Merge made by the 'recursive' strategy.ReadMe | 1 +1 file changed, 1 insertion(+)
[xrw@iZ7xv0vjzfc2mzsasssfooZ git_practice]$ git log --graph --pretty=oneline --abbrev-commit
* 5765521 merge with no-ff
|\
| * 07244a7 modify ReadMe
|/
* d01c986 merge ReadMe
✅总结
-
Fast forward 模式
-
不产生新提交。
-
历史记录无法看出分支合并痕迹。
-
-
–no-ff 模式
-
会生成新的提交。
-
历史记录清晰保留合并轨迹,便于理解项目演进过程。
-
分支管理策略
1. 基本原则
-
master 分支
-
非常稳定,用于 发布新版本。
-
平时不能直接在上面开发。
-
-
dev 分支
-
用于日常开发,不稳定。
-
当需要发布版本(如 v1.0)时,将 dev 合并到 master。
-
-
个人开发分支
-
每个开发者从 dev 分支拉取自己的功能分支(feature/xxx)。
-
功能开发完成后,合并回 dev 分支。
-
2. 工作流
-
日常开发:大家在各自的功能分支上开发。
-
合并流程:
-
功能分支 → dev
-
dev → master(发布版本时)
-
✅ 这样一来,整个团队的分工就非常清晰:
-
master
永远稳定 → 只发布。 -
dev
用于团队开发整合。 -
feature/*
分支用于个人开发。
Bug 修复与分支管理
1. 场景
-
当前在
dev2
分支上开发,代码未完成(工作区有修改,未提交)。 -
突然发现 master 分支有 bug 需要紧急修复。
-
问题:
dev2
上的代码还没写完,不能提交。
2. 解决方案:使用 git stash
git stash
可以临时保存工作区和暂存区的修改,保持当前分支干净。
git stash # 保存当前未提交的修改
git stash list # 查看保存的列表
git stash pop # 恢复并删除 stash
git stash apply # 恢复但不删除 stash
git stash drop # 删除 stash
3. 修复 bug 流程
① 储藏当前开发进度
git stash
git status # 工作区干净了
② 切换到 master,新建 bug 分支
git checkout master
git checkout -b fix_bug
③ 在fix_bug分支中修改、提交 bug 修复
vim ReadMe
git add ReadMe
git commit -m "fix bug"
④ 合并回 master 并删除 bug 分支
git checkout master
git merge --no-ff -m "merge fix_bug branch" fix_bug
git branch -d fix_bug
4. 回到 dev2
分支继续开发
① 切换回 dev2
git checkout dev2
git stash pop # 恢复之前的开发进度
② 继续开发并提交
vim ReadMe
git add .
git commit -m "modify ReadMe"
5. 同步 bug 修复到 dev2
此时,dev2
没有 master 上的 bug 修复提交,需要把 master 合并进来。
① 合并 master 到 dev2
git merge master
# 如果有冲突,手动解决
git add .
git commit -m "merge master"
② 再让 master 合并 dev2
(无冲突)
git checkout master
git merge dev2 # 通常 fast-forward
git branch -d dev2
6. ✅总结
-
遇到 bug 修复优先级高 → 使用临时分支 fix_bug。
-
当前分支未完成的开发 → 用 git stash 暂存现场。
-
bug 修复完成后 → 合并回 master,并删除临时分支。
-
继续开发 → 回到原分支,恢复 stash,继续写代码。
-
避免在 master 上直接解决冲突 → 先在自己的分支里合并 master,解决冲突并测试,再合并回 master。
强制删除分支
1. 场景
-
软件开发中,功能不断添加,每个新功能建议 在独立分支开发(feature 分支)。
-
功能完成后 → 合并回主分支 → 删除 feature 分支。
-
如果功能被临时叫停,即使开发了一半,也需要销毁该 feature 分支。
2. 创建 feature 分支并开发
# 新建并切换到 dev3 分支
git checkout -b dev3# 修改代码并提交
vim ReadMe
git add .
git commit -m "modify ReadMe for new features"
3. 删除 feature 分支遇到的问题
① 切回 master 分支
git checkout master
② 尝试常规删除
git branch -d dev3结果:error: The branch 'dev3' is not fully merged.
If you are sure you want to delete it, run 'git branch -D dev3'.
原因:dev3 上的提交尚未合并到 master,-d 参数要求分支必须完全合并才能删除。
4. 强制删除 feature 分支
git branch -D dev3
- -D = 强制删除,不管是否合并。
删除后查看分支列表:git branch
# 结果:
* master
✅ 总结
-
常规删除
-d
:只能删除已合并分支。 -
强制删除
-D
:可以删除未合并的分支,用于中止开发的 feature 分支。 -
使用强制删除时要小心,未合并的提交将丢失(除非通过 reflog 恢复)。
二、远程操作
理解分布式版本控制系统
- Git 是分布式版本控制系统
-
我们之前讨论的 工作区、暂存区、版本库,都是在 本地(电脑上)。
-
Git 是 分布式版本控制系统(DVCS),每个开发者的电脑上都有完整的版本库。
优点
-
离线工作:本地就有完整版本库,不需要联网也能提交、查看历史、回滚等。
-
安全性高:即使一台电脑坏掉,也可以从其他人的版本库恢复。
- 多人协作
-
情景:你在电脑上修改了文件 A,你的同事也修改了文件 A。
-
解决方法:各自把修改 推送(push) 给对方,就可以同步修改。
-
分布式特点:每个人都可以独立提交,历史完整。
- 中央服务器的作用
-
虽然 Git 是分布式,但通常会有一个“中央服务器”(如 GitHub/GitLab)。
-
作用:
-
方便交换修改:开发者之间通过 push/pull 与中央服务器同步。
-
备份作用:本地电脑出故障时,可以从中央服务器恢复。
-
-
注意:中央服务器只是为了方便协作和备份,本地完全可以独立工作。
远程仓库
创建远程仓库
初始化仓库选项介绍
- 选择语言
-
语言选项只是 为了初始化一些与语言相关的模板文件(如 .gitignore),并不会改变 Git 的核心功能。
-
如果你已有本地项目,也可以不选语言,手动添加 .gitignore 和其他文件。
- 添加
.gitinore
-
作用: 创建一个 .gitignore 文件,用于告诉 Git 哪些文件或目录不需要被版本控制。
-
好处:
-
可以避免提交不必要的文件,例如编译生成的二进制文件、日志文件或 IDE 配置文件。
-
平台会根据你选择的开发语言或框架提供模板(例如 Python、Node、Java 等)。
-
- 添加许可证
-
作用: 给项目添加一个开源许可证文件,例如 MIT、Apache 2.0、GPL 等。
-
好处:
-
明确规定他人对你的代码使用权限。
-
对开源项目非常重要,避免版权纠纷。
-
设置模板选项介绍
Readme
文件
-
用途: 为仓库提供说明文档。
-
作用:
-
第一次打开仓库时,显示仓库简介、使用说明、项目目标等内容。
-
对其他开发者或用户了解项目很重要。
-
可以写成 Markdown 格式,支持格式化文本、代码块、图片等。
-
Issue
模板文件
-
用途: 给仓库的问题(Issue)创建 规范模板。
-
作用:
-
当有人在仓库中提交问题(bug、功能请求等)时,会自动加载模板。
-
模板可以包含必填字段,例如问题描述、复现步骤、环境信息等。
-
有助于团队统一收集信息,提高问题处理效率。
-
Pull Request
模板文件
-
用途: 为 Pull Request(PR) 创建 规范模板。
-
作用:
-
当有人提交代码合并请求时,会显示模板。
-
模板可以包含提交目的、改动内容、测试说明等字段。
-
方便团队评审代码、确认改动是否符合规范、避免遗漏信息。
-
选择分支模型
- 单分支模型(只创建 master 分支)
-
特点:
-
仓库只会有一个主分支 master。
-
所有开发、修复、上线操作都在 master 上进行。
-
-
适用场景:
-
项目很小,只有一个开发人员或者小团队。
-
不需要复杂的版本管理。
-
-
优点:
- 简单易用,入门门槛低。
-
缺点:
-
不利于多人协作和并行开发。
-
容易在 master 上产生不稳定代码。
-
- 主干开发模型(Trunk-based Development / main/master + dev 分支)
-
特点:
-
仓库默认有 master(或 main)分支,以及一个 develop 分支。
-
日常开发在 develop 分支进行,稳定后再合并到 master。
-
-
适用场景:
-
小到中型团队。
-
需要区分“开发版本”和“生产版本”。
-
-
优点:
-
master 分支保持稳定,可随时部署上线。
-
团队协作更有条理。
-
-
缺点:
- 分支管理稍复杂,需要团队遵守流程。
- Git Flow 模型(包含 feature/release/hotfix 分支)
-
特点:
-
仓库默认创建 master、develop,以及用于功能开发、发布、修复的分支模板:
-
feature/xxx:新功能开发。
-
release/xxx:准备发布。
-
hotfix/xxx:线上紧急修复。
-
-
-
适用场景:
-
中大型团队,复杂项目。
-
多环境并行开发,要求版本严格管理。
-
-
优点:
-
支持多人协作、并行开发。
-
清晰的分支管理,便于发布和修复。
-
-
缺点:
-
学习成本高,流程复杂。
-
小团队可能觉得过度设计。
-
克隆远程仓库
克隆/下载远程仓库到本地,需要使用 git clone
命令,后面跟上远程仓库的链接。远程仓库的链接可以从仓库中找到:选择“克隆/下载”获取远程仓库链接。
Git 最常用的数据传输协议有两种:SSH 和 HTTPS。
- SSH 协议:使用公钥加密和公钥登录机制,安全可靠。使用此协议需要将公钥上传到服务器,由 Git 服务器管理。
- HTTPS 协议:不需要额外配置,可以直接克隆。
使用 HTTPS 方式克隆
直接克隆即可
git clone https://gitee.com/rxrw/server.git
使用 SSH 方式克隆
当我直接克隆时:
[xrw@iZ7xv0vjzfc2mzsasssfooZ Test]$ git clone git@gitee.com:rxrw/server.git
Cloning into 'server'...
The authenticity of host 'gitee.com (180.76.199.13)' can't be established.
ECDSA key fingerprint is SHA256:FQGC9Kn/eye1W8icdBgrQp+KkGYoFgbVr17bmjey0Wc.
ECDSA key fingerprint is MD5:27:e5:d3:f7:2a:9e:eb:6c:93:cd:1f:c1:47:a3:54:b1.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'gitee.com,180.76.199.13' (ECDSA) to the list of known hosts.
Permission denied (publickey).
fatal: Could not read from remote repository.Please make sure you have the correct access rights
and the repository exists.
由于没有添加公钥到远程库,服务器拒绝了 clone 操作。需要进行以下设置:
第一步:创建 SSH Key
-
检查用户主目录下是否有 .ssh 目录,以及是否已有
id_rsa
和id_rsa.pub
文件。 -
如果没有,创建 SSH Key:
[xrw@iZ7xv0vjzfc2mzsasssfooZ .ssh]$ ssh-keygen -t rsa -C "2512485314@qq.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/xrw/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/xrw/.ssh/id_rsa.
Your public key has been saved in /home/xrw/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:R0W66+FaAn1L4ZMUuQzf46vJ1U8ncW3Evv6JApW/cUY 2512485314@qq.com
The key's randomart image is:
+---[RSA 2048]----+
| .oo |
| . .+ . |
| +=o. o|
| . ++*o E.|
| . S X...o =|
| . = +.+ *.|
| . * ..B.o|
| * =..o+o|
| ..*... o+|
+----[SHA256]-----+
- 完成后,可在 .ssh 目录下找到密钥对:
[xrw@iZ7xv0vjzfc2mzsasssfooZ ~]$ ls -a .ssh/
. .. id_rsa id_rsa.pub known_hosts
-
id_rsa
:私钥,不能泄露 -
id_rsa.pub
:公钥,可上传到远程仓库
第二步:添加公钥到远程仓库
-
登录 Gitee/GitHub,找到 SSH 公钥 设置,添加
id_rsa.pub
公钥。 -
完成认证后,即可成功使用 SSH 克隆仓库:
[xrw@iZ7xv0vjzfc2mzsasssfooZ Test]$ git clone git@gitee.com:rxrw/server.git
Cloning into 'server'...
Warning: Permanently added the ECDSA host key for IP address '180.76.198.77' to the list of known hosts.
remote: Enumerating objects: 49, done.
remote: Counting objects: 100% (49/49), done.
remote: Compressing objects: 100% (47/47), done.
remote: Total 49 (delta 5), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (49/49), 145.03 KiB | 5.00 KiB/s, done.
Resolving deltas: 100% (5/5), done.
成功!如果有多人协作开发,可以添加多个公钥,每个人都可以在各自电脑上向远程仓库推送代码。
查看远程仓库信息
克隆仓库后,本地的 master
分支会自动和远程 master
分支对应,远程仓库默认名称为 origin
。
[xrw@iZ7xv0vjzfc2mzsasssfooZ server]$ git remote
origin[xrw@iZ7xv0vjzfc2mzsasssfooZ server]$ git remote -v
origin git@gitee.com:rxrw/server.git (fetch)
origin git@gitee.com:rxrw/server.git (push)
-
fetch
:抓取远程更新 -
push
:向远程提交更新(需要权限)
向远程仓库推送
当本地已经 clone 成功远程仓库 后,就可以向远程仓库提交内容。
新建文件
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ ll
total 12
-rw-rw-r-- 1 xrw xrw 7 Sep 15 21:40 file.txt
-rw-rw-r-- 1 xrw xrw 956 Sep 15 21:37 README.en.md
-rw-rw-r-- 1 xrw xrw 1317 Sep 15 21:37 README.md[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git add .
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git commit -m "create file.txt"
[master ca67d82] create file.txt1 file changed, 1 insertion(+)create mode 100644 file.txt
⚠️ 注意:
-
如果之前设置过全局的 name 和 email,必须与 gitee 上配置的用户名和邮箱一致,否则会报错。
-
如果从未设置过,也会在第一次提交时报错,需要重新配置。
推送到远程仓库
提交到本地仓库后,需要使用 git push
将内容推送到远程仓库。
git push <远程主机名> <本地分支名>:<远程分支名>
如果 本地分支名与远程分支名相同,可以省略冒号部分:
git push <远程主机名> <本地分支名>
如下:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git push origin master
Username for 'https://gitee.com': rxrw
Password for 'https://rxrw@gitee.com':
fatal: Authentication failed for 'https://gitee.com/rxrw/git-practice.git/'
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git push origin master
Username for 'https://gitee.com': rxrw
Password for 'https://rxrw@gitee.com':
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 302 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [1.1.5]
remote: Set trace flag 6d418fb0
To https://gitee.com/rxrw/git-practice.gitf953e39..ca67d82 master -> master
协议差异
-
SSH 协议:推送时无需每次输入密码,更加方便。
-
HTTPS 协议:每次推送都必须输入口令,相对麻烦。
拉取远程仓库
在 gitee 上点击 file.txt
文件并在线修改它。
此时,远程仓库领先于本地仓库一个版本。为了使本地仓库保持最新版本,我们需要拉取远端代码,并合并到本地。
Git 提供了 git pull
命令,该命令用于从远程获取代码并合并到本地版本。
命令格式
git pull <远程主机名> <远程分支名>:<本地分支名>
如果远程分支是与当前分支合并,则冒号后面的部分可以省略:
git pull <远程主机名> <远程分支名>
示例:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git pull origin master
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), done.
From https://gitee.com/rxrw/git-practice* branch master -> FETCH_HEAD
Updating ca67d82..c8d2e57
Fast-forwardfile.txt | 3 ++-1 file changed, 2 insertions(+), 1 deletion(-)
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ cat file.txt
xxxxxxx
bbbbbbbbb
配置 Git 忽略文件
为什么需要忽略文件?
在日常开发中,有些文件我们不想或者不应该提交到远端,例如:
- 保存数据库密码的配置文件
- 编译生成的二进制文件
为了让 Git 自动忽略这些文件,我们需要在工作区的根目录下创建一个特殊的文件:
.gitignore
使用 .gitignore
Gitee 在创建仓库时可以帮我们自动生成 .gitignore
,只需勾选即可。
如果当时没有勾选,我们也可以自己创建。
示例:忽略所有以 .so
和 .ini
结尾的文件
# My configurations:
*.ini
*.so
.gitignore 文件本身也需要提交到远程,才能让团队协作时生效。
验证 .gitignore
新增两个文件 a.so
和 b.ini
:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ touch a.so b.ini
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# .gitignore
nothing added to commit but untracked files present (use "git add" to track)
特殊情况
(1) 强制添加被忽略的文件
有时你就是想把被忽略的文件添加进去,可以用 -f
参数强制添加:
git add -f [filename]
(2) 检查忽略规则
如果发现 .gitignore
写错了,可以用 git check-ignore
查看是哪一条规则导致的:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git check-ignore -v a.so
.gitignore:3:*.so a.so
👉 输出表示:.gitignore 文件第 3 行规则忽略了 a.so。
(3) 添加例外规则
例如,你想忽略所有以 . 开头的隐藏文件,但不想忽略 .gitignore 本身,可以这样写:
# 排除所有 . 开头的隐藏文件
.*# 但不排除 .gitignore
!.gitignore
总结
在 .gitignore
中:
-
普通规则表示“要忽略”
-
! 开头表示“例外”
三、Git 命令配置别名
1. 为什么要用别名?
在使用 Git 的过程中,有些命令太长、不方便记忆或输入。
幸运的是,Git 支持为命令配置 别名(alias),让常用命令更简洁。
2. 配置示例
将 git status
简化为 git st
git config --global alias.st status
-
–global 参数表示 全局配置,在当前电脑的所有 Git 仓库都生效。
-
如果不加 --global,则只在当前仓库生效。
验证:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git config alias.st status
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git st
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# .gitignore
nothing added to commit but untracked files present (use "git add" to track)
3. 常见的别名推荐(可选)
如果以后要用,可以考虑以下配置:
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.last "log -1"
这样输入就更简洁,例如:
-
git co -b new-feature
→ 创建并切换分支 -
git br
→ 查看分支 -
git ci -m "msg"
→ 提交 -
git st
→ 查看状态 -
git last
→ 查看最后一次提交
四、标签管理
1. 什么是标签(Tag)?
- 标签(tag)可以理解为 某次 commit 的一个别名。
- 常用于项目发布版本时,给特定提交打上有意义的标签,例如
v1.0
。 - 相比难以记忆的 commit id,标签更直观。
- 回退到某个版本时,用标签能快速定位。
2. 创建标签
(1) 在最新提交上打标签
切换到需要打标签的分支:
git branch
* master
创建标签:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git tag v1.0
查看所有标签:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git tag
v1.0
(2) 在指定 commit 上打标签
先查看历史提交:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git log --pretty=oneline --abbrev-commit
c8d2e57 update file.txt.
ca67d82 create file.txt
f953e39 Initial commit
在指定提交 f953e39
上打标签:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git tag v0.9 f953e39
再次查看标签:
[xrw@iZ7xv0vjzfc2mzsasssfooZ git-practice]$ git tag
v0.9
v1.0
注意:标签列表是按 字母排序,不是时间顺序。
3. 查看标签信息
git show v1.0
4. 创建带说明的标签
git tag -a v1.1 -m "Release version 1.1" [commit_id]
如果是给最新的commmit_id打标签那么也可以不带[commit_id]
-
-a
指定标签名 -
-m
添加说明文字
5. 操作标签
(1) 删除本地标签
git tag -d v0.9
(2) 推送标签到远程
git push origin v1.0
一次性推送所有标签:
git push origin --tags
(3) 删除远程标签
先删除本地标签:
git tag -d v1.0
再删除远程标签:
git push origin :v1.0
也可以
git push origin :refs/tags/v1.0
如果:
左边为空,意思就是“推送一个空的引用”,相当于删除远程的对应引用
-
分支在 .git/refs/heads/ 下,比如 refs/heads/master。
-
标签在 .git/refs/tags/ 下,比如 refs/tags/v1.0。
6. 小结
-
标签就是对 commit 的一个“快照别名”,常用于版本管理。
-
标签分为两种:
-
轻量标签:只有名字,指向某次提交。
-
附注标签:带有说明信息,更适合版本发布。
-
-
标签默认只存在于本地,需要手动推送到远程。
-
推错的标签可以安全删除,并且可以从远程移除。