版本控制~Git攻略

453 阅读35分钟

1. Git 基础概念

1.1 什么是 Git

Git 是一个开源的分布式版本控制系统,是目前世界上最先进、最流行的版本控制系统。可以快速高效地处理 从很小到非常大的项目版本管理。 也就是说Git可以让你的代码有版本,你可以随时回退到某个版本。

特点:项目越大越复杂,协同开发者越多,越能体现出 Git 的高性能和高可用性!

1.2 Git 的特性

Git 之所以快速和高效,主要依赖于它的如下两个特性:

  1. 直接记录快照,而非差异比较
  2. 近乎所有操作都是本地执行

1.2.1 SVN 的差异比较

传统的版本控制系统(例如 SVN)是基于差异的版本控制,它们存储的是一组基本文件和每个文件随时间逐步累积的差异

  • 好处:节省磁盘空间
  • 缺点:耗时、效率低 在每次切换版本的时候,都需要在基本文件的基础上,应用每个差异,从而生成目标版本对应的文件。

1.2.2 Git 的记录快照

Git 快照是在原有文件版本的基础上重新生成一份新的文件,类似于备份。为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。

  • 缺点:占用磁盘空间较大
  • 优点:版本切换时非常快,因为每个版本都是完整的文件快照,切换版本时直接恢复目标版本的快照即可。
  • 特点:空间换时间

1.2.3 近乎所有操作都是本地执行

在 Git 中的绝大多数操作都只需要访问本地文件和资源,一般不 需要来自网络上其它计算机的信息。

特性:

  • 断网后依旧可以在本地对项目进行版本管理
  • 联网后,把本地修改的记录同步到云端服务器即可
  • 服务器故障或损坏后,可使用任何一个客户端的备份进行恢复

1.3 Git 中的三个区域

使用 Git 管理的项目,拥有三个区域,分别是工作区、暂存区、Git 仓库。

Snipaste_2022-06-09_16-35-11.png

1.4 Git 中的三种状态

Snipaste_2022-06-09_16-34-58.png

注意:

  • 工作区的文件被修改了,但还没有放到暂存区,就是已修改状态。
  • 如果文件已修改并放入暂存区,就属于已暂存状态。
  • 如果 Git 仓库中保存着特定版本的文件,就属于已提交状态

1.5 基本的 Git 工作流程

基本的 Git 工作流程如下:

  1. 在工作区中修改文件
  2. 将你想要下次提交的更改进行暂存
  3. 提交更新,找到暂存区的文件,将快照永久性 存储到 Git 仓库

1.6 杂谈:版本控制的进化

  1. 本地版本控制系统
  2. 集中化的版本控制系统
  3. 分布式版本控制系统

1.6.1 本地版本控制系统

特点: 使用软件来记录文件的不同版本,提高了工作效率, 降低了手动维护版本的出错率

缺点:

  1. 单机运行,不支持多人协作开发
  2. 版本数据库故障后,所有历史更新记录会丢失

1.6.2 集中化的版本控制系统

特点: 基于服务器、客户端的运行模式

  1. 服务器保存文件的所有更新记录 (差异)
  2. 客户端只保留最新的文件版本 优点: 联网运行,支持多人协作开发

缺点:

  1. 不支持离线提交版本更新
  2. 中心服务器崩溃后,所有人无法正常工作
  3. 版本数据库故障后,所有历史更新记录会丢失 典型代表:SVN

1.6.3 分布式版本控制系统

特点: 基于服务器、客户端的运行模式

  1. 服务器保存文件的所有更新版本 (文件快照/备份)
  2. 客户端是服务器的完整备份,并不是只保留文件的最新版本 优点:
  3. 联网运行,支持多人协作开发
  4. 客户端断网后支持离线本地提交版本更新
  5. 服务器故障或损坏后,可使用任何一个客户端的备份进行恢复 典型代表:Git

2. 安装并配置 Git

2.1 下载并安装 Git

在开始使用 Git 管理项目的版本之前,需要将它安装到计算机上。可以使用浏览器访问如下的网址,根据自己 的操作系统,选择下载对应的 Git 安装包: git-scm.com/downloads

Snipaste_2022-06-12_20-08-32.png

注意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,调处命令窗口

Snipaste_2022-06-09_11-07-24.png

2.3 Git 的全局配置文件

