以前在学校提交作业时使用过Git这个工具,感觉自己的使用没有发挥出它的全部优势,所以最近利用假期时间认真学习了一下Git。
Git的分布式特性和回滚、分支等操作十分实用,特此记录下Git学习过程。
Git
Git介绍
官网中对Git的介绍
- Git 是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目。
- Git 易于学习,占地面积小,性能极快。 它具有廉价的本地库,方便的暂存区域和多个工作流分支等特性。 其性能优于 Subversion、 CVS、 Perforce 和 ClearCase 等版本控制工具。
版本控制介绍
-
版本控制是一种记录文件内容变化,以便将来查阅特定版本修订情况的系统。
-
版本控制其实最重要的是可以记录文件修改历史记录,从而让用户能够查看历史版本,方便版本切换。
-
版本控制有利于从个人开发过渡到团队协作。
分布式版本控制VS集中式版本控制
集中式版本控制工具
集中化的版本控制系统诸如 CVS、 SVN 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。多年以来,这已成为版本控制系统的标准做法。
这种做法带来了许多好处,每个人都可以在一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松掌控每个开发者的权限,并且管理一个集中化的版本控制系统, 要远比在各个客户端上维护本地数据库来得轻松容易。
事分两面,有好有坏。这么做显而易见的缺点是中央服务器的单点故障。如果服务器宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。
分布式版本控制工具
像 Git 这种分布式版本控制工具,客户端提取的不是最新版本的文件快照,而是把代码仓库完整地镜像下来(本地库)。这样任何一处协同工作用的文件发生故障,事后都可以用其他客户端的本地仓库进行恢复。因为每个客户端的每一次文件提取操作,实际上都是一次对整个文件仓库的完整备份。
分布式的版本控制系统出现之后,解决了集中式版本控制系统的缺陷:
- 服务器断网的情况下也可以进行开发(因为版本控制是在本地进行的)
- 每个客户端保存的也都是整个完整的项目(包含历史记录, 更加安全)
Git的发展历史
工作机制和代码托管中心
工作机制
代码托管中心
代码托管中心是基于网络服务器的远程代码仓库,一般我们简单称为远程库。
- 局域网
- GitLab
- 互联网
- GitHub(外网)
- Gitee 码云(国内网站)
Git安装
在Git下载页面,选择下载Windows 64位版的Git安装软件。
安装步骤按照安装软件的安装向导安装即可,无需过多配置。
安装成功后,通常在文件浏览器空白处单击击鼠标右键,弹出菜单栏有Git的选项。
Git命令
设置用户签名
|
|
说明:签名的作用是区分不同操作者身份。用户的签名信息在每一个版本的提交信息中能够看到,以此确认本次提交是谁做的。 Git 首次安装必须设置一下用户签名,否则无法提交代码。
tips: 这里设置的用户名和将来登录 GitHub(或其他代码托管中心)的账号没有任何关系。
查看用户签名
|
|
即查看系统盘/用户/.gitconfig文件
初始化本地库
|
|
即在当前目录下创建了一个名为.git的非空隐藏文件夹。
查看本地库状态
|
|
添加暂存区
|
|
提交本地库
|
|
查看提交记录
|
|
git log
命令可以显示所有提交过的版本信息,如果感觉太繁琐,可以加上参数 --pretty=oneline
,只会显示版本号和提交时的备注信息。
git reflog
显示所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作)
版本穿梭
|
|
tips: 版本穿梭,底层其实是移动HEAD指针
Git分支
什么是分支
在版本控制过程中,若同时推进多个任务。我们就可以为每个任务创建单独分支。使用分支意味着程序员可以把自己的工作从开发主线上分离开来, 开发自己分支的时候,不会影响主线分支的运行。分支可以简单理解为副本,一个分支就是一个单独的副本。(分支底层其实也是指针的引用)
分支的优点
- 可以同时并行推进多个功能开发,提高开发效率。
- 各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任何影响。失败的分支删除重新开始即可。
查看分支
|
|
创建分支
|
|
tips:创建的新分支相当于将主分支的内容复制了一份
切换分支
|
|
分支合并
|
|
首先要切换到master分支上,然后在master分支上合并hot-fix分支
合并冲突(merge conflict)
- 原因:合并分支时,两个分支在同一个文件的同一个位置有两套完全不同的修改。 Git 无法替我们决定使用哪一个,因此,必须人为决定新代码内容。
- 解决:编辑有冲突的文件,删除特殊符号,决定要使用的内容
创建和切换分支的实质
master、 hot-fix 其实都是指向具体版本记录的指针。当前所在的分支,其实是由 HEAD决定的。所以创建分支的本质就是多创建一个指针。
-
HEAD 如果指向 master,那么我们现在就在 master 分支上。
-
HEAD 如果执行 hot-fix,那么我们现在就在 hot-fix 分支上。
所以切换分支的本质就是移动 HEAD 指针。
Github
创建远程库
登陆后,点击“New repository”,创建远程库
创建远程库的别名
|
|
推送本地库到远程库
|
|
在提交代码前最好先更新下远程仓库的代码到本地仓库,这样可以减少不必要的冲突
拉取远程库到本地
|
|
克隆远程库到本地
|
|
clone所做操作:
- 拉取代码(pull)
- 初始化本地仓库(init)
- 创建别名(remote add)
团队内协作和跨团队协作
团队内协作
选择目标
发送网址
接受邀请
跨团队协作
发送网址
收到网址
Fork项目
pull请求
合并请求
SSH免密登录
我们可以看到远程仓库中还有一个 SSH 的地址,因此我们也可以使用 SSH 进行访问。
- 先到用户的主页目录,删除.ssh文件夹(如果没有.ssh文件夹,忽略此步)
- 在用户的主页目录运行命令
ssh-keygen -t rsa -C 登录邮箱
后敲三次回车即可生成.ssh目录 - 复制.ssh/rsa.pub中的公钥并添加至Github账号SSH设置中
接下来便可使用SSH方式推送或拉取
IDEA集成Git
配置Git忽略文件
与项目的实际功能无关,不参与服务器上部署运行。把它们忽略掉能够屏蔽 IDE 工具之间的差异。例如,Maven工程根据src生成的target。
创建忽略规则文件 xxxx.ignore(前缀名随便起,建议是 git.ignore),这个文件的存放位置原则上在哪里都可以,为了便于让~/.gitconfig 文件引用,建议也放在用户家目录下。
git.ignore 文件模版内容如下:
|
|
在.gitconfig 文件中引用忽略配置文件(此文件在 Windows 的家目录中)
|
|
注意:这里要使用“正斜线(/)”,不要使用“反斜线(\)”
在idea配置Git程序
在菜单栏File->Setting->搜索栏搜Git,配置Git的安装路径。
初始化Git
在菜单栏VCS -> Import into Version Control -> Create Git Repository
选择要创建 Git 本地仓库的工程,然后OK。
添加到暂存区
右键点击文件,选择Git->Add,添加文件到暂存区。
添加成功后,文件名会从红色变成绿色。
提交到本地库
右键点击文件,选择Git->Commit File
添加日志信息后提交
版本穿梭
在IDEA 的左下角,点击 Git,然后点击 Log 查看版本
右键选择要切换的版本,然后在菜单里点击 Checkout Revision。
创建分支
右键点击文件,Git -> Repository -> Branches,或者点击IDEA的右下角,如图红圈所示部位:
选择点击New Branch:
创建新分支:
切换分支
跟创建分支步骤相似,如点击IDEA的右下角(它显示项目正处在那条分支),如图红圈所示部位,选择你想要切换的分支,然后checkout:
或者在log窗口,右键点击分支,选择checkout:
合并分支
点击IDEA 窗口的右下角的master,将 hot-fix 分支合并到当前 master 分支。选择hot-fix->Merge into Current
如果代码没有冲突, 分支直接合并成功,分支合并成功以后,代码自动提交,无需手动提交本地库。
合并冲突
冲突产生,需要人工解决:
代码冲突解决,将代码提交本地库后,如图所示:
设置Github账号
在菜单栏File->Setting->搜索栏搜GitHub,添加GitHub账号:
分享项目到Github
推送代码到远程库
拉取远程库代码合并到本地库
克隆代码到本地
在菜单栏的File->Close Project->Get from Version Control
或者在菜单栏VCS->Get from Version Control
Gitee
码云简介
众所周知, GitHub 服务器在国外, 使用 GitHub 作为项目托管网站,如果网速不好的话,严重影响使用体验,甚至会出现登录不上的情况。针对这个情况, 大家也可以使用国内的项目托管网站-码云。
码云是开源中国推出的基于 Git 的代码托管服务中心, 网址是 https://gitee.com/ ,使用方式跟 GitHub 一样,而且它还是一个中文网站,如果你英文不是很好,它是最好的选择。
创建远程库
可以从GitHub与GitLab中导入仓库
IDEA集成Gitee
首先,要在IDEA安装Gitee插件。
在菜单栏选File->Settings->Plugins,搜Gitee。
安装插件成功后,重启IDEA。
功能跟在IDEA的Github插件,功能类似,如添加Gitee账号等,可参考前文IDEA的Github插件,触类旁通。

