Git 初步教程

时光机,启动!

版本控制系统(VCS)概述

一个小情景

设想一下,如果你写了一个程序,它会有一个甚至多个源代码文件:

在这之后,你把它发布了(比如交作业)。
但是老师看完后,发现缺了功能,让你再进行修改;
你改完,又将它交上去了,但是老的功能又出了bug。
你很无奈,准备把它改回去,再在其基础上进行修改。

这时候,你发现自己的第一版源代码被覆盖掉了!!
然后你忘记了原来是怎样写的,遂PDF并重写。。

你发现,如果在第一版文件写成后将其存档,记为一个版本,这样就不会发生这种事了。
你可以在第二版被驳回后,返回到第一版并继续修改。
当然Git的功能远不止这些。

VCS概念

有时候,一个程序同时存有两个以上的版本有其必要性,例如:发布版本中程序错误已经被修正,但没有加入新功能;而开发版本则有新的功能正在开发、也有新的错误待解决,于是便需要同时维护两个不同的版本。

此外,为了找出只存在于某一特定版本中的程序错误、或找出程序错误出现的版本,开发人员也必须通过比对不同版本的源代码以找出问题的位置。

我们可以使用版本控制器来:

  • 对一个目录中的内容创建不同版本
  • 创建不同的时间线(分支)
  • 切换到任意版本/分支
  • 比较各个版本中文件的差异

Git

我们要讲的Git,就是软件版本控制器中最著名的一个,也是应用最广的一个。
它由Linus Torvalds(Linux kernel项目创始人、主力开发者)使用C语言写成。
它负责管理了从Linux kernel v2.6至今的代码。
它是分布式的,意味着我们可以从其他机器获取更新版本的代码以及把我们的代码传输至其他机器上。

安装

首先要知道你使用的是什么平台。
各个平台的安装方式都是不同的。

Linux

  1. Debian/Ubuntu:
    1
    2
    3
    sudo apt update
    sudo apt install git
    # 然后看提示,按Y键、回车
  2. RHEL/Rocky Linux/Alma Linux/CentOS/Fedora
    1
    2
    3
    4
    5
    sudo dnf up
    sudo dnf in git
    # 如果无法正常运行,可能是版本太老,请使用以下命令
    sudo yum update
    sudo yum install git
  3. Arch Linux/Manjaro
    1
    2
    3
    sudo pacman -Sy
    sudo pacman -S git
    # 回车
  4. openSUSE/SLE
    1
    2
    sudo zypper up
    sudo zypper in git
  5. Gentoo Linux
    1
    sudo emerge -a dev-vcs/git

之后执行git --version
如果有以下输出,安装就完成了:

macOS

当然这需要新的macOS版本;
如果你还在用Catalina,请务必更新。

1
xcode-select --install

这样,执行:git --version

就对了。

Windows

  1. 如果是Windows 11并且使用了魔法,那么你大概是可以使用winget的。这是很方便的。
    Win + R输入powershell

    1
    winget install --id Git.Git -e --source winget

    即可。

  2. 如果不幸的事,你不喜欢更新,在使用老掉牙的1803版Windows 10,或者不能使用魔法:
    https://git-scm.com/download/win 下载适应你OS的版本。

    一般人下载第二个就可,之后一路无脑Next。

使用

初始化

你新建了一个文件夹,你将在里面放置你要管理的文件(或者已经放置了)
如何让Git管理它呢?使用下面命令即可让Git接管它。

1
git init


现在,目录下多了一个.git文件夹,它就是负责存放Git的配置文件以及相关版本数据的。

添加文件到仓库

我们现在添加一个文件test进去,它的内容是:

1
2
3
This is a test file.
Now, its version is:
1

记住现在它的版本是1。
如果你在使用一些“花里胡哨”的shell插件,比如omz,你会发现:

Git发现有一个文件被更改了。
这时候它还没有把这个文件记录在案,我们需要这样把一个文件加入仓库

1
git add test

test文件就被加入仓库了。
如果那你想把目录下的全部文件加入仓库,执行:

1
git add .

这样全部文件都会加进来。

提交

好的,你的这份作业已经写好,正准备交给老师。
现在我们需要把这堆文件记录成一个版本,也就是提交动作。

1
git commit -m "Version 1!加入test文件"

后面的-m参数是必加不可的,它是用来描述这个版本大概是做了什么的。
这两个引号,必须是英文的。
当然随便写命令也可以执行成功,但是不建议这么做。
因为到后面你可能看不懂这个版本是干什么的。

这样这个版本就被存储了下来。

修改与回档(版本回退)

不幸,老师不认可你这份作业。你需要改进它,于是你修改test文件:

1
sed -i '' 's/1/2/g' test

这个属于sed替换文本,看不懂无视就好。

现在test文件已经是第二版了!

现在我们可以看到,我们的文件内容中的“1”变成了“2”,同时Git也发现了这个文件更改。
好了,我们再重复上一步提交。

1
2
git add .
git commit -m "Version 2!修改test文件"

老师看了一下,原来他的不认可是来自于一个拼写错误:it’s => its,并非不满意那个版本号。
看来并不需要修改版本号,只需要修改拼写错误就行。

有同学会觉得这是小题大做了,我只修改个版本号为什么要用Git回退,直接改一下不就行了么?

我这里只是在演示功能。如果你写一些大的工程,很多地方的语句&调用函数等可能经过比较大程度的修改甚至覆盖。
这样做可以完全回到原来的状态。

Git用HEAD表示当前的版本。前一个版本就是HEAD^,前两个版本就是HEAD^^。
往前100个版本可以写100个^,但是这肯定是不易数的,所以可以写成HEAD~100。

我们往前退一个版本,而且要回到前一个版本的已提交状态,所以我们:

1
git reset --hard HEAD^

现在查看下test文件的内容:

--hard参数会回退到上个版本的已提交状态,--soft会回退到上个版本的未提交状态,--mixed会回退到上个版本已添加但未提交的状态。

然后你修改文件再提交:

1
2
3
sed -i '' "s/its/it's/g" test
git add .
git commit -m "Commit 2: fix spell issue."

你可能觉得写HEAD^的方法过于笨拙,当然还有一种方法可以解决:

1
git log


当然在这里,你的commit id和我的不会一样。
之后,如果你想回到哪个版本,就:

1
git reset --hard 版本commit id

这里的commit id不需要写全,当然写一两个字母也不行。主要是让Git分辨出来特定版本,又不与别的版本混淆就行。
比如前6个字符大概就可。

远程仓库

你可能听说过一些平台,比如 Github, Gitlab等,这些都是Git远程仓库平台。
那么,如何使用这些远程仓库呢?

Clone(克隆)

没错,命令就是git clone
后面接链接与本地目标目录。
比如,从Github克隆Linux内核的仓库到当前用户主目录下:

1
git clone https://github.com/torvalds/linux.git ~/linux

这后面名字可以自己起,但是建议维持原名,最多只在其基础上加点东西。
现在,远程的目录就被1:1复刻到你这里来了。

Pull(拉取)

过了一段时间,Linux内核源码的仓库更新了,而你的仓库还是旧版本,这时候该如何同步?
切换到仓库目录下,运行:

1
git pull

这样仓库就会更新了。

Push(推送)

显然,Linux内核源码仓库是很严格的,只有官方人员才能提交代码。
所以,我们自己创建一个Github仓库用于演示:

创建之后,是这样的:

你看它下面都写出来了,如何给本地仓库设置远程:

1
2
3
git remote add origin https://github.com/zlicdt/Test.git
git branch -M main
git push -u origin main

这样,远程仓库这辈子就有了。

(请忽略我用老邮箱进行提交导致的头像变动

另请注意

Github应该是在很久以前(似乎是2020-2021年间)禁止了只使用用户名+邮箱进行的提交。
我们可能遇到相关提示,并且有一大堆很麻烦的操作。
表面上是为了安全,实际上却是安全了,但更多的是推自家的github-cli,它可以概括为让你在CLI登录Github账号,从而正常进行推送。
建议都装一个。

更新中,敬请期待……


Git 初步教程
https://blog.zlicdt.top/2024/08/21/git-guide/
作者
zlicdt
发布于
2024年8月21日
许可协议