夕阳无限好
Eason
阅读本文前应具有对Linux系统一定程度的了解.
本文面向第一次使用Git与Github的用户编写.
本文阅读时间可能偏长.
本文不是面向Linux系统以外的环境的教程.
Git
无论是txt、word、excel还是你的代码以及程序,只要涉及到版本管理那么便会让人搔首踟蹰、力不从心.
不信可视下文,
譬如我某次写的立项书:
大学生寒假社会实践立项书.xsxl
大学生寒假社会实践立项书_电子版.xsxl
大学生寒假社会实践立项书_书面版.xsxl
大学生寒假社会实践立项书_电子版_1.xsxl
大学生寒假社会实践立项书_电子版_2.xsxl
大学生寒假社会实践立项书_电子版_3.xsxl
大学生寒假社会实践立项书_书面版_1.xsxl
不仅含有两个分支,而且每次修改都要在文件名后置一个下标来标注;现在还只是管理两个分支总共两个文件的小项目,等到了有管理几百、几千、几万个文件的项目的需求时,这种做法实在是令人焦头烂额。
在此我们引入版本管理工具 Git,通过使用Git便可以极为方便的对项目版本进行管理
//没错(( 你的学术垃圾也可以用Git管理
Git ( /ɡɪt/ )[8] 是一个分布式版本控制系统[9],用于跟踪文件的版本。它通常被程序员用来控制源代码,以便协作开发软件。
Git 的设计目标包括速度、数据完整性以及对分布式、非线性工作流程的支持——成千上万的并行分支在不同的计算机上运行。[10][11][12]
与大多数其他分布式版本控制系统一样,与大多数客户端-服务器系统不同,Git 保持整个代码库(即 repo)的本地副本,具有历史记录和版本跟踪功能,独立于网络访问或中央服务器。每台计算机上的 repo 存储在一个标准目录中,并包含额外的隐藏文件以提供版本控制功能。Git 提供了在共享历史的 repo 之间同步更改的功能;这些 repo 是相互复制(克隆)而来的。为了协作,Git 支持与远程机器上的 repo 进行同步。尽管所有具有相同历史的 repo 是对等的,但开发人员通常使用中央服务器来托管一个 repo,以保存集成副本。
Git 是一个在 GPL-2.0-only 许可证下共享的免费开源软件。
Git 最初是由 Linus Torvalds 为 Linux 内核的开发而创建的版本控制工具。[14] "Git"商标由软件自由保护协会注册,标志着其在开源社区的正式认可和持续发展。
今天,Git 是事实上的标准版本控制系统。它是最受欢迎的分布式版本控制系统,截至 2022 年,近 95% 的开发者报告称它是他们的主要版本控制系统。它是专业开发者中使用最广泛的源代码管理工具。提供 Git 仓库服务的有 GitHub、SourceForge、Bitbucket 和 GitLab。
— 摘自wikipedia —
Git的安装与配置
若想使用Git,首先得安装Git
Linux系统可在终端键入以下命令一键安装:
$ sudo dnf install git-all
Debian的发行版如Ubuntu请使用apt
$ sudo apt install git-all
Windows系统请访问官网进行安装 Git 重申:本文不是面向Linux系统以外的环境的教程
安装完成后可以用以下命令检查是否安装成功
$ git -v
在正式使用之前,需要先使用git config配置邮箱与用户名
$ git config ---global user.name "username"
$ git config ---global user.email mail@mailaddress.domain
config 后的第一段 也就是–global的位置是标识配置的作用范围的标识符,其中
省略: 如果省略此项,则对本地仓库(当前仓库)生效
–global: 填入此项则为全局配置,对所有的仓库生效
–system: 填入此项则为系统配置,对所有的用户生效
第一行双引号内部的字符串常量username为你的用户名
第二行最后一块内容为你的邮箱,此两项自行修改即可
输入以下命令可以保存,避免每次使用都需要进行设置[存在安全隐患]
$ git config --global credential.help store
一切就绪后可以使用如下命令显示先前的设置确保无误
$ git config --global --list
开始建库
一切就绪以后我们就可以使用Git新建本地仓库了
Repositories意为版本库/仓库,我们取首四字符repo作简称,表示一个项目的仓库.
repo类似一个文件夹,但其内部所有的内容 全部都被Git所维护
每个文件的修改 删除 以及添加文件的操作 都可以被Git追踪到
这就可以让我们很方便的追踪项目历史 或是回溯先前的版本
创建一个repo非常简单 只需要一条7个字符的命令 然后就可以把一个文件夹变成git所管理的本地仓库
$git init
或者,你可以直接从远程服务器上clone一个以及存在的仓库
$ git clone /* url */
值得注意的是,不同版本的Git在init一个项目的时候 主要分支的名称可能不一样,可能为master或main,这两个名称是等价的,因此无需在意此方面的偏差.
你也可以在config里设置此项,来令初始的主分支自动命名为main
$ git config --global init.defaultBranch main
此时使用ls -a命令可以看到一个名为.get的隐藏文件夹 便说明本地仓库已经建立完成
\rm -rf .get删除 .git文件可以表明当前文件夹不再是一个repo
git init 后还可以填入指定的文件名称 如果填入了则会在当前文件夹下新建一个指定名称的文件夹 此文件夹内部包含一个.get文件夹
Git的工作区域与文件状态
Git的本地数据管理分为三个区域
Git
|---------工作区 Working Directory
|---------暂存区 Starting Area/Index
|---------本地仓库 Local Repositories
工作区 也叫工作目录或本地目录,资源管理器看到的repo所在的文件夹就是一个工作区
暂存区 是一种临时存储区域 用于保存即将提交到Git仓库的修改内容 类似C++ 输入输出流中的缓冲区 暂存区是在Git进行版本控制时非常重要的一个区域 .git/index
本地仓库 即为使用git init 建立的仓库 其包含了完整的项目历史和元数据 .git/objects
完成一次文件的编辑后 我们需要使用一次git add 把变更的信息添加到暂存区内
然后再使用git commit把信息从暂存区移至本地仓库
在这个过程中我们可以使用Git的查看、比较以及撤销操作来保证版本控制的准确性和完整性
于是相应的 Git管理的文件存在以下几种状态
1.未跟踪 Untrack
2.未修改 Unmodified
3.已修改 Modified
4.已暂存 Staged
未跟踪状态的文件是没有被Git所管理的文件
未修改状态的文件是已经被Git所管理但内容没有发生变化
已修改状态的文件是已经被Git所管理且内容已经发生变化但未放入暂存区的文件
已暂存状态的文件是修改后且已经放入暂存区的文件
添加和提交文件
在了解上述内容后,我们就可以尝试为repo添加和提交文件了
总共涉及三个基础命令
$ git status 查看仓库状态
$ git add 添加文件
$ git commit 提交文件
在一个刚刚init的空repo中 键入git status会是如下情景
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)
此时文件夹为空,添加任一文件后status中会出现一列Untrack files内容(自行尝试)其中的文件/文件夹会被标红
使用git add命令可以追踪一个Untrack的文件 将其添加到暂存区内
status中便会出现一行标绿的new file ,此时新文件就已经被置入了暂存区
放入暂存区后文件还需要提交 这时候就要使用git commit了 我们的文件只有提交到本地仓库之后才真正的被git所管理了起来
commit只能对暂存区的文件进行操作 同时每commit一次都需要提供一个信息 具体操作如下
$ git commit -m "message" filename
如果不提供-m选项则会进入一个交互式界面 默认会使用vim来编辑提交的message
git add 与git commit还可以接受通配符作为文件名的某一部分来进行操作
如过要查看commit历史 则可以键入如下命令
$ git log
$ git log --oneline 此参数可以将每次commit的信息放在一行内
回退版本
仅仅是添加和提交还不能满足我们项目的需求
倘若某天我们提交了一个错误文件,此时我们又没有先前文件的备份
仅仅依靠脑力弥补是不能胜任的
我们于是又引入一个命令
$ git reset --soft
$ git reset --hard
$ git reset --mixed
reset 命令用于回退版本 其中
soft参数用于表示回退到某一个版本 并且保留工作区和暂存区的所有修改内容
hard参数用于表示回退到某一个版本 并且丢弃工作区和暂存区的所有修改内容
mixed参数用于表示回退到某一个版本 并且丢弃暂存区但保留工作区的所以修改内容,mixed参数同时也是reset的默认参数,也就是说不置选项时会默认为mixed模式
如果我们不小心–hard回退了一个版本 则可以通过reflog查看操作之前的版本号之后再用reset回退
$ git reflog
查看差异
在此引入一个命令 diff
$ git diff
diff不仅可以查看 工作区 暂存区 本地仓库之间的差异
还可以查看 不同版本、不同分支之间的差异
有很多GUI工具可以很方便的图形化的查看它们之间的差异
当然 即使在终端内部diff的优势也是显而易见
无给定参数的diff默认显示工作区和暂存区的差异 我们作出如下的测试
diff --git a/newtest.txt b/newtest.txt
deleted file mode 100644
index 3b2aed8..0000000
--- a/newtest.txt
+++ /dev/null
这段提示词是在我删掉工作区已经添加且提交的newtest.txt文件后显示的diff 我们诸行解释
第一行用于显示所有发生了变更的文件
第二行用于显示所发生的操作
第三行为文件的40位哈希 “..” 内为省略的内容
第四行起为其内容的差异 如果是修改文件而非删除文件 则最下方会给出不同颜色的字符串 绿色为添加 红色为删除
如果给定了HEAD参数 则会令当前工作区和最新一次提交的本地仓库进行比较
$ git diff HEAD
如果给定了–cached参数 则会令当前暂存区与最新一次提交的本地仓库进行比较
$ git diff --cached
如果给定了 两个版本号作为参数 则会令两个版本进行比较//你当然可以比较两个一样的版本 但是没什么意义
$git diff versioncode1 versioncode2
你可以理解HEAD 为一个当前最新版本号的宏 因此在比较两个版本的时候也可以使用HEAD为一个参数
Git也给出了HEAD~和HEAD^作为前一个版本号的宏,比较代码仓库里的最新两个版本只需要把第一个参数置为HEAD~ 再把第二个参数置为HEAD 即可
HEAD~/HEAD^ 后放置数字 如HEAD~5 则为往前第五个版本号的宏 (可以理解成当前最新的版本号的下标为0,HEAD~n为下标为n的版本)
再在后面追加一个文件名(适用通配符) 则可以比较指定文件在不同版本号之间的差别
$git diff commit_hash1 commit_hash2 filename
如果想查看两个分支之间的差异 则把commit_hash换成分支名即可
$git diff branchname1 branchname2 filename