通过 git config --global user.name 和 git config --global user.email 配置的用户名和邮箱地址,会被写 入到 C:/Users/用户名文件夹/.gitconfig 文件中。这个文件是 Git 的全局配置文件,配置一次即可永久生效。 可以使用记事本或者vscode打开此文件,从而查看自己曾经对 Git 做了哪些全局性的配置.

每个人的用户名是不同的,比如我的是:C:\Users\zgc99\.gitconfig

Snipaste_2022-06-11_22-04-15.png

2.4 检查配置信息

除了使用记事本查看全局的配置信息之外,还可以运行如下的终端命令,快速的查看 Git 的全局配置信息:

右击桌面,点击Git Bash Here,调处命令窗口

//查看所有的全局配置项
git config --list --global
//查看指定的全局配置项
git config user.name
git config user.email
git config xxxxxxxxxx

Snipaste_2022-06-11_22-07-31.png

2.5 获取帮助信息

可以使用 git help 命令,无需联网即可在浏览器中打开帮助手册,例如:

//想要打开 git config 命令的帮助手册
git help config

如果不想查看完整的手册,那么可以用 -h 选项获得更简明的“help”输出:

//想要获取 git config 命令的快速参考
git config -h

3. Git 的基本操作

3.1 获取 Git 仓库的两种方式

  1. 将尚未进行版本控制的本地目录转换为 Git 仓库
  2. 从其它服务器克隆一个已存在的 Git 仓库 以上两种方式都能够在自己的电脑上得到一个可用的 Git 仓库

3.2 在现有目录中初始化仓库

如果自己有一个尚未进行版本控制的项目目录,想要用 Git 来控制它,需要执行如下两个步骤:

  1. 在项目根目录中,通过鼠标右键打开“Git Bash”
  2. 执行 git init 命令将当前的目录转化为 Git 仓库

git init 命令会创建一个名为 .git 的隐藏目录,这个 .git 目录就是当前项目的 Git 仓库,里面包含了初始的必要 文件,这些文件是 Git 仓库的必要组成部分。

//在项目根目录中点击鼠标右键,点击Git Bash Here,调处命令窗口
输入 git init //初始化项目,创建一个.git的目录,用来做本地仓库

Snipaste_2022-06-09_15-19-58.png

.git 目录:

Snipaste_2022-06-14_17-05-37.png

  • 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之后) Snipaste_2022-06-09_15-24-34.png

Git 操作的终极结果:让工作区中的文件都处于 “未修改” 的状态。 总结起来一个文件的状态通常可以分为:

  • 不受版本控制的 untracked 状态
  • 受版本控制并且已修改的 modified 状态
  • 受版本控制已修改并提交到暂存区的 staged状态
  • 从暂存区已经提交到本地仓库的 committed 状态
  • 提交到本地仓库未修改或者从远程仓库克隆下来的 unmodified 状态

3.4 检查文件的状态

3.4.1 git status

可以使用 git status 命令查看文件处于什么状态,例如:

//在项目根目录中点击鼠标右键,点击Git Bash Here,调处命令窗口
输入 git status //检查文件状态

Snipaste_2022-06-09_15-31-21.png

在状态报告中可以看到新建的 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

未跟踪文件前面有红色的 ?? 标记,例如:

Snipaste_2022-06-09_15-38-51.png

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 这行的下面,说明已被跟踪,并处于暂存状态

Snipaste_2022-06-09_15-44-14.png

以精简的方式显示文件的状态:

Snipaste_2022-06-09_15-44-58.png

新添加暂存区中的文件前面有绿色的 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,按回车健退出

提交成功之后,会显示如下的信息:

Snipaste_2022-06-09_15-56-15.png

注意:此时已被跟踪暂存的文件被提交到Git仓库,但未被跟踪的文件不会被提交

如果项目中所有文件被提交:

Snipaste_2022-06-09_16-07-03.png 证明工作区中所有的文件都处于“未修改”的状态,没有任何文件需要被提交。

3.8 对已提交的文件进行修改

目前,index.html等文件已经被 Git 跟踪,并且工作区和 Git 仓库中的 index.html等文件内容保持一致。当我们修改了工作区中 index.html 的内容之后,再次运行 git status 和 git status -s 命令,会看到如下的内容:

Snipaste_2022-06-09_16-16-21.png 文件 index.html 出现在 Changes not staged for commit 这行下面,说明已跟踪文件的内容发生了变化, 但还没有放到暂存区。

注意:修改过的、没有放入暂存区的文件前面有红色的 M 标记

3.9 暂存已修改的文件

