Git图解:安装与基本操作(一)


这个博客系列,分享的Git操作,这不是简单的指令罗列,小编通过画图和问题回答的方式对Git指令使用原理的总结,希望能够帮助到大家!有错误的地方也请大家多多指正!有帮助到您,也请点赞支持!

1.为什么用Git

当我们在学习过程中,需要完成老师交给我们的任务:
在这里插入图片描述
在这里插入图片描述

这时候为了避免手动管理我们需要版本控制器,而Git就是一个版本控制器,它是目前主流的!

Git 是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目,它 可以控制电脑上所有格式的⽂件。但是对于程序猿来说更多的是管理我们源代码。

2.安装Git
2.1.CentOS下安装

查看 Git 安装的版本:

[xiyan@hecs-34711 ~]$ git --version

CentOS安装Git :

[xiyan@hecs-34711 ~]$ sudo yum install git -y
2.2.ubuntu下安装

查看 Git 安装的版本:

xiyan@ubuntu:~$ git --version

安装Git :

xiyan@ubuntu:~$ sudo apt-get install git -y
3.基本操作
3.1.创建并初始化仓库

仓库是进⾏版本控制的⼀个⽂件⽬录。 所以使用Git版本控制,首先要创建一个目录,但是mkdir创建出来的只是普通的目录,我们需要初始化仓库。

  • 创建普通目录并进入目录:
[xiyan@hecs-34711 ~]$ mkdir git_space
[xiyan@hecs-34711 ~]$ cd git_space
[xiyan@hecs-34711 git_space]$ pwd
/home/xiyan/git_space
  • 使用git init命令就初始化了一个Git仓库:
[xiyan@hecs-34711 git_space]$ git init
  • 查看刚初始化的.git的文件结构:
[xiyan@hecs-34711 git_space]$ ls -a
[xiyan@hecs-34711 git_space]$ tree .git
.git
├── branches
├── config
├── description
├── HEAD
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags
3.2.工作区、暂存区、版本库

配置Git:

当初始化一个仓库后先要设置你的 ⽤⼾名称 和 e-mail 地址,使用–global参数表⽰这台机器上所有的 Git 仓库都会使⽤这个配置。

git config [--global] user.name "Your Name" 
git config [--global] user.email "email@example.com"

查看配置命令为:

git config -l

删除对应的配置命令为:

git config [--global] --unset user.name
git config [--global] --unset user.email

当我们初始化git_sapce目录,并在其下创建一个read文件,那么这个read文件能否别Git管理?

[xiyan@hecs-34711 git_space]$ touch read
[xiyan@hecs-34711 git_space]$ ls -a
.  ..  .git  read

答案是不能!

如果需要理解为什么那么我们需要弄清楚工作区、暂存区、版本库这三个概念,注意理解这些概念能更加清晰的使用指令!

在上面我们通过指令ls -a将git_space目录下的文件都列举出来。其中隐藏目录 .git称之为版本库(仓库);把git_space目录下除.git目录,我们都称之为工作区;而暂存区(stage或 index),一般存放在(.git/index)路径下。 对于一个刚初始化的仓库,我们是用tree .git并不能找到对应的index文件,但是通过命令:

[xiyan@hecs-34711 git_space]$ git add read
[xiyan@hecs-34711 git_space]$ git commit -m "the first commit of read" # 这里为了能统一些,可以先commit,不用commit,add就能生成index文件。
[xiyan@hecs-34711 git_space]$ tree .git

将工作区的内容添加到暂存区我们tree命令就能查看到二进制文件index。

