Git 初步教程
时光机,启动!
版本控制系统(VCS)概述
一个小情景
设想一下,如果你写了一个程序,它会有一个甚至多个源代码文件:
在这之后,你把它发布了(比如交作业)。
但是老师看完后,发现缺了功能,让你再进行修改;
你改完,又将它交上去了,但是老的功能又出了bug。
你很无奈,准备把它改回去,再在其基础上进行修改。
这时候,你发现自己的第一版源代码被覆盖掉了!!
然后你忘记了原来是怎样写的,遂PDF并重写。。
你发现,如果在第一版文件写成后将其存档,记为一个版本,这样就不会发生这种事了。
你可以在第二版被驳回后,返回到第一版并继续修改。
当然Git的功能远不止这些。
VCS概念
有时候,一个程序同时存有两个以上的版本有其必要性,例如:发布版本中程序错误已经被修正,但没有加入新功能;而开发版本则有新的功能正在开发、也有新的错误待解决,于是便需要同时维护两个不同的版本。
此外,为了找出只存在于某一特定版本中的程序错误、或找出程序错误出现的版本,开发人员也必须通过比对不同版本的源代码以找出问题的位置。
我们可以使用版本控制器来:
- 对一个目录中的内容创建不同版本
- 创建不同的时间线(分支)
- 切换到任意版本/分支
- 比较各个版本中文件的差异
Git
我们要讲的Git,就是软件版本控制器中最著名的一个,也是应用最广的一个。
它由Linus Torvalds(Linux kernel项目创始人、主力开发者)使用C语言写成。
它负责管理了从Linux kernel v2.6至今的代码。
它是分布式的,意味着我们可以从其他机器获取更新版本的代码以及把我们的代码传输至其他机器上。
安装
首先要知道你使用的是什么平台。
各个平台的安装方式都是不同的。
Linux
- Debian/Ubuntu:
1
2
3sudo apt update
sudo apt install git
# 然后看提示,按Y键、回车 - RHEL/Rocky Linux/Alma Linux/CentOS/Fedora
1
2
3
4
5sudo dnf up
sudo dnf in git
# 如果无法正常运行,可能是版本太老,请使用以下命令
sudo yum update
sudo yum install git - Arch Linux/Manjaro
1
2
3sudo pacman -Sy
sudo pacman -S git
# 回车 - openSUSE/SLE
1
2sudo zypper up
sudo zypper in git - Gentoo Linux
1
sudo emerge -a dev-vcs/git
之后执行git --version
:
如果有以下输出,安装就完成了:
macOS
当然这需要新的macOS版本;
如果你还在用Catalina,请务必更新。
1 |
|
这样,执行:git --version
就对了。
Windows
如果是Windows 11并且使用了魔法,那么你大概是可以使用
winget
的。这是很方便的。
按Win + R
输入powershell
,1
winget install --id Git.Git -e --source winget
即可。
如果不幸的事,你不喜欢更新,在使用老掉牙的1803版Windows 10,或者不能使用魔法:
从 https://git-scm.com/download/win 下载适应你OS的版本。
一般人下载第二个就可,之后一路无脑Next。
使用
初始化
你新建了一个文件夹,你将在里面放置你要管理的文件(或者已经放置了)
如何让Git管理它呢?使用下面命令即可让Git接管它。
1 |
|
现在,目录下多了一个.git文件夹,它就是负责存放Git的配置文件以及相关版本数据的。
添加文件到仓库
我们现在添加一个文件test
进去,它的内容是:
1 |
|
记住现在它的版本是1。
如果你在使用一些“花里胡哨”的shell插件,比如omz,你会发现:
Git发现有一个文件被更改了。
这时候它还没有把这个文件记录在案,我们需要这样把一个文件加入仓库:
1 |
|
test
文件就被加入仓库了。
如果那你想把目录下的全部文件加入仓库,执行:
1 |
|
这样全部文件都会加进来。
提交
好的,你的这份作业已经写好,正准备交给老师。
现在我们需要把这堆文件记录成一个版本,也就是提交动作。
1 |
|
后面的-m
参数是必加不可的,它是用来描述这个版本大概是做了什么的。
这两个引号,必须是英文的。
当然随便写命令也可以执行成功,但是不建议这么做。
因为到后面你可能看不懂这个版本是干什么的。
这样这个版本就被存储了下来。
修改与回档(版本回退)
不幸,老师不认可你这份作业。你需要改进它,于是你修改test
文件:
1 |
|
这个属于sed替换文本,看不懂无视就好。
现在test
文件已经是第二版了!
现在我们可以看到,我们的文件内容中的“1”变成了“2”,同时Git也发现了这个文件更改。
好了,我们再重复上一步提交。
1 |
|
老师看了一下,原来他的不认可是来自于一个拼写错误:it’s => its,并非不满意那个版本号。
看来并不需要修改版本号,只需要修改拼写错误就行。
有同学会觉得这是小题大做了,我只修改个版本号为什么要用Git回退,直接改一下不就行了么?
我这里只是在演示功能。如果你写一些大的工程,很多地方的语句&调用函数等可能经过比较大程度的修改甚至覆盖。
这样做可以完全回到原来的状态。
Git用HEAD表示当前的版本。前一个版本就是HEAD^,前两个版本就是HEAD^^。
往前100个版本可以写100个^,但是这肯定是不易数的,所以可以写成HEAD~100。
我们往前退一个版本,而且要回到前一个版本的已提交状态,所以我们:
1 |
|
现在查看下test
文件的内容:--hard
参数会回退到上个版本的已提交状态,--soft
会回退到上个版本的未提交状态,--mixed
会回退到上个版本已添加但未提交的状态。
然后你修改文件再提交:
1 |
|
你可能觉得写HEAD^
的方法过于笨拙,当然还有一种方法可以解决:
1 |
|
当然在这里,你的commit id和我的不会一样。
之后,如果你想回到哪个版本,就:
1 |
|
这里的commit id不需要写全,当然写一两个字母也不行。主要是让Git分辨出来特定版本,又不与别的版本混淆就行。
比如前6个字符大概就可。
远程仓库
你可能听说过一些平台,比如 Github, Gitlab等,这些都是Git远程仓库平台。
那么,如何使用这些远程仓库呢?
Clone(克隆)
没错,命令就是git clone
。
后面接链接与本地目标目录。
比如,从Github克隆Linux内核的仓库到当前用户主目录下:
1 |
|
这后面名字可以自己起,但是建议维持原名,最多只在其基础上加点东西。
现在,远程的目录就被1:1复刻到你这里来了。
Pull(拉取)
过了一段时间,Linux内核源码的仓库更新了,而你的仓库还是旧版本,这时候该如何同步?
切换到仓库目录下,运行:
1 |
|
这样仓库就会更新了。
Push(推送)
显然,Linux内核源码仓库是很严格的,只有官方人员才能提交代码。
所以,我们自己创建一个Github仓库用于演示:
创建之后,是这样的:
你看它下面都写出来了,如何给本地仓库设置远程:
1 |
|
这样,远程仓库这辈子就有了。
(请忽略我用老邮箱进行提交导致的头像变动
另请注意
Github应该是在很久以前(似乎是2020-2021年间)禁止了只使用用户名+邮箱进行的提交。
我们可能遇到相关提示,并且有一大堆很麻烦的操作。
表面上是为了安全,实际上却是安全了,但更多的是推自家的github-cli,它可以概括为让你在CLI登录Github账号,从而正常进行推送。
建议都装一个。