1. Git 基础概念
1.1 什么是 Git
Git 是一个开源的分布式版本控制系统,是目前世界上最先进、最流行的版本控制系统。可以快速高效地处理 从很小到非常大的项目版本管理。 也就是说Git可以让你的代码有版本,你可以随时回退到某个版本。
特点:项目越大越复杂,协同开发者越多,越能体现出 Git 的高性能和高可用性!
1.2 Git 的特性
Git 之所以快速和高效,主要依赖于它的如下两个特性:
- 直接记录快照,而非差异比较
- 近乎所有操作都是本地执行
1.2.1 SVN 的差异比较
传统的版本控制系统(例如 SVN)是基于差异的版本控制,它们存储的是一组基本文件和每个文件随时间逐步累积的差异。
- 好处:节省磁盘空间
- 缺点:耗时、效率低 在每次切换版本的时候,都需要在基本文件的基础上,应用每个差异,从而生成目标版本对应的文件。
1.2.2 Git 的记录快照
Git 快照是在原有文件版本的基础上重新生成一份新的文件,类似于备份。为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。
- 缺点:占用磁盘空间较大
- 优点:版本切换时非常快,因为每个版本都是完整的文件快照,切换版本时直接恢复目标版本的快照即可。
- 特点:空间换时间
1.2.3 近乎所有操作都是本地执行
在 Git 中的绝大多数操作都只需要访问本地文件和资源,一般不 需要来自网络上其它计算机的信息。
特性:
- 断网后依旧可以在本地对项目进行版本管理
- 联网后,把本地修改的记录同步到云端服务器即可
- 服务器故障或损坏后,可使用任何一个客户端的备份进行恢复
1.3 Git 中的三个区域
使用 Git 管理的项目,拥有三个区域,分别是工作区、暂存区、Git 仓库。
1.4 Git 中的三种状态
注意:
- 工作区的文件被修改了,但还没有放到暂存区,就是已修改状态。
- 如果文件已修改并放入暂存区,就属于已暂存状态。
- 如果 Git 仓库中保存着特定版本的文件,就属于已提交状态
1.5 基本的 Git 工作流程
基本的 Git 工作流程如下:
- 在工作区中修改文件
- 将你想要下次提交的更改进行暂存
- 提交更新,找到暂存区的文件,将快照永久性 存储到 Git 仓库
1.6 杂谈:版本控制的进化
- 本地版本控制系统
- 集中化的版本控制系统
- 分布式版本控制系统
1.6.1 本地版本控制系统
特点: 使用软件来记录文件的不同版本,提高了工作效率, 降低了手动维护版本的出错率
缺点:
- 单机运行,不支持多人协作开发
- 版本数据库故障后,所有历史更新记录会丢失
1.6.2 集中化的版本控制系统
特点: 基于服务器、客户端的运行模式
- 服务器保存文件的所有更新记录 (差异)
- 客户端只保留最新的文件版本 优点: 联网运行,支持多人协作开发
缺点:
- 不支持离线提交版本更新
- 中心服务器崩溃后,所有人无法正常工作
- 版本数据库故障后,所有历史更新记录会丢失 典型代表:SVN
1.6.3 分布式版本控制系统
特点: 基于服务器、客户端的运行模式
- 服务器保存文件的所有更新版本 (文件快照/备份)
- 客户端是服务器的完整备份,并不是只保留文件的最新版本 优点:
- 联网运行,支持多人协作开发
- 客户端断网后支持离线本地提交版本更新
- 服务器故障或损坏后,可使用任何一个客户端的备份进行恢复 典型代表:Git
2. 安装并配置 Git
2.1 下载并安装 Git
在开始使用 Git 管理项目的版本之前,需要将它安装到计算机上。可以使用浏览器访问如下的网址,根据自己 的操作系统,选择下载对应的 Git 安装包: git-scm.com/downloads
注意git/cmder的操作:
git/cmder清屏:clear
git/cmder复制:鼠标左键选中
git粘贴:1. 点击鼠标右键,选择paste;2. 点击鼠标中键
cmder粘贴:点击鼠标右键
2.2 配置用户信息
安装完 Git 之后,要做的第一件事就是设置自己的用户名和邮件地址。因为通过 Git 对项目进行版本管理的时 候,Git 需要使用这些基本信息,来记录是谁对项目进行了操作:
git config --global user.name 你的英文名
git config --global user.email 你的邮箱
//下面四行一模一样,直接复制粘贴就行
git config --global push.default simple
git config --global core.quotepath false
git config --global core.editor "code --wait" //修改git默认的编辑器为 vscode,默认是vim
//git config --global core.editor vim 修改git默认的编辑器改回vim,本来vim就是默认的,不用运行这一句
git config --global core.autocrlf input
注意:如果使用了 --global 选项,那么该命令只需要运行一次,即可永久生效。
右击桌面,点击Git Bash Here,调处命令窗口
2.3 Git 的全局配置文件
通过 git config --global user.name 和 git config --global user.email 配置的用户名和邮箱地址,会被写 入到 C:/Users/用户名文件夹/.gitconfig 文件中。这个文件是 Git 的全局配置文件,配置一次即可永久生效。 可以使用记事本或者vscode打开此文件,从而查看自己曾经对 Git 做了哪些全局性的配置.
每个人的用户名是不同的,比如我的是:C:\Users\zgc99\.gitconfig
2.4 检查配置信息
除了使用记事本查看全局的配置信息之外,还可以运行如下的终端命令,快速的查看 Git 的全局配置信息:
右击桌面,点击Git Bash Here,调处命令窗口
//查看所有的全局配置项
git config --list --global
//查看指定的全局配置项
git config user.name
git config user.email
git config xxxxxxxxxx
2.5 获取帮助信息
可以使用 git help 命令,无需联网即可在浏览器中打开帮助手册,例如:
//想要打开 git config 命令的帮助手册
git help config
如果不想查看完整的手册,那么可以用 -h 选项获得更简明的“help”输出:
//想要获取 git config 命令的快速参考
git config -h
3. Git 的基本操作
3.1 获取 Git 仓库的两种方式
- 将尚未进行版本控制的本地目录转换为 Git 仓库
- 从其它服务器克隆一个已存在的 Git 仓库 以上两种方式都能够在自己的电脑上得到一个可用的 Git 仓库
3.2 在现有目录中初始化仓库
如果自己有一个尚未进行版本控制的项目目录,想要用 Git 来控制它,需要执行如下两个步骤:
- 在项目根目录中,通过鼠标右键打开“Git Bash”
- 执行
git init
命令将当前的目录转化为 Git 仓库
git init 命令会创建一个名为 .git 的隐藏目录,这个 .git 目录就是当前项目的 Git 仓库,里面包含了初始的必要 文件,这些文件是 Git 仓库的必要组成部分。
//在项目根目录中点击鼠标右键,点击Git Bash Here,调处命令窗口
输入 git init //初始化项目,创建一个.git的目录,用来做本地仓库
.git 目录:
- hooks 目录包含客户端或服务端的钩子脚本,在特定操作下(add/commit 等)自动执行
- info 信息文件夹. 包含一个全局性排除文件,可以配置文件忽略不需要提交的内容
- logs 保存日志信息(提交历史记录)
- objects 仓库目录,存储所有数据内容,本地的版本库存放位置 --仓库区
- refs 目录存储指向数据的提交对象的指针(存储分支信息)
- COMMIT_EDITMSG.swp 最后一次提交的文字声明(vim的暂时文件)
- COMMIT_EDITMSG 最后一次提交的文字声明
- config 该文件包含项目特有的配置选项
- description 用来显示对仓库的描述信息
- HEAD 文件指示目前被检出的分支的路径
- index 暂存区文件,是一个二进制文件 (git ls-files) --暂存区
切记: 不要手动去修改 .git 文件夹中的内容
3.3 工作区中文件的 4 种状态
工作区中的每一个文件可能有 4 种状态,这四种状态共分为两大类,如图所示:
- 未被Git管理:未跟踪(如新建文件或者刚刚git init初始化仓库的文件未被Git管理)
- 已被Git管理:未修改(git commit 提交之后)、已修改、已暂存(执行git add之后)
Git 操作的终极结果:让工作区中的文件都处于 “未修改” 的状态。 总结起来一个文件的状态通常可以分为:
- 不受版本控制的
untracked
状态 - 受版本控制并且已修改的
modified
状态 - 受版本控制已修改并提交到暂存区的
staged
状态 - 从暂存区已经提交到本地仓库的
committed
状态 - 提交到本地仓库未修改或者从远程仓库克隆下来的
unmodified
状态
3.4 检查文件的状态
3.4.1 git status
可以使用 git status
命令查看文件处于什么状态,例如:
//在项目根目录中点击鼠标右键,点击Git Bash Here,调处命令窗口
输入 git status //检查文件状态
在状态报告中可以看到新建的 index.html 等文件出现在Untracked files
(未跟踪的文件) 下面。 未跟踪的文件意味着 Git 在之前的快照(提交)中没有这些文件;Git 不会自动将之纳入跟踪范围,除非明确 地告诉它“我需要使用 Git 跟踪管理该文件”。
3.4.2 git diff与git ls-files
git ls-files //查看暂存区的文件
git diff //查看工作区与暂存区的差异(不显示新增文件),显示做了哪些修改
git diff --cached // 查看暂存区与仓库的差异
3.5 以精简的方式显示文件状态
使用 git status
输出的状态报告很详细,但有些繁琐。如果希望以精简的方式显示文件的状态,可以使用如下 两条完全等价的命令,其中-s
是 --short
的简写形式:
//在项目根目录中点击鼠标右键,点击Git Bash Here,调处命令窗口
简写:git status -s
git status --short
未跟踪文件前面有红色的 ?? 标记
,例如:
3.6 跟踪新文件
使用命令 git add
开始跟踪一个文件。 所以,要跟踪 index.html 文件,运行如下的命令即可:
//在项目根目录中点击鼠标右键,点击Git Bash Here,调处命令窗口
git add index.html //选中index.html这个文件,添加到暂存区
git add . //选中当前文件夹(目录)中所有的新增和修改过的文件,添加到暂存区
git add --all //添加全部 git add --A简写
此时再运行 git status
命令,会看到 index.html等文件在 Changes to be committed
这行的下面,说明已被跟踪,并处于暂存状态
:
以精简的方式显示文件的状态:
新添加到暂存区中的文件前面有
绿色的 A 标记
3.7 提交更新
现在暂存区
中有一个 index.html
文件等待被提交到 Git 仓库中进行保存。可以执行 git commit
命令进行提交, 其中 -m 选项后面是本次的提交消息,用来对提交的内容做进一步的描述:
//在项目根目录中点击鼠标右键,点击Git Bash Here,调处命令窗口
git commit //在 Git Bash或者Cmder/配置了Cmder的vscode中使用,会在vscode中打开新文件让你输入
git commit -m "对内容进行描述" //在 Git Bash或者Cmder/配置了Cmder的vscode中通用
git commit -v //在 Git Bash或者Cmder/配置了Cmder的vscode中使用,会在vscode中打开新文件让你输入,会对比改变前后的差异
备注:如进入的是vim编辑器,则按a或者i进入编辑模式,写完说明后,先按 Esc退出编辑模式,然后输入:wq,按回车健退出
提交成功之后,会显示如下的信息:
注意:此时已被跟踪暂存的文件被提交到Git仓库,但未被跟踪的文件不会被提交
如果项目中所有文件被提交:
证明工作区中所有的文件都处于“未修改”的状态,没有任何文件需要被提交。
3.8 对已提交的文件进行修改
目前,index.html等文件已经被 Git 跟踪,并且工作区和 Git 仓库中的 index.html等文件内容保持一致。当我们修改了工作区中 index.html 的内容之后,再次运行 git status 和 git status -s 命令,会看到如下的内容:
文件 index.html 出现在 Changes not staged for commit
这行下面,说明已跟踪文件的内容发生了变化, 但还没有放到暂存区。
注意:修改过的、没有放入暂存区的文件前面有
红色的 M 标记
。
3.9 暂存已修改的文件
目前,工作区中的 index.html 文件已被修改,如果要暂存这次修改,需要再次运行 git add
命令,这个命令 是个多功能的命令,主要有如下 3 个功效:
- 可以用它开始跟踪新文件
- 把已跟踪的、且已修改的文件放到暂存区
- 把有冲突的文件标记为已解决状态
3.10 提交已暂存的文件
再次运行 git commit -m "提交消息"
命令,即可将暂存区中记录的 index.html的快照,提交到 Git 仓库中进行保存:
3.11 撤销对文件的修改--checkout
撤销对文件的修改指的是:把对工作区中对应文件的修改,还原成 Git 仓库中所保存的版本。 操作的结果:所有的修改会丢失,且无法恢复!危险性比较高,请慎重操作!
即放弃对本地已修改但尚未提交的文件的修改,并用最近一次的commit内容还原到当前工作区。
注意: 已add
/commit
的文件不适用个方法,应该用本文提到的第二种方法:回退。
git checkout . # 撤销对所有已修改但未提交的文件的修改,无法新增文件起作用
git checkout --[filename] # 撤销对指定文件的修改,[filename]为文件名,无法新增文件起作用
-------------------------------------------------------------------------------------
git checkout -- index.html
撤销操作的本质:用 Git 仓库中保存的文件,覆盖工作区中指定的文件。
注意:该命令不会对新增文件起作用。因为新增的文件是还未加到
git
的记录里面的,即属于未被跟踪的状态,所以撤销修改和回退均对其不影响,我们直接手动删除文件就行了。
3.12 撤销对文件的修改--restore
Git 2.23 版本新增了restore命令,因为git checkout
命令职责较多、不够明确,而restore
命令则专门用来还原、撤销修改等操作。
git restore --staged <file> //是将暂存区的文件从暂存区撤出,但不会撤销文件的更改。
--------------------------------------------------------------------------------------------
git restore <file> //使得在工作空间但是不在暂存区的文件撤销更改(内容恢复到没修改之前的状态)
如果暂存区有该文件的修改,恢复到和暂存区一致;如果暂存区没有该文件,会将工作区的文件恢复到和最近的提交的一致。
--------------------------------------------------------------------------------------------
git restore . // 撤销工作区所有文件的修改
git restore test2.txt // 撤销工作区est2.txt文件的修改
--------------------------------------------------------------------------------------------
git restore --staged *.java 表示将所有暂存区的java文件恢复状态
git restore --staged . 表示将当前目录所有暂存区文件从暂存区撤出
--staged 参数就是表示仅仅恢复暂存区的
3.13 取消暂存的文件 --reset
即撤销
git add
命令 如果需要从暂存区中移除对应的文件,可以使用如下的命令:
git reset HEAD 要移除的文件名
------------------------------
git reset HEAD index.html //将index.html移除暂存区
git reset HEAD . //将当前目录下所有在暂存区的文件移除暂存区
3.14 查看提交历史并回退到指定的版本
3.14.1 查看提交历史
// 按时间的先后顺序列出所有的提交历史,最近的提交排在最上面
git log
// 只展示最新的两条提交历史,数字可以按需进行填写
git log -2
// 在一行上展示最近两条提交历史的信息
git log -2 --pretty=oneline
// 在一行上展示最近两条提交历史的信息,并自定义输出的格式
// %h提交的简写哈希值 %an作者的名字 %ar作者的修订日期,按多久以前的方式显示 %s提交说明
git log -2 --pretty=format:"%h | %an | %ar | %s"
注意:在最后面的:处按Enter会将因窗口太小显示不全的记录显示出来;且按
Q
键退出窗口
3.14.2 回退到指定版本
git reset --hard xxxxxx //xxxx是唯一标识ID
注意:
- 用git reset --hard xxxxxx之前必须提交,否则未提交的会消失。
- XXXXXX 是 commit 的号码,可以是6位,也可以是4位,也可以是 7位,只要是惟一的即可。
3.14.3 git log与git reflog
- git log 命令只能查看当前分支下的 commit 信息,查看其它分支 commit 需要切换分支;
- git reflog 可以查看所有分支的所有操作记录(包括已经被回退的 commit 记录和 reset 的操作);
例如执行 git reset --hard xxxx,退回到上一个版本,用git log则是看不出来被删除的commitid,用git reflog则可以看到被删除的commitid,我们就可以买后悔药,恢复到被删除的那个版本。
3.15 跳过使用暂存区域
Git 标准的工作流程是工作区 → 暂存区 → Git 仓库,但有时候这么做略显繁琐,此时可以跳过暂存区,直接将工作区中的修改提交到 Git 仓库,这时候 Git 工作的流程简化为了工作区 → Git 仓库。 Git 提供了一个跳过使用暂存区域的方式, 只要在提交的时候,给 git commit 加上 -a 选项
,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤:
注意:是所有已经跟踪过的文件,之前未跟踪过的不行
git commit -a -m "输入备注"
3.16 移除文件
即撤销
git commit
命令 从 Git 仓库中移除文件的方式有两种:
- 从 Git 仓库和工作区中同时移除对应的文件
- 只从 Git 仓库中移除指定的文件,但保留工作区中对应的文件
//从 Git 仓库和工作区中同时移除对应的文件
git rm -f 文件名
//只从 Git 仓库中移除指定的文件,但保留工作区中对应的文件
git rm --cached 文件名
----------------------------------------------------
git rm -f . //全部文件
git rm -r --cached . //全部文件
运行命令之前:
运行git rm -f 文件名
:
注意:该文件已经被标记为删除,下一次提交后工作区与仓库区就不再包含index.html
运行git rm --cached 文件名
:
注意:该文件已经被标记为删除,下一次提交后仓库区就不再包含index.css,并且index.css文件变为未跟踪的状态。
3.17 忽略文件
项目中有些文件不应该存储到版本库中,Git中需要创建一个文件.gitignore
配置忽略,一般与 .git 目录同级。
常见情况有:
- 临时文件.
- 多媒体文件,如音频,视频
- 编辑器生成的配置文件 (.idea)
- npm 安装的第三方模块
文件
.gitignore
的格式规范如下: - 以 # 开头的是注释
- 以 / 结尾的是目录
- 以 / 开头防止递归
- 以 ! 开头表示取反
- 可以使用 glob 模式进行文件和文件夹的匹配(glob 指简化了的正则表达式)
3.17.1 glob 模式
所谓的 glob 模式是指简化了的正则表达式:
- 星号 * 匹配零个或多个任意字符
- [abc] 匹配任何一个列在方括号中的字符 (此案例匹配一个 a 或匹配一个 b 或匹配一个 c)
- 问号 ? 只匹配一个任意字符
- 在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配 所有 0 到 9 的数字)
- 两个星号 ** 表示匹配任意中间目录(比如 a/**/z 可以匹配 a/z 、 a/b/z 或 a/b/c/z 等)
3.17.2 .gitignore实例
-
config.php #忽略当前项目下所有名为 config.php 文件
-
*.sample #忽略当前项目下所有以 .sample 结尾的文件
-
!lib.sample #即使你忽略所有以 .sample 结尾的文件,但 lib.sample 除外
-
/TODO #仅仅忽略项目根目录下的 TODO 文件,不包括其他文件夹下的TODO文件
-
build/ #忽略当前根目录下的build文件夹,该文件夹下的所有内容都会被忽略,不忽略build文件
-
doc/*.txt #会忽略 doc/notes.txt,即doc文件夹下的以.txt结尾的文件;但不会忽略doc/server/arch.txt,即其他文件夹(包括子文件夹)下的以.txt结尾的文件不会忽略。
-
[] #匹配字符列,如 [Ll]ibrary 意为Library或library均满足条件
-
**/foo #忽略/foo, a/foo, a/b/foo等
-
a/**/b #忽略a/b, a/x/b, a/x/y/b等
-
doc/**/*.pdf #忽略doc目录及其子目录下的所有.pdf结尾的文件
-
忽略
.a
或.A文件
,不包含demo.a
文件*.[aA] !demo.a
-
在已忽略文件夹中不忽略指定文件夹
/libs/* !/libs/extend/
-
在已忽略文件夹中不忽略指定文件
/libs/* !/libs/extend/fastjson.jar
-
忽略
libs
文件,不忽略libs
目录:libs !libs/
3.17.3 .gitignore不生效问题
.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。 解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:
1. git rm -r --cached . //git rm -r --cached index.md
2. 在.gitignore中配置要忽略的文件名
3. git add .
4. git commit -m 'update .gitignore'
4. GitHub
4.1 注册 Github 账号
- 访问 Github 的官网首页 github.com/
- 点击“Sign up”按钮跳转到注册页面
- 填写可用的用户名、邮箱、密码
- 通过点击箭头的形式,将验证图片摆正
- 点击“Create account”按钮注册新用户
- 登录到第三步填写的邮箱中,点击激活链接,完成注册
4.2 远程仓库的使用
4.2.1 新建空白远程仓库
- 在仓库首页点击左侧上方的NEW按钮,即可创建新仓库;
-
在Repository name中输入仓库名,在Description中输入项目描述,点击Create repository创建成功;
-
新建空白远程仓库成功
4.2.2 远程仓库的两种访问方式
Github 上的远程仓库,有两种访问方式,分别是 HTTPS 和 SSH。它们的区别是:
- HTTPS:零配置;但是每次访问仓库时,需要重复输入 Github 的账号和密码才能访问成功
- SSH:需要进行额外的配置;但是配置成功后,每次访问仓库时,不需重复输入 Github 的账号和密码
注意:在实际开发中,推荐使用 SSH 的方式访问远程仓库。
4.3 基于 HTTPS 将本地仓库上传到 Github
git remote add origin https://github.com/xiaohigh/test2.git
//远端仓库管理,创建远程仓库url的别名
add 添加
origin 远端仓库的别名 ,随意写
https://github.com/xiaohigh/test2.git 仓库地址
git push -u origin main
//将本次仓库的某个分支推送到远程仓库的分支上
push 推送
-u 分支关联, 加上以后,后续提交时可以直接使用 git push,不需要再加仓库别名与分支名
origin 远端仓库的别名,和上面需要保持一致
main 本地仓库的分支名
注意:从2021年8月14日之后,使用git对github进行身份验证操作的时候不再接受使用账号密码形式clone和push代码,之前使用账号密码形式的可以改为使用acces_token形式上传
解决方法:设置Token--juejin.cn/post/699817…
切记:一定要将Token找好地方保持,我的token保存在C:\Users\zgc99中
如果是再次提交同步代码,只需要使用:
git push
4.4 基于 SSH 将本地仓库上传到 Github
4.4.1 SSH key
- SSH key 的作用:实现本地仓库和 Github 之间免登录的加密数据传输。
- SSH key 的好处:免登录身份认证、数据加密传输。 SSH key 由两部分组成,分别是:
- id_rsa(私钥文件,存放于客户端的电脑中即可)
- id_rsa.pub(公钥文件,需要配置到 Github 中)
4.4.2 生成 SSH key
- 打开 Git Bash
- 粘贴如下的命令,并将 your_email@example.com 替换为注册 Github 账号时填写的邮箱:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
- 连续敲击 3 次回车,即可在 C:\Users\用户名文件夹.ssh 目录中生成 id_rsa 和 id_rsa.pub 两个文件
比如说我的就保存在: C:\Users\zgc99.ssh中
4.4.3 配置 SSH key
- 使用记事本打开 id_rsa.pub 文件,复制里面的文本内容
- 在浏览器中登录 Github,点击头像 -> Settings -> SSH and GPG Keys -> New SSH key
- 将 id_rsa.pub 文件中的内容,粘贴到 Key 对应的文本框中
- 在 Title 文本框中任意填写一个名称,来标识这个 Key 从何而来
4.4.4 检测 SSH key 是否配置成功
打开 Git Bash,输入如下的命令并回车执行:
ssh -T git@github.com
上述的命令执行成功后,可能会看到一些提示消息: 输入 yes 之后,如果能看到类似于下面的提示消息,证明 SSH key 已经配置成功了。
4.4.5 上传测试
与之前操作相同,只是将 HTTPS 改为了 SSH
4.5 将远程仓库克隆到本地
打开 Git Bash,输入如下的命令并回车执行:
git clone 远程仓库的地址
git clone git@github.com:zgcwf/a.git //将仓库下载
------------------------------------------------------------------
git clone git@github.com:zgcwf/a.git zgc //将仓库下载并将其重命名为zgc
------------------------------------------------------------------
注意:git clone 会将仓库的所有分支全部拉取下来而 git pull 只会拉取指定的分支内容
注意:克隆之后进入该文件再进行操作
cd zgc
5. Git 分支
5.1 本地分支
5.1.1 分支的概念
分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努 力学习SVN。 如果两个平行宇宙互不干扰,那对现在的你也没啥影响。 不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN!
5.1.2 分支在实际开发中的作用
在进行多人协作开发的时候,为了防止互相干扰,提高协同开发的体验,建议每个开发者都基于分支进行项目 功能的开发,例如:
5.1.3 master/main 主分支
在初始化本地 Git 仓库的时候,Git 默认已经帮我们创建了一个名字叫做 master 的分支。通常我们把这个 master 分支叫做主分支,当我们上传到GitHUb的时候,会将master改为main(因为 master 有奴隶主的意思,涉嫌歧视黑人,政治正确。)
在实际工作中,master 主分支的作用是:用来保存和记录整个项目已完成的功能代码。 因此,不允许程序员直接在 master 分支上修改代码,因为这样做的风险太高,容易导致整个项目崩溃。
5.1.4 功能分支
由于程序员不能直接在 master 分支上进行功能的开发,所以就有了功能分支的概念。 功能分支指的是专门用来开发新功能的分支,它是临时从 master 主分支上分叉出来的,当新功能开发且测试 完毕后,最终需要合并到 master 主分支上,如图所示:
5.1.5 查看分支列表
使用如下的命令,可以查看当前 Git 仓库中所有的分支列表:
git branch //列出当前所有本地分支
git branch -a //查看所有分支
注意:分支名字前面的 *
号表示当前所处的分支。
5.1.6 创建新分支
使用如下的命令,可以基于当前分支,创建一个新的分支,此时,新分支中的代码和当前分支完全一样:
git branch 分支名称
注意:执行完创建分支命令后,用户所处的还是master主分支
5.1.7 切换分支
使用如下的命令,可以切换到指定的分支上进行开发:
git checkout 分支名称
确保你当前分支工作区和缓存区是干净的:如果你的当前分支工作区和缓存区是干净的,也就是在当前分支 commit 之后再没做任何更改,你往别的分支切换时不会有影响的。但是如果你在当前分支有未完成的工作,也就是存在没有
add
或者commit
的文件,你往 master 分支切换的时候,会把你在当前分支下未提交的工作也带过去。www.jianshu.com/p/a298cb3d9…
5.1.8 分支的快速创建和切换
使用如下的命令,可以创建指定名称的新分支,并立即切换到新分支上:
# -b表示创建一个新的分支
# checkout表示切换到刚才新建的分支上
-------------------------------------
git checkout -b 分支名称
注意: "git checkout -b 分支名称
" 是下面 两条命令的简写形式:
git branch 分支名称
git checkout 分支名称
创建分支时最好切换到主分支进行创建
5.1.9 合并分支
功能分支的代码开发测试完毕之后,可以使用如下的命令,将完成后的代码合并到 master 主分支上:
# 1.切换到master分支
git checkout master
# 2.在 master 分支上执行 git merge 命令,將要合并的分支的代码合并到master分支
git merge 分支名称
合并分支时的注意点:
- 确保你当前分支工作区和缓存区是干净的,已经 add 与 commit 完成
- 假设要把 C 分支的代码合并到 A 分支, 则必须先切换到 A 分支上,再运行 git merge 命令,来合并 C 分支!
- 注意你的主分支名字是 master 还是 main 流程:
- 首先在 login 分支创建了 login.html 文件
- 暂存并提交,即:git add 和 git commit(很重要)
- 切换回主分支,注意主分支名称是master 还是 main
- 此时会发现在主分支下,login分支中新建的 login.html 文件消失
- 在主分支下运行 git merge login 合并分支 login分支:
主分支: 少了login.html文件
合并后的主分支:
5.1.10 删除分支
当把功能分支的代码合并到 master 主分支上以后,就可以使用如下的命令,删除对应的功能分支:
git branch -d 分支名称
注意:
- 删除分支时你一定要保证自己不在那个被删除的分支上面
- 删除时确保该分支已经被合并到主分支了,否则会进行报错提示,可以使用
git branch -D 分支名称
进行强制删除
5.1.11 遇到冲突时的分支合并
如果在两个不同的分支中,对同一个文件进行了不同的修改,Git 就没法干净的合并它们。 此时,我们需要打开 这些包含冲突的文件然后手动解决冲突。
# 假设再将 zgc 分支合并到 main 分支期间,代码发生了冲突
git checkout main
git merge zgc
# 打开包含冲突的文件,手动解决冲突之后,再执行如下的命令
git add .
git commit -m "解决了分支合并冲突的问题"
流程:
- 在主分支更改了index.html文件,暂存并提交;
- 在zgc分支更改了index.html文件,暂存并提交;
- 切换回主分支,运行
git merge zgc
,合并分支,发生冲突 - 在vscode打开项目进行选择,解决分支冲突
- 冲突解决后暂存并提交
注:可以用ctrl + z 撤销选择,进行回退
复杂情况:
- 如果冲突文件过多,可以使用
git status -sb
查看哪个/哪些文件冲突了 - 依次打开每个文件
- 搜索====四个等于号,找到冲突的地方
- 同上述情况,选择要保留的代码,删除不用的代码,删除 ==== >>>> <<<<这些标记
git add
对应文件- 再次
git status -sb
解决下一个文件冲突,git add
对应文件 - 直到没有冲突,运行
git commit
5.2 远程分支
5.2.1 将本地分支推送到远程仓库
如果是第一次将本地分支推送到远程仓库,需要运行如下的命令:
# -u 表示把本地分支和远程分支进行关联,只在第一次推送的时候需要带-u参数
git push -u 远程仓库的别名 本地分支名称:远程分支名称
# 实际案例
git push -u origin payment:pay
# 如果希望远程分支的名称和本地分支名称保持一致,可以对命令进行简化
git push -u origin payment
注意:第一次推送分支需要带 -u 参数,此后可以直接在对应分支使用
git push
推送当前分支的代码到对应的远程分支。完整版:www.yiibai.com/git/git_pus…
5.2.2 查看远程仓库名称
git remote
5.2.3 查看远程仓库中所有的分支列表
通过如下的命令,可以查看远程仓库中,所有的分支列表的信息:
git remote show 远程仓库名称
5.2.4 跟踪分支
跟踪分支指的是:从远程仓库中,把远程分支下载到本地仓库中。需要运行的命令如下:
# 从远程仓库中,把对应的远程分支下载到本地仓库,保持本地分支和远程分支名称相同
git checkout 远程分支的名称 //如果本地有对应仓库是切换仓库
# 示例
git checkout pay
-----------------------------------------------------------------------------------------------
# 从远程仓库中,把对应的远程分支下载到本地仓库,并把下载的本地分支进行重命名
git checkout -b 本地分支名称 远程仓库名称/远程分支名称
# 示例
git checkout -b payment origin/pay
5.2.5 拉取远程分支的最新的代码
git pull
命令的作用是:取回远程主机某个分支的更新,再与本地的指定分支合并。默认模式下,git pull
是git fetch
后跟git merge FETCH_HEAD
# 从远程仓库,拉取当前分支最新代码,保持当前分支的代码和远程分支代码一致
git pull //在哪个分支上运行,就拉取哪个分支的最新代码
//注意:这样写只会拉取当前所处分支的更新,不会拉取其他分支的更新代码
完整版:
命令格式如下:
git pull <远程主机名> <远程分支名>:<本地分支名>
将远程主机 origin仓库 的 master 分支拉取过来,与本地的 brantest 分支合并。
git pull origin master:brantest //这种写法不用去切换所在分支了,在所有分支效果都是一样的
如果远程分支是与本地当前所在的分支合并,则冒号后面的部分可以省略。
git pull origin master // 取回 origin/master 分支,再与本地所处的分支合并,这种写法要切换至你想要合并的分支
5.2.6 删除远程分支
可以使用如下的命令,删除远程仓库中指定的分支:
# 删除远程仓库中,指定名称的远程分支
git push 远程仓库名称 --delete 远程分支名称
# 示例
git push origin --delete pay
5.2.7 将一个本地仓库上传至两个远程仓库
- 在github上创建两个远程仓库
- 在桌面创建一个文件,用vscode打开
- 新建终端,创建初始仓库并提交
- 输入github中提示的代码,注意两个仓库别名要修改成不一致的
- 上传本地仓库到main分支远程仓库origin1的main分支
- 上传本地仓库到zgc分支远程仓库origin2的zgc分支
6. 附录
6.1 Linux常用命令
Linux 是一套开源免费的操作系统。与系统的交互通常用命令来实现,常用的命令有:
- ls : 查看文件夹下的文件
ls //查看当前目录下的文件
ls css //查看当前目录下的css文件中的文件
- ctrl + c 取消命令 (cancel)
- Tab 自动补齐路径
- 上下方向键,可以查看命令历史 (history 查看所有的历史命令)
- clear :清屏(也可以使用
ctrl + l
快捷键) - pwd :查看工作目录的完整路径
pwd //在命令行中输入pwd可立刻得知您目前所在的工作目录的绝对路径名称
- cd : 进入某一个文件夹内
cd .. //回到上一级
cd 文件名 // 进入该文件(注意,该文件必须是当前目录下存在的文件,不能跨目录)
Tab键 //自动补全路径,当一个文件名太长时,输入一部分文件名,按Tab健会自动补全剩余字符
cd /d //cd后面跟 `/硬盘名`可以无视路径跳入该硬盘
cd ~ //进入用户文件夹
cd ~/Desktop //进入桌面
- mkdir :创建文件夹
mkdir 文件夹名
-------------
mkdir js //创建js文件夹
mkdir html //创建html文件夹
--------------------------
mkdir js html css //同时创建3个文件夹
- touch : 创建一个文件(注意:必须在对应的文件夹下运行该语句)
touch 文件名
-----------
touch app.js //创建app.js的文件
touch test.html //创建test.html的文件
-----------------------------------
touch js/app.js images/logo.png //在分别当前目录下的images文件夹和js文件夹中创建文件
- rm : 删除文件 (注意:被该命令删除的文件不会进回收站,无法恢复)
rm 文件名
------------
rm zgc.css //删除当前目录下的zgc.css文件
- rm -rf:删除文件夹(注意:被该命令删除的文件不会进回收站,无法恢复)
rm -rf 目录名字
//-r 向下递归,不管有多少级目录,一并删除。
//-f 直接强行删除,没有任何提示。
rm -rf /var/log/httpd //删除/var/log/httpd目录以及其下所有文件、文件夹,httpd文件夹也被删除
rm -f /var/log/httpd/access.log //这个将会强制删除/var/log/httpd/access.log这个文件,和删除文件效果是一样的
注意:以上两个是绝对路径,想改为相对路径的话直接在最前面的/加一个.,即 ./var/....
- 删除当前目录下所有文件:
rm ./* -rf
- mv : 移动文件或者更改文件名
mv login.js js //将 login.js文件移动到js文件夹下
mv a b //将a文件夹移入到b文件夹
mv source/1.txt . //将source文件夹里面的1.txt文件移动到当前目录
mv 1.txt 2.txt //将1.txt重命名为2.txt
mv login.js js/index.js //将 login.js文件移动到js文件夹下并改名为index.js
- cat : 查看文件内容
cat login.html //查看当前目录下login.html文件的内容
- 删库跑路语句: 慎用!!!
Linux:`rm / -rf`
MySQL:`drop database project`
Mongodb:`db.dropDatabase()`
Linux 命令执行的潜规则:如果没有任何输出表明成功,如果出现
error
,fatal(致命)
表明执行失败
6.2 Vim编辑器的使用
Vim 是一款命令行下的文本编辑器,编辑方式跟图形化编辑器不同
vim test.html
编辑文件(文件存在进行编辑,文件不存在则创建后编辑)- 按
i
/a/o 这三个字母的其中一个进入编辑模式,用i
就行 - 编辑完成后:
ESC
+:w
保存,之后可以再按i
进入编辑模式ESC
+:q
退出ESC
+:wq
保存并退出ESC
+:q!
不保存并退出
- 快捷键:
ctrl + insert //复制
shift + insert //粘贴
6.3 GitHub 团队协作
GitHub 团队协作开发也比较容易管理,可以创建一个组织
- 首页 -> 右上角
+
号-> new Organization - 免费计划
- 填写组织名称和联系方式(不用使用中文名称)
- 邀请其他开发者进入组织,输入用户名搜索,发起邀请后会发送邮件给被邀请者确认
- 点击组织右侧的 settings 设置
- 左侧 Member privileges
- 右侧 Base permissions 将
read
改为write
👌,这样成员就对组织当中的仓库有写入权限
- 最后在创建新仓库时,在Owner选择对应的组织就可以了
6.4 协作流程
第一次
-
得到 Git 远程仓库的地址和账号密码
-
将代码克隆到本地(地址换成自己的)
git clone xxxxxx
-
切换分支,在属于自己的分支上开发代码
git checkout -b xiaohigh
-
开发代码
-
本地提交
git add -A git commit -m '注释内容'
-
合并分支
git checkout master git merge xiaohigh
-
更新本地代码
git pull 冲突解决:同分支冲突一样的处理,将代码调整成最终的样式,提交(add,commit)代码即可。
-
提交代码
git push
6.5 GitFlow
GitFlow 是团队开发的一种最佳实践,将代码划分为以下几个分支
- Master 主分支: 上面只保存正式发布的版本
- Hotfix 线上代码 Bug 修复分支: 开发完后需要合并回 Master 和 Develop 分支,同时在 Master 上打一个 tag
- Feather 功能分支: 当开发某个功能时,创建一个单独的分支,开发完毕后再合并到 dev 分支
- Release 分支: 待发布分支,Release 分支基于 Develop 分支创建,在这个 Release 分支上测试,修改 Bug
- Develop 开发分支: 开发者都在这个分支上提交代码