我们通过一张原理图快速的理解三者的关系:
在这里插入图片描述

  • 在创建 Git 版本库时,Git 会为我们⾃动创建⼀个唯⼀的 master 分⽀,以及指向 master 的⼀个指针叫 HEAD。

  • 想要让Git管理文件,必须要通过使⽤ git add 和 git commit 命令才能将⽂件添加到仓库中!在版本库(仓库)中的文件⽂件被 Git 管理起来,可以对每个⽂件的修改、删除进行跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

    我们wirte新建一个文件并写入 “绝知此事要躬行!”:

    [xiyan@hecs-34711 git_space]$ git status    # 查看当前仓库状态
    [xiyan@hecs-34711 git_space]$ vim wirte
    [xiyan@hecs-34711 git_space]$ git add write # 添加write 
    [xiyan@hecs-34711 git_space]$ git status
    [xiyan@hecs-34711 git_space]$ git commit -m "the wirte file commit"
     1 file changed, 1 insertion(+)
     create mode 100644 write
    说明:一个文件改变,插入一行内容
    

    至此我们就将工作区中的write文件添加到了版本库中,并让git进行管理。

  1. 使用git add 命令可以将⽂件添加到暂存区:

    • 添加⼀个或多个⽂件到暂存区: git add [file1] [file2] ...
    • 添加指定⽬录到暂存区,包括⼦⽬录: git add [dir]
    • 添加当前⽬录下的所有⽂件改动到暂存区: git add .
    
  2. 再使⽤ git commit 命令将暂存区内容添加到本地仓库中:

    • 提交暂存区全部内容到本地仓库中: git commit -m "message"
    • 提交暂存区的指定⽂件到仓库区: git commit [file1] [file2] ... -m "message"
    

    注意:必须要带上-m选项,并好好的描述你提交内容的信息! 如果你忘记带-m选项,那么也会跳出一个窗口让你提交描述细节

3.3.查看日志和.git

上面我们已经知道如何将工作区中的文件上传到仓库中,交给git管理,在上传的过程中也适当的通过git status来验证是否上传成功了,但:

你说将文件传到了.git仓库中,具体存放在哪里?能不能看得到?请往下看!

先来看看,我们上传文件的日志

[xiyan@hecs-34711 git_space]$ git log
commit 2f6e2d2cf3b01c2e7e6320415d35b3610a69aee0
Author: xiyan <3219576710@qq.com>
Date:   Sun Dec 24 10:52:53 2023 +0800

    the wirte file commit # commit填写的描述信息

显⽰从最近到最远的提交⽇志,这里截取了最新的日志。如果你觉得这样输出详细的日志太凌乱,那么你可以带上参数:

[xiyan@hecs-34711 git_space]$ git log --pretty=oneline
2f6e2d2cf3b01c2e7e6320415d35b3610a69aee0 the wirte file commit
39f72af92b306f0fc6e3c653d4e85ef0b56d671a the first commit of read

这样就比较清爽。但:

2f6e2d2cf3b01c2e7e6320415d35b3610a69aee0这一长串是什么?

每次提交的 commit id (版本号),Git 的 commit id 不是1,2,3……递增的数字,⽽是⼀个 哈希 计算出来的⼀个⾮常⼤的数字,⽤⼗六进制表⽰。

我们通过git log查看到了commit id,那么这长串的数字有什么用?

我们可用通过它,进行版本的回退,查找到对应的objects对象!
在这里插入图片描述

上面的图我们通过对比.git文件,发现了很多不同,接下来我们来看看.git一些重要的文件:

index: 暂存区, git add 后会更新该内容。

HEAD: 默认指向 master 分⽀的⼀个指针。

[xiyan@hecs-34711 git_space]$ cat .git/HEAD
ref: refs/heads/master
[xiyan@hecs-34711 git_space]$ cat .git/refs/heads/master 
2f6e2d2cf3b01c2e7e6320415d35b3610a69aee0

而master就保存当前最新的commit id。

objects 为 Git 的对象库,⾥⾯包含了创建的各种版本库对象及内容。当执⾏ git add 命令时,暂存区的⽬录树被更新,同时⼯作区修改的⽂件内容被写⼊到对象库中的⼀个新的对象中。

[xiyan@hecs-34711 git_space]$ ls .git/objects/
0e  2f  39  61  9c  e6  info  pack

查找 object 时要将 commit id 分成2部分,其前2位是⽂件夹名称,后38位是⽂件名称。

[xiyan@hecs-34711 git_space]$ cat .git/objects/0e/*
x+)JMU06b040031Q(JMLax6𒫍¯9{wk®+ºq爏󂣜)[xiyan@hecs-34711 git_space]$

我们不同直接用cat命令看到⾥⾯是什么,该类⽂件是经过 安全哈希算法加密过的⽂件,打印出来回乱码,我们要使用git cat-file 命令(可以使用使用man命令来查看详细用法)来查看版本库对象的内容,-p选项——pretty-print object’s content。

[xiyan@hecs-34711 git_space]$ cat .git/refs/heads/master
2f6e2d2cf3b01c2e7e6320415d35b3610a69aee0

[xiyan@hecs-34711 git_space]$ git cat-file -p 2f6e2d2c...35b3610a69aee0	 #注意使用用自己机器上的commit id,这里省略了
tree 9cffb16f8c6fcfce13583b17334580260e1f21d6
parent 39f72af92b306f0fc6e3c653d4e85ef0b56d671a
author xiyan <3219576710@qq.com> 1703386373 +0800
committer xiyan <3219576710@qq.com> 1703386373 +0800

the wirte file commit

[xiyan@hecs-34711 git_space]$ git cat-file -p 9cffb16f8c...260e1f21d6
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391	read
100644 blob 61823625adb7093c12c41a0f937850e7a493ade4	write

[xiyan@hecs-34711 git_space]$ git cat-file -p 61823625...a493ade4
绝知此事要躬行!

暂存区,master分支这些都只存放的一个指向对象库的一个索引。

在这里插入图片描述

3.5.修改文件

Git 跟踪并管理的是修改,⽽⾮⽂件。 新增和删除都称之为修改。我们在wirte添加一行内容,“劝君惜取少年时!”

[xiyan@hecs-34711 git_space]$ vim write
[xiyan@hecs-34711 git_space]$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   write
#
no changes added to commit (use "git add" and/or "git commit -a")

我们使用git status也能反映,对应的文件被修改,但是看不着哪些被修改很慌,如果想要知道更加详细哪一行别修改怎么办。

**git diff [file] 命令⽤来显⽰暂存区和⼯作区⽂件的差异,**显⽰的格式正是Unix通⽤的diff格式。也可以使⽤ git diff HEAD – [file] 命令来查看版本库和⼯作区⽂件的区别。

[xiyan@hecs-34711 git_space]$ git diff write
diff --git a/write b/write
index 6182362..ec7fd22 100644
--- a/write
+++ b/write
@@ -1 +1,2 @@
 绝知此事要躬行!
+劝君惜取少年时!

这样使用diff查看到具体的信息,我们就可以放心的将内容提交。

[xiyan@hecs-34711 git_space]$ git add .
[xiyan@hecs-34711 git_space]$ git commit -m "change line in wirte"
[master 56f2997] change line in wirte
 1 file changed, 1 insertion(+)
[xiyan@hecs-34711 git_space]$ git status
# On branch master
nothing to commit, working directory clean
3.6.版本回退

比如我们吭哧吭哧写了三天的代码,发现我们代码有很大的问题,这时候我们想要回到三天前的代码版本,重新开始可以吗?

当然是可以的,这也是版本控制器重要的能⼒,Git 能够管理⽂件的历史版本。

[xiyan@hecs-34711 git_space]$ git diff write # 没有输出内容
[xiyan@hecs-34711 git_space]$ git diff HEAD -- write # 没有输出内容
[xiyan@hecs-34711 git_space]$ cat write 
绝知此事要躬行!
劝君惜取少年时!

上面查看了当前,暂存区和本版库与工作区中的内容,说明三个内容都是一样的。现在只在工作区中添加一行内容 “知行合一!”,当然可以再用git diff,查看内容的差别,图示:

在这里插入图片描述

回退版本的方式:

git reset 命令语法格式为: git reset [–soft | --mixed | --hard] [HEAD]

  • 可直接写成 commit id,表⽰指定退回的版本
  • HEAD 表⽰当前版本、HEAD^ 上⼀个版本、HEAD^^ 上上⼀个版本,以此类推
  • 可以使⽤ 〜数字表⽰:HEAD~0 表⽰当前版本、HEAD~1 上⼀个版本、HEAD~2 上上⼀个版本

这里进行版本的回退,那么commit是-m的描述就显得很重要了,这能让我们知道要回退到那个版本。所以提交细节要好好写!

# 使用--soft参数
[xiyan@hecs-34711 git_space]$ git log --pretty=oneline
56f2997314a012b1755b56b84efbef138578826a change line in wirte
2f6e2d2cf3b01c2e7e6320415d35b3610a69aee0 the wirte file commit
39f72af92b306f0fc6e3c653d4e85ef0b56d671a the first commit of read
[xiyan@hecs-34711 git_space]$ git reset --soft 2f6e2d2cf3b0..5b3610a69aee0
[xiyan@hecs-34711 git_space]$ git diff HEAD write 
diff --git a/write b/write
index 6182362..898a60c 100644
--- a/write
+++ b/write
@@ -1 +1,3 @@
 绝知此事要躬行!
+劝君惜取少年时!
+知行合一!

# 使用--mixed参数
[xiyan@hecs-34711 git_space]$ git diff write 
diff --git a/write b/write
index ec7fd22..898a60c 100644
--- a/write
+++ b/write
@@ -1,2 +1,3 @@
 绝知此事要躬行!
 劝君惜取少年时!
+知行合一!
[xiyan@hecs-34711 git_space]$ git reset --mixed HEAD
Unstaged changes after reset:
M	write
[xiyan@hecs-34711 git_space]$ git diff write
diff --git a/write b/write
index 6182362..898a60c 100644
--- a/write
+++ b/write
@@ -1 +1,3 @@
 绝知此事要躬行!
+劝君惜取少年时!
+知行合一!

#使用--hard参数
[xiyan@hecs-34711 git_space]$ git reset --hard HEAD
HEAD is now at 2f6e2d2 the wirte file commit
[xiyan@hecs-34711 git_space]$ cat write 
绝知此事要躬行!

至此我们就完成了上图版本回退的操作。

但是我现在后悔了,怎么办,我要恢复原来的状态?当然Git提供了后悔药吃,可以使用最开是的git log查看到的残留的commit id来恢复,当然它也提供了来抢救,

[xiyan@hecs-34711 git_space]$ git reflog
2f6e2d2 HEAD@{0}: reset: moving to 2f6e2d2cf3b01c2e7e6320415d35b3610a69aee0
56f2997 HEAD@{1}: reset: moving to 56f2997314a012b1755b56b84efbef138578826a
39f72af HEAD@{2}: reset: moving to HEAD~2
56f2997 HEAD@{3}: reset: moving to 56f2997
2f6e2d2 HEAD@{4}: reset: moving to HEAD^
56f2997 HEAD@{5}: commit: change line in wirte
2f6e2d2 HEAD@{6}: commit: the wirte file commit
39f72af HEAD@{7}: commit (initial): the first commit of read
[xiyan@hecs-34711 git_space]$ git reset --hard 56f2997
HEAD is now at 56f2997 change line in wirte
[xiyan@hecs-34711 git_space]$ cat write 
绝知此事要躬行!
劝君惜取少年时!

虽然我们这里恢复了版本,但是对于添加的"知行合一",这行没有提交所以找不回来了,所以版本回退是–hard参数要慎用!

对于56f2997也是commit id的一部分,我们也可以通过它来就行版本回退,注意虽然git reflog命令能查看所有操作记录,但是随着版本快速迭代commit id有可能找不回来!所以后悔了快速的做出改变。

Git 的版本回退速度⾮常快,因为 Git 在内部有个指向当前分⽀(此处是master)的HEAD 指针, refs/heads/master ⽂件⾥保存当前 master 分⽀的最新 commit id 。当我们在回退版本的时候,Git 仅仅是给 refs/heads/master 中存储⼀个特定的version(commit id ),图示:

在这里插入图片描述

3.7.撤销修改与文件删除

当我们写了很久的代码,但是发现自己的代码很low,想撤销修改,有三种情况:

在这里插入图片描述

如果代码只存在工作区,是不推荐用手动修改的:手动修改思路就是将git diff [file]对比之后一行一行删除,这样很容易改出bug。

# 情况一:
[xiyan@hecs-34711 git_space]$ vim write 
[xiyan@hecs-34711 git_space]$ cat write
绝知此事要躬行!
劝君惜取少年时!
知行合一!
[xiyan@hecs-34711 git_space]$ git checkout -- write # 注意--不能少!!!
[xiyan@hecs-34711 git_space]$ cat write 
绝知此事要躬行!
劝君惜取少年时!

# 情况二:
[xiyan@hecs-34711 git_space]$ vim write 
[xiyan@hecs-34711 git_space]$ cat write
绝知此事要躬行!
劝君惜取少年时!
知行合一!
[xiyan@hecs-34711 git_space]$ git add write
[xiyan@hecs-34711 git_space]$ git reset --hard HEAD
HEAD is now at 56f2997 change line in wirte
[xiyan@hecs-34711 git_space]$ cat write 
绝知此事要躬行!
劝君惜取少年时!
[xiyan@hecs-34711 git_space]$ git status
# On branch master
nothing to commit, working directory clean

# 情况三:有个前提没有将代码push到远程仓库(请往后看),而是在本地仓库操作。
[xiyan@hecs-34711 git_space]$ vim write 
[xiyan@hecs-34711 git_space]$ cat write
绝知此事要躬行!
劝君惜取少年时!
知行合一!
[xiyan@hecs-34711 git_space]$ git add .
[xiyan@hecs-34711 git_space]$ git commit -m "the add one line in wirte"
[master 42006b8] the add one line in wirte
 1 file changed, 1 insertion(+)
[xiyan@hecs-34711 git_space]$ git reset --hard HEAD^
HEAD is now at 56f2997 change line in wirte
[xiyan@hecs-34711 git_space]$ cat write 
绝知此事要躬行!
劝君惜取少年时!

当我们有一个Git管理着文件被误删,或者就是要删除该文件,怎么办?

我们快速新建一个文件:

[xiyan@hecs-34711 git_space]$ touch input
[xiyan@hecs-34711 git_space]$ ll
total 4
-rw-rw-r-- 1 xiyan xiyan  0 Dec 25 14:52 input
-rw-rw-r-- 1 xiyan xiyan  0 Dec 23 21:12 read
-rw-rw-r-- 1 xiyan xiyan 50 Dec 25 14:45 write
[xiyan@hecs-34711 git_space]$ git add input 
[xiyan@hecs-34711 git_space]$ git commit -m "add file input" 
[master 44a65f7] add file input
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 input

假设我们使用rm误删了工作区中的input文件,怎么恢复:

[xiyan@hecs-34711 git_space]$ rm input
[xiyan@hecs-34711 git_space]$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	deleted:    input
#
no changes added to commit (use "git add" and/or "git commit -a")
[xiyan@hecs-34711 git_space]$ git checkout -- input
[xiyan@hecs-34711 git_space]$ ll
total 4
-rw-rw-r-- 1 xiyan xiyan  0 Dec 25 14:55 input
-rw-rw-r-- 1 xiyan xiyan  0 Dec 23 21:12 read
-rw-rw-r-- 1 xiyan xiyan 50 Dec 25 14:45 write

我们就是要删除input文件,要将Git管理的工作区和本地库文件都要删除,使用git rm [file]命令并且 commit操作!

[xiyan@hecs-34711 git_space]$ git rm input 
rm 'input'
[xiyan@hecs-34711 git_space]$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	deleted:    input
#
[xiyan@hecs-34711 git_space]$ git commit -m "delete input"
[master 7e919ad] delete input
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 input
[xiyan@hecs-34711 git_space]$ git status
# On branch master
nothing to commit, working directory clean
[xiyan@hecs-34711 git_space]$ ll
total 4
-rw-rw-r-- 1 xiyan xiyan  0 Dec 23 21:12 read
-rw-rw-r-- 1 xiyan xiyan 50 Dec 25 14:45 write


master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	deleted:    input
#
[xiyan@hecs-34711 git_space]$ git commit -m "delete input"
[master 7e919ad] delete input
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 input
[xiyan@hecs-34711 git_space]$ git status
# On branch master
nothing to commit, working directory clean
[xiyan@hecs-34711 git_space]$ ll
total 4
-rw-rw-r-- 1 xiyan xiyan  0 Dec 23 21:12 read
-rw-rw-r-- 1 xiyan xiyan 50 Dec 25 14:45 write
  • 17
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值