目前,工作区中的 index.html 文件已被修改,如果要暂存这次修改,需要再次运行 git add 命令,这个命令 是个多功能的命令,主要有如下 3 个功效:

  1. 可以用它开始跟踪新文件
  2. 已跟踪的、且已修改的文件放到暂存区
  3. 把有冲突的文件标记为已解决状态

Snipaste_2022-06-09_16-20-53.png

3.10 提交已暂存的文件

再次运行 git commit -m "提交消息" 命令,即可将暂存区中记录的 index.html的快照,提交到 Git 仓库中进行保存:

Snipaste_2022-06-09_16-40-28.png

3.11 撤销对文件的修改--checkout

撤销对文件的修改指的是:把对工作区中对应文件的修改,还原成 Git 仓库中所保存的版本。 操作的结果:所有的修改会丢失,且无法恢复!危险性比较高,请慎重操作!

即放弃对本地已修改但尚未提交的文件的修改,并用最近一次的commit内容还原到当前工作区。
注意:  已 addcommit 的文件不适用个方法,应该用本文提到的第二种方法:回退

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 .     //将当前目录下所有在暂存区的文件移除暂存区

Snipaste_2022-06-09_19-34-15.png

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"

Snipaste_2022-06-09_21-01-23.png

注意:在最后面的:处按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

  1. git log 命令只能查看当前分支下的 commit 信息,查看其它分支 commit 需要切换分支;
  2. git reflog 可以查看所有分支的所有操作记录(包括已经被回退的 commit 记录和 reset 的操作);

例如执行 git reset --hard xxxx,退回到上一个版本,用git log则是看不出来被删除的commitid,用git reflog则可以看到被删除的commitid,我们就可以买后悔药,恢复到被删除的那个版本。

Snipaste_2022-06-09_21-16-22.png

3.15 跳过使用暂存区域

Git 标准的工作流程是工作区 → 暂存区 → Git 仓库,但有时候这么做略显繁琐,此时可以跳过暂存区,直接将工作区中的修改提交到 Git 仓库,这时候 Git 工作的流程简化为了工作区 → Git 仓库。 Git 提供了一个跳过使用暂存区域的方式, 只要在提交的时候,给 git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤

注意:是所有已经跟踪过的文件,之前未跟踪过的不行

git commit -a -m "输入备注"

Snipaste_2022-06-09_19-41-22.png

3.16 移除文件

即撤销 git commit 命令 从 Git 仓库中移除文件的方式有两种:

  1. 从 Git 仓库和工作区中同时移除对应的文件
  2. 只从 Git 仓库中移除指定的文件,但保留工作区中对应的文件
//从 Git 仓库和工作区中同时移除对应的文件
git rm -f 文件名
//只从 Git 仓库中移除指定的文件,但保留工作区中对应的文件
git rm --cached 文件名
----------------------------------------------------
git rm -f . //全部文件
git rm -r --cached . //全部文件

运行命令之前:

Snipaste_2022-06-09_19-49-14.png 运行git rm -f 文件名

Snipaste_2022-06-09_19-58-58.png

注意:该文件已经被标记为删除,下一次提交后工作区与仓库区就不再包含index.html

运行git rm --cached 文件名

Snipaste_2022-06-09_20-10-10.png

注意:该文件已经被标记为删除,下一次提交后仓库区就不再包含index.css,并且index.css文件变为未跟踪的状态。

3.17 忽略文件

项目中有些文件不应该存储到版本库中,Git中需要创建一个文件.gitignore配置忽略,一般与 .git 目录同级。

常见情况有:

  1. 临时文件.
  2. 多媒体文件,如音频,视频
  3. 编辑器生成的配置文件 (.idea)
  4. npm 安装的第三方模块 文件 .gitignore 的格式规范如下:
  5. 以 # 开头的是注释
  6. 以 / 结尾的是目录
  7. 以 / 开头防止递归
  8. 以 ! 开头表示取反
  9. 可以使用 glob 模式进行文件和文件夹的匹配(glob 指简化了的正则表达式)

3.17.1 glob 模式

所谓的 glob 模式是指简化了的正则表达式:

  1. 星号 * 匹配零个或多个任意字符
  2. [abc] 匹配任何一个列在方括号中的字符 (此案例匹配一个 a 或匹配一个 b 或匹配一个 c)
  3. 问号 ? 只匹配一个任意字符
  4. 在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配 所有 0 到 9 的数字)
  5. 两个星号 ** 表示匹配任意中间目录(比如 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 账号

  1. 访问 Github 的官网首页 github.com/
  2. 点击“Sign up”按钮跳转到注册页面
  3. 填写可用的用户名、邮箱、密码
  4. 通过点击箭头的形式,将验证图片摆正
  5. 点击“Create account”按钮注册新用户
  6. 登录到第三步填写的邮箱中,点击激活链接,完成注册

4.2 远程仓库的使用

4.2.1 新建空白远程仓库

  1. 在仓库首页点击左侧上方的NEW按钮,即可创建新仓库;

Snipaste_2022-06-10_09-48-26.png

  1. 在Repository name中输入仓库名,在Description中输入项目描述,点击Create repository创建成功Snipaste_2022-06-10_09-43-24.png

  2. 新建空白远程仓库成功

Snipaste_2022-06-10_09-50-17.png

4.2.2 远程仓库的两种访问方式

Github 上的远程仓库,有两种访问方式,分别是 HTTPSSSH。它们的区别是:

  1. HTTPS:零配置;但是每次访问仓库时,需要重复输入 Github 的账号和密码才能访问成功
  2. SSH:需要进行额外的配置;但是配置成功后,每次访问仓库时,不需重复输入 Github 的账号和密码

注意:在实际开发中,推荐使用 SSH 的方式访问远程仓库。

4.3 基于 HTTPS 将本地仓库上传到 Github

Snipaste_2022-06-10_10-16-44.png

   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形式上传

Snipaste_2022-06-10_10-44-54.png

解决方法:设置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

  1. 打开 Git Bash
  2. 粘贴如下的命令,并将 your_email@example.com 替换为注册 Github 账号时填写的邮箱:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com" 
  1. 连续敲击 3 次回车,即可在 C:\Users\用户名文件夹.ssh 目录中生成 id_rsa 和 id_rsa.pub 两个文件

Snipaste_2022-06-10_11-16-51.png

比如说我的就保存在: C:\Users\zgc99.ssh中

4.4.3 配置 SSH key

  1. 使用记事本打开 id_rsa.pub 文件,复制里面的文本内容
  2. 在浏览器中登录 Github,点击头像 -> Settings -> SSH and GPG Keys -> New SSH key
  3. 将 id_rsa.pub 文件中的内容,粘贴到 Key 对应的文本框中
  4. 在 Title 文本框中任意填写一个名称,来标识这个 Key 从何而来

4.4.4 检测 SSH key 是否配置成功

打开 Git Bash,输入如下的命令并回车执行:

ssh -T git@github.com

上述的命令执行成功后,可能会看到一些提示消息: 输入 yes 之后,如果能看到类似于下面的提示消息,证明 SSH key 已经配置成功了。

Snipaste_2022-06-10_11-27-50.png

4.4.5 上传测试

与之前操作相同,只是将 HTTPS 改为了 SSH

Snipaste_2022-06-10_11-44-46.png

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 只会拉取指定的分支内容

Snipaste_2022-06-10_11-37-58.png

注意:克隆之后进入该文件再进行操作 cd zgc

5. Git 分支

5.1 本地分支

5.1.1 分支的概念

分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努 力学习SVN。 如果两个平行宇宙互不干扰,那对现在的你也没啥影响。 不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN!

Snipaste_2022-06-10_17-01-56.png

5.1.2 分支在实际开发中的作用

在进行多人协作开发的时候,为了防止互相干扰,提高协同开发的体验,建议每个开发者都基于分支进行项目 功能的开发,例如:

Snipaste_2022-06-10_16-58-57.png

5.1.3 master/main 主分支

在初始化本地 Git 仓库的时候,Git 默认已经帮我们创建了一个名字叫做 master 的分支。通常我们把这个 master 分支叫做主分支,当我们上传到GitHUb的时候,会将master改为main(因为 master 有奴隶主的意思,涉嫌歧视黑人,政治正确。)

Snipaste_2022-06-10_17-06-49.png

在实际工作中,master 主分支的作用是:用来保存和记录整个项目已完成的功能代码。 因此,不允许程序员直接在 master 分支上修改代码,因为这样做的风险太高,容易导致整个项目崩溃。

5.1.4 功能分支

由于程序员不能直接在 master 分支上进行功能的开发,所以就有了功能分支的概念。 功能分支指的是专门用来开发新功能的分支,它是临时从 master 主分支上分叉出来的,当新功能开发且测试 完毕后,最终需要合并到 master 主分支上,如图所示:

Snipaste_2022-06-10_17-06-58.png

5.1.5 查看分支列表

使用如下的命令,可以查看当前 Git 仓库中所有的分支列表:

git branch //列出当前所有本地分支

git branch -a //查看所有分支

注意:分支名字前面的 * 表示当前所处的分支

Snipaste_2022-06-10_17-16-12.png

5.1.6 创建新分支

使用如下的命令,可以基于当前分支,创建一个新的分支,此时,新分支中的代码和当前分支完全一样

git branch 分支名称

注意:执行完创建分支命令后,用户所处的还是master主分支

Snipaste_2022-06-10_17-23-08.png

5.1.7 切换分支

使用如下的命令,可以切换到指定的分支上进行开发

git checkout 分支名称

Snipaste_2022-06-10_17-27-11.png

确保你当前分支工作区和缓存区是干净的:如果你的当前分支工作区和缓存区是干净的,也就是在当前分支 commit 之后再没做任何更改,你往别的分支切换时不会有影响的。但是如果你在当前分支有未完成的工作,也就是存在没有 add 或者 commit 的文件,你往 master 分支切换的时候,会把你在当前分支下未提交的工作也带过去。www.jianshu.com/p/a298cb3d9…

5.1.8 分支的快速创建和切换

使用如下的命令,可以创建指定名称的新分支,并立即切换到新分支上:

# -b表示创建一个新的分支
# checkout表示切换到刚才新建的分支上
-------------------------------------
git checkout -b 分支名称

注意: "git checkout -b 分支名称" 是下面 两条命令的简写形式:

  1. git branch 分支名称
  2. git checkout 分支名称

创建分支时最好切换到主分支进行创建

Snipaste_2022-06-10_17-37-08.png

5.1.9 合并分支

功能分支的代码开发测试完毕之后,可以使用如下的命令,将完成后的代码合并到 master 主分支上:

# 1.切换到master分支
git checkout master

# 2.在 master 分支上执行 git merge 命令,將要合并的分支的代码合并到master分支
git merge 分支名称

合并分支时的注意点:

  • 确保你当前分支工作区和缓存区是干净的,已经 addcommit 完成
  • 假设要把 C 分支的代码合并到 A 分支, 则必须先切换到 A 分支上,再运行 git merge 命令,来合并 C 分支!
  • 注意你的主分支名字是 master 还是 main 流程:
  1. 首先在 login 分支创建了 login.html 文件
  2. 暂存并提交,即:git addgit commit(很重要)
  3. 切换回主分支,注意主分支名称是master 还是 main
  4. 此时会发现在主分支下,login分支中新建的 login.html 文件消失
  5. 在主分支下运行 git merge login 合并分支 login分支:

Snipaste_2022-06-10_18-11-44.png

主分支: 少了login.html文件

Snipaste_2022-06-10_18-18-36.png

合并后的主分支:

Snipaste_2022-06-10_18-20-38.png

5.1.10 删除分支

当把功能分支的代码合并到 master 主分支上以后,就可以使用如下的命令,删除对应的功能分支:

git branch -d 分支名称

注意:

  1. 删除分支时你一定要保证自己不在那个被删除的分支上面
  2. 删除时确保该分支已经被合并到主分支了,否则会进行报错提示,可以使用 git branch -D 分支名称 进行强制删除

Snipaste_2022-06-10_23-01-17.png

5.1.11 遇到冲突时的分支合并

如果在两个不同的分支中,对同一个文件进行了不同的修改,Git 就没法干净的合并它们。 此时,我们需要打开 这些包含冲突的文件然后手动解决冲突。

# 假设再将 zgc 分支合并到 main 分支期间,代码发生了冲突
git checkout main
git merge zgc

# 打开包含冲突的文件,手动解决冲突之后,再执行如下的命令
git add .
git commit -m "解决了分支合并冲突的问题"

流程:

  1. 主分支更改了index.html文件,暂存并提交;
  2. zgc分支更改了index.html文件,暂存并提交;
  3. 切换回主分支,运行 git merge zgc,合并分支,发生冲突
  4. 在vscode打开项目进行选择,解决分支冲突
  5. 冲突解决后暂存并提交

Snipaste_2022-06-10_20-57-54.png

注:可以用ctrl + z 撤销选择,进行回退

Snipaste_2022-06-10_21-02-43.png

复杂情况:

  1. 如果冲突文件过多,可以使用 git status -sb 查看哪个/哪些文件冲突了
  2. 依次打开每个文件
  3. 搜索====四个等于号,找到冲突的地方
  4. 同上述情况,选择要保留的代码,删除不用的代码,删除 ==== >>>> <<<<这些标记
  5. git add 对应文件
  6. 再次 git status -sb 解决下一个文件冲突, git add 对应文件
  7. 直到没有冲突,运行 git commit

5.2 远程分支

5.2.1 将本地分支推送到远程仓库

如果是第一次将本地分支推送到远程仓库,需要运行如下的命令:

# -u 表示把本地分支和远程分支进行关联,只在第一次推送的时候需要带-u参数
git push -u 远程仓库的别名 本地分支名称:远程分支名称

# 实际案例
git push -u origin payment:pay

# 如果希望远程分支的名称和本地分支名称保持一致,可以对命令进行简化
git push -u origin payment

Snipaste_2022-06-10_21-19-20.png

注意:第一次推送分支需要带 -u 参数,此后可以直接在对应分支使用 git push推送当前分支的代码到对应的远程分支。完整版:www.yiibai.com/git/git_pus…

Snipaste_2022-06-10_21-19-58.png

5.2.2 查看远程仓库名称

git remote

Snipaste_2022-06-10_21-26-34.png

5.2.3 查看远程仓库中所有的分支列表

通过如下的命令,可以查看远程仓库中,所有的分支列表的信息:

git remote show 远程仓库名称

Snipaste_2022-06-10_21-22-21.png

5.2.4 跟踪分支

跟踪分支指的是:从远程仓库中,把远程分支下载到本地仓库中。需要运行的命令如下:

# 从远程仓库中,把对应的远程分支下载到本地仓库,保持本地分支和远程分支名称相同
git checkout 远程分支的名称 //如果本地有对应仓库是切换仓库

# 示例
git checkout pay
-----------------------------------------------------------------------------------------------
# 从远程仓库中,把对应的远程分支下载到本地仓库,并把下载的本地分支进行重命名
git checkout -b 本地分支名称 远程仓库名称/远程分支名称

# 示例
git checkout -b payment origin/pay

Snipaste_2022-06-10_22-22-08.png

5.2.5 拉取远程分支的最新的代码

git pull命令的作用是:取回远程主机某个分支的更新,再与本地的指定分支合并。默认模式下,git pullgit fetch后跟git merge FETCH_HEAD

# 从远程仓库,拉取当前分支最新代码,保持当前分支的代码和远程分支代码一致
git pull  //在哪个分支上运行,就拉取哪个分支的最新代码
//注意:这样写只会拉取当前所处分支的更新,不会拉取其他分支的更新代码

Snipaste_2022-06-10_22-38-34.png

完整版:

命令格式如下:

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

Snipaste_2022-06-10_22-56-49.png

5.2.7 将一个本地仓库上传至两个远程仓库

  1. 在github上创建两个远程仓库
  2. 在桌面创建一个文件,用vscode打开
  3. 新建终端,创建初始仓库并提交
  4. 输入github中提示的代码,注意两个仓库别名要修改成不一致的
  5. 上传本地仓库到main分支远程仓库origin1的main分支
  6. 上传本地仓库到zgc分支远程仓库origin2的zgc分支

Snipaste_2022-06-15_17-06-58.png

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就行
  • 编辑完成后:
    1. ESC + :w 保存,之后可以再按i进入编辑模式
    2. ESC + :q 退出
    3. ESC + :wq 保存并退出
    4. ESC + :q! 不保存并退出
  • 快捷键:
ctrl + insert //复制
shift + insert //粘贴

6.3 GitHub 团队协作

GitHub 团队协作开发也比较容易管理,可以创建一个组织

  • 首页 -> 右上角 + 号-> new Organization
  • 免费计划
  • 填写组织名称和联系方式(不用使用中文名称)
  • 邀请其他开发者进入组织,输入用户名搜索,发起邀请后会发送邮件给被邀请者确认
  • 点击组织右侧的 settings 设置
  • 左侧 Member privileges
  • 右侧 Base permissions 将read改为write👌,这样成员就对组织当中的仓库有写入权限
  • 最后在创建新仓库时,在Owner选择对应的组织就可以了

Snipaste_2022-06-15_17-46-40.png

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 开发分支: 开发者都在这个分支上提交代码

Snipaste_2022-06-15_22-02-45.png