Git命令总结
命令名称 | 作用 |
---|---|
安装与配置 | |
sudo apt-get install git | Ubuntu上安装Git |
git config –global user.name 用户名 | 设置用户名(安装Git后必须设置) |
git config –global user.email 邮箱 | 设置邮箱地址(安装Git后必须设置) |
获取与创建项目 | |
git init | 初始化本地库 |
git clone 远程库地址 | 从远程库克隆到本地 |
基本快照 | |
git status | 查看本地库状态 |
git add 文件名 | 添加到暂存区 |
git restore –staged 文件名 | 复位在暂存区的文件(add的反悔) |
git rm –cached 文件名 | 移除在暂存区的文件(add的反悔) |
git commit -m “备注文本” 文件名 | 提交暂存区文件到本地库(文件名缺省时,将暂存区所有文件提交) |
git commit –amend | 修改上次提交的备注文本 |
git revert 版本号(7位) | 撤销指定的提交(commit的反悔) |
git reset –hard 版本号(7位) | 版本穿梭(配合git reflog使用) |
git reset –hard HEAD^ | 穿梭到上一个版本 |
分支与合并 | |
git branch | 列出所有分支 |
git branch 分支名 | 创建分支 |
git checkout 分支名 | 切换分支 |
git merge 分支名B | 分支B合并到当前所处分支 |
git branch -d 分支名 | 删除分支 |
git tag | 列出所有本地标签 |
git tag -l 通配模式文本(*) | 根据符合通配模式文本,列出所有本地标签 |
git tag 标签名 | 为最新提交创建轻量标签 |
git tag 标签名 版本号(7位) | 为对应版本号提交创建轻量标签(在后期打标签) |
git tag -a 标签名 -m 备注文本 | 为最新提交创建附注标签 |
git tag -d 标签名 | 删除指定标签 |
共享与更新项目 | |
git remote add 别名 远程仓库地址 | 添加远程库 |
git remote -v | 查看添加过的远程库 |
git push 远程库地址或其别名 分支名 | 推送到远程库 |
git push 远程库地址或其别名 –tags | 推送所有标签到远程库 |
git fetch | 将远程库的最新内容拉到本地 |
git pull 远程库地址或其别名 分支名 | 将远程仓库对于分支最新内容拉下来后与当前本地分支直接合并, 相当于git fetch + git merge,这样可能会产生冲突,需要手动解决 |
检查与比较 | |
git show 标签名 | 显示标签信息和与之对应的提交信息 |
git show 版本号(7位) | 显示对应版本对应的提交信息 |
git log | 显示当前分支所有提交过的版本信息 |
git log –follow 文件名 | 显示当前分支所有提交过的关于指定文件版本信息 |
git log –pretty=oneline | 显示当前分支所有提交过的版本信息(精简) |
git log –graph | 显示当前分支所有提交过的版本信息(附有分支合并图) |
git diff 分支一 分支二 | 显示两分支差异 |
git diff 版本号一(7位) 版本号二(7位) | 显示同一分支两版本差异 |
管理 | |
git reflog | 可以查看所有分支的所有操作记录 (包括已被删除的commit记录和reset的操作) |
commit提交规范
conventional-commits: The conventional commits specification
git提交信息一定要很清晰地表达出本次提交的主要内容,一般不要一次性提交太多代码,一次提交更多只是提交一个功能点,或者一个bug修复
关于提交规范有一个比较好的实践:约定式提交,定义提交信息包含几个部分
|
|
提交类型包括:
feat(功能)
:添加了新的功能或特性- 示例:
git commit -m "feat: add search functionality"
- 示例:
fix(修复)
:修复了某个bug
- 示例:
git commit -m "fix: resolve null pointer exception"
- 示例:
chore(日常任务)
:完成了日常的维护任务,如更新依赖库、改进构建过程、工具配置等- 示例:
git commit -m "chore: update dependencies to latest version"
- 示例:
docs(文档)
:更新了项目的文档,例如修改 README 文件、API 文档等- 示例:
git commit -m "docs: update API documentation"
- 示例:
style(样式)
:代码样式的变更,如格式化代码、修正缩进、空格、空行等,例如修改代码结构、变量名、函数名等但没有影响代码逻辑- 示例:
git commit -m "style: reformat code to follow coding standards"
- 示例:
refactor(重构)
:对代码进行了重构,优化了代码结构或清理了代码,但没有添加新功能或修复 bug- 示例:
git commit -m "refactor: optimize data processing logic"
- 示例:
test(测试)
:添加或更新了测试用例- 示例:
git commit -m "test: add unit tests for login module"
- 示例:
perf(性能)
:优化了代码的性能、减少内存占用等- 示例:
git commit -m "perf: improve query performance by adding indexes"
- 示例:
build(构建)
:更改了构建系统或外部依赖项,例如修改依赖库、外部接口或者升级 Node 版本等- 示例:
git commit -m "build: configure webpack for better code splitting"
- 示例:
ci(持续集成)
:更新了持续集成流程和脚本,例如修改 Travis、Jenkins 等工作流配置- 示例:
git commit -m "ci: setup continuous deployment with Travis"
- 示例:
revert(回退)
:回退了之前的提交- 示例:
git commit -m "revert: revert commit 0a12345"
- 示例:
规范提交PR
找项目 (Finding projects)
这个很简单,确定目标项目,这里是:
https://github.com/leerob/leerob.iogithub.com/leerob/leerob.io
友情提示: \1. 做开源贡献之前,可以先看看 issue 和 PR 中,有没有人已经提出过与你观点相同和相近的反馈意见或修改提交。注意作者是怎么回复的,避免浪费自己时间。
如果是一些小问题,而且自己时间有限,可以先提一个 issue,提醒作者本人或者其他人解决,如果没有人回应,再尝试自己提交 PR。这里我先提了一个 issue,https://github.com/leerob/leerob.io/issues/550
派生一个存储库 (Forking a repository)
进入 https://github.com/leerob/leerob.io 项目主页,点击 Fork
按钮,创建一个新的派生项目(Create a new fork)
再点击 Create fork
按钮,创建派生项目到自己的工作区。
克隆一个派生 (Cloning a fork)
进入自己的 Github 工作区,将派生项目克隆到本地(或者远端服务器),详见 https://docs.github.com/en/get-started/quickstart/contributing-to-projects
|
|
创建一个分支 (Creating a branch)
|
|
做出修改 (Make changes)
删除一行无用的代码,import Link from 'next/link'
提交修改 (Pushing changes)
这步需要注意一下,有些项目更新的会比较频繁。当你做出修改和提交 PR 之前,可能有作者新的提交和 PR 被合并到原项目。如果有这种情况发生,在你工作区的派生项目会显示原项目有更新。例如:
点击 Update branch
之后,将原项目(https://github.com/leerob/leerob.io)更新同步到派生项目(https://github.com/shenlu89/leerob.io)。再进入本地项目文件夹
|
|
查看更新后的内容是否和本地修改有冲突,有冲突就解决冲突,完成后就可以提交修改了
|
|
创建合并请求 (Create a pull request)
回到线上派生项目的工作区,会看到新分支和修改的合并提交信息,点击**Compare & pull request
**
选择你想并入的原项目分支,标题和描述信息。如果有对应的 issue,就通过键入 #
添加(Github 会自动展示 issues 列表)
点击 Create pull request
,就行了。不出意外,你提的 PR 就应该躺在下面了:
发表评论 (Address review comments)
这部分是原项目作者需要遵循的规范,Lee Robinson 也给了一个礼貌性的回复
合并你的请求 (Merge your pull request)
这是原项目作者要做的,已经展示过了,不再赘述。
删除你的分支 (Delete your branch)
最后一步不是必须的,只是保持一个规范的开源协作习惯,减少意外提交错误项目分支的情况发生。
来到原项目 Github 主页,找到之前已经合并的提交请求(在关闭的 PR 列表中),点击 Delete branch
|
|
注意:下次在已有的派生项目创建新分支前,要先将原项目的更新同步到派生项目,并将更新后的派生项目拉到(
git pull
)本地,再重新建立分支(git checkout -b new-branch-name
),再重复上述过程即可。
Github 官网对协作流程方面写很清楚,但阐述逻辑上有点混乱,而且没有中文版。有人可能会问,GitHub Docs 提供多语言访问,而且是开源的,为什么中文版有些部分没有翻译完整?详见https://github.com/github/docs/blob/main/contributing/types-of-contributions.md#earth_asia-translations 如下:
所以,GitHub Docs 其他语言的官方翻译会滞后于英文版,因为其他语言版本不接受内容贡献(这是 Github 官方在准确度和效率之间做的一个平衡)。如果 GitHub Docs 中没有提供符合你阅读习惯的语言版本,只能发信催 Github 官方尽快提供相关语言版本。实在不行,用 ChatGPT 帮忙翻译一下。
避坑提醒: 1. 给 GitHub Docs 提交内容翻译 PR 通常是不会通过的。这里官方说的很清楚了,不接受翻译内容贡献。 2. 如果发现英文原文内容有问题(语法,语义,词法),这个是可以提交修改意见 (Issue) 和合并请求 (Pull Request) 的(其他语言的版本也都是通过英文版本翻译过来的)。但也要基于原文内容修改,自己独立创作的内容合并请求很难被 Github 官方通过。
下面是参考的相关 Github 官方文档: