0%

git用法浅析

前言

本文主要记录git常见的基础用法以及如何离线在linux上安装git。

本文旨在让人成为git使用者而不是git使用专家,所有命令基本都是充分且必要的。

  1. git是什么
  2. linux离线安装git
  3. git基本用法

git是什么

  Git是目前世界上最先进的分布式版本控制系统。所谓版本控制,打个简单的比方:修改一份文件,我们往往会另存为很多个备份,每个备份可能代表一个版本,如图所示:

 这导致了两个严重的问题:第一,你不知道这些文件的每个版本都有谁改动过;第二,过了一段时间,你自己都不知道这些文件代表啥, 但是你还不敢删。我们希望文件的管理是这样的:每次文件的改动都有相应的记录,不仅记录了是谁改了文件,还要有改动文件的说明,看起来就像这样。

  简而言之,git就是干这活的,把每个文件都想这样管理起来,这样我们只需要保存两样东西:

  • 一份最新的文件
  • 这份文件所有的历史改动信息

  这里说一下,git比svn好在哪里。

  SVN是典型的集中式的版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。

  那分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。

  和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。

  在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已

  而且git最有用的是其强大的分支管理,而SVN全在同一条分支上进行开发,非常混乱。

linux离线安装git

  啥都不说了,工作需要,一般情况用不到这种安装方式,这里记录一下,防止忘记。步骤如下:

  1. git官网下载linux下git安装包(.tar.gz),不要下载.rpm,因为公司电脑没有rpm。
  2. 安装步骤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 解压: xxx自己换成下载的版本
tar -zxvf git.xxx.tar.gz

# 安装路径: 自己选安装在哪,我给装的都是在/home/git
cd git-xxx
./configure --prefix=/home/git

# 安装
make && make install

# 配置环境变量
vim /etc/profile
## 这里java自己配
export GIT_HOME=/usr/local/git
export PATH=$JAVA_HOME/bin:$PATH:$GIT_HOME/bin
## 激活环境变量
source /etc/profile

# 检查有没有装好
git --version

git基本用法

配置用户并生成公钥私钥

  安装好git后第一件事就是把全局的user配置了,不然无法上传代码。

  git基于ssh连接,配置公钥到远程仓库中可以省去认证。这里不讲怎么放,只讲怎么生成。

1
2
3
4
5
6
# 配置用户
git config --global user.name "xxx"
git config --global user.email "xxx@yyy.com"

# 输入命令后一路回车,公钥在 ~/.ssh 文件夹下
ssh-keygen -t rsa -C "xxx@yyy.com"

git版本库

  每个人使用git的时候,会在项目中创建一个git版本库,这个库是实际可以理解为一个.git文件夹,git的所有操作,都是对这个.git文件夹进行修改。当我们用git来进行项目管理时,版本库会把这个项目分成三个区域,如图所示:

  工作区就是我们的文件夹,暂存区(stage)和最终的提交区域就是我们的git版本库,这里的控制都是在.git中进行的,请注意区分工作区和版本库,这两个概念是不同的。图中add、commit、HEAD等下文再讲。看到这里我们应该清楚了一个git仓库的基本结构。

创建git版本库

  命令:git init。这个命令可以创建一个纯净的git版本库,运行这个命令后,会在这个文件夹下生成一个.git文件夹,这说明你的这个文件夹可以开始被git管理了。这里值得注意的是,运行这个命令后,不管你的文件夹下有没有内容,.git初始化后始终是一个纯净的空仓库。

我们可以通过git status命令来查看git版本库的情况。

1
2
3
4
5
6
7
git init
已初始化空的 Git 仓库于 /Users/memoforward/Project/test/testgit/temp/.git/

git status
位于分支 master
尚无提交
无文件要提交(创建/拷贝文件并使用 "git add" 建立跟踪)

把文件添加到版本库并提交

先在工作区创建一个新文件.gitignore

通过git add将修改的内容从工作区添加到git版本库的暂存区

1
2
3
4
5
6
7
8
9
10
git add 文件名+后缀

*********实例**********
git add .gitignore
git status
位于分支 master
尚无提交
要提交的变更:
(使用 "git rm --cached <文件>..." 以取消暂存)
新文件: .gitignore

通过git commit暂存区的内容提交到最终的区域,并添加提交说明

1
2
3
4
5
6
7
8
9
10
git commit -m "提交说明"

git commit -m "添加gitignore"
[master(根提交) c92669e] 添加.gitignore
1 file changed, 1 insertion(+)
create mode 100644 .gitignore

git status
位于分支 master
无文件要提交,干净的工作区

此时我们的git项目就通过本地git仓库进行了管理

回滚

  我们可能不小心提交了一个错误的版本(即最新的版本存在问题),为了保证git仓库中最新的版本是稳定的,我们在短期内搞不定的情况,就要对版本进行回滚。

  PS:其实在自己本地的库上影响不严重,但是在远程的库上若有这种问题,则情况就非常严重,因为一般情况下,远程库中的git就是线上的版本,线上出问题,一般很难定位。此时,回滚是一个兜底策略,非常重要。

版本回退

  一个项目可能有很多人在进行开发,会进行成百上千次提交,每次提交就是一个版本,我们不可能记得住每个版本都修改了哪些内容,但是git能帮我们记住,只需要输入git log 就行。

1
2
3
4
5
6
7
8
9
git log
# 将日志一行显示,更加简洁,我喜欢加上这样的命令, 但是看不到作者信息了
git log --oneline

3fc2d100b (HEAD -> master, origin/master, origin/HEAD) enable Github Action for Unit test (#6726)
a2a14dcb4 add short/byte data type support for PojoUtils#getDefaultValue (#6551)
b14e53443 fix boolean data type issue for Pojoutils.java#getDefaultValue
4a265a52b update dubbo-provider.xml for demo (#6857)
1a3949ebb remove impossible reach branch and the useless variable for RedisRegistry.java (#6862)

  这个命令能让你看到所有的提交,commit后面可以理解为版本号,以下包括作者提交时间以及提交说明。这就体现了每次提交都写提交说明的重要性,为了方便我们对每次版本进行查看。

  当我们获取到了该一个git项目所有历史版本号之后,我们就可以把git提交区域的版本回退到特定历史。下面介绍回退版本的命令:

1
2
3
4
git reset --hard HEAD^ # 回退到上个版本
git reset --hard HEAD^^ # 回退到上上个版本
git reset --hard HEAD~10 # 回退到10个版本以前
git reset --hard commit_id # 可以调到任意一个版本,可以回退可以前进

  git版本回退的原理是维护一个指向版本的指针,这个指针名叫HEAD,git保存的不是每次版本的文件,而是保存每次版本的修改,因此十分高效,如下图所示:

1
2
3
4
5
6
graph BT
subgraph table
commit_id2 ---> commit_id1
commit_id3 ---> commit_id2
end
HEAD((HEAD)) ---> commit_id2