文章目录
这个博客系列,分享的Git操作,这不是简单的指令罗列,小编通过画图和问题回答的方式对Git指令使用原理的总结,希望能够帮助到大家!有错误的地方也请大家多多指正!有帮助到您,也请点赞支持!
1.为什么用Git
当我们在学习过程中,需要完成老师交给我们的任务:
在这里插入图片描述
这时候为了避免手动管理我们需要版本控制器,而Git就是一个版本控制器,它是目前主流的!
Git 是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目,它 可以控制电脑上所有格式的⽂件。但是对于程序猿来说更多的是管理我们源代码。
2.安装Git
2.1.CentOS下安装
查看 Git 安装的版本:
[xiyan@hecs-34711 ~]$ git--version
CentOS安装Git :
[xiyan@hecs-34711 ~]$ sudo yum installgit-y
2.2.ubuntu下安装
查看 Git 安装的版本:
xiyan@ubuntu:~$ git--version
安装Git :
xiyan@ubuntu:~$ sudoapt-getinstallgit-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 protected]"
查看配置命令为:
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]$ touchread[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]$ gitaddread[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]$ gitaddwrite# 添加write [xiyan@hecs-34711 git_space]$ git status[xiyan@hecs-34711 git_space]$ git commit -m"the wirte file commit"1file changed, 1 insertion(+) create mode 100644write说明:一个文件改变,插入一行内容
至此我们就将工作区中的write文件添加到了版本库中,并让git进行管理。
- 使用git add 命令可以将⽂件添加到暂存区:
• 添加⼀个或多个⽂件到暂存区: gitadd[file1][file2]...• 添加指定⽬录到暂存区,包括⼦⽬录: gitadd[dir]• 添加当前⽬录下的所有⽂件改动到暂存区: gitadd.
- 再使⽤ 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 <[email protected]>
Date: Sun Dec 2410: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 3961 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 <[email protected]>1703386373 +0800
committer xiyan <[email protected]>1703386373 +0800
the wirte file commit
[xiyan@hecs-34711 git_space]$ git cat-file -p 9cffb16f8c...260e1f21d6
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 read100644 blob 61823625adb7093c12c41a0f937850e7a493ade4 write[xiyan@hecs-34711 git_space]$ git cat-file -p61823625...a493ade4
绝知此事要躬行!
暂存区,master分支这些都只存放的一个指向对象库的一个索引。
3.5.修改文件
Git 跟踪并管理的是修改,⽽⾮⽂件。新增和删除都称之为修改。我们在wirte添加一行内容,“劝君惜取少年时!”
[xiyan@hecs-34711 git_space]$ vimwrite[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]$ gitdiffwritediff--git a/write b/write
index 6182362..ec7fd22 100644
--- a/write
+++ b/write
@@ -1 +1,2 @@
绝知此事要躬行!
+劝君惜取少年时!
这样使用diff查看到具体的信息,我们就可以放心的将内容提交。
[xiyan@hecs-34711 git_space]$ gitadd.[xiyan@hecs-34711 git_space]$ git commit -m"change line in wirte"[master 56f2997] change line in wirte
1file 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]$ gitdiffwrite# 没有输出内容[xiyan@hecs-34711 git_space]$ gitdiff HEAD -- write# 没有输出内容[xiyan@hecs-34711 git_space]$ catwrite
绝知此事要躬行!
劝君惜取少年时!
上面查看了当前,暂存区和本版库与工作区中的内容,说明三个内容都是一样的。现在只在工作区中添加一行内容 “知行合一!”,当然可以再用git diff,查看内容的差别,图示:
回退版本的方式:
git reset 命令语法格式为: git reset [–soft | --mixed | --hard] [HEAD]
- 可直接写成 commit id,表⽰指定退回的版本
- HEAD 表⽰当前版本、HEAD^ 上⼀个版本、HEAD^^ 上上⼀个版本,以此类推
- 可以使⽤ 〜数字表⽰:HEAD
0 表⽰当前版本、HEAD1 上⼀个版本、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]$ gitdiff HEAD writediff--git a/write b/write
index 6182362..898a60c 100644
--- a/write
+++ b/write
@@ -1 +1,3 @@
绝知此事要躬行!
+劝君惜取少年时!
+知行合一!
# 使用--mixed参数[xiyan@hecs-34711 git_space]$ gitdiffwritediff--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]$ gitdiffwritediff--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]$ catwrite
绝知此事要躬行!
至此我们就完成了上图版本回退的操作。
但是我现在后悔了,怎么办,我要恢复原来的状态?当然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]$ catwrite
绝知此事要躬行!
劝君惜取少年时!
虽然我们这里恢复了版本,但是对于添加的"知行合一",这行没有提交所以找不回来了,所以版本回退是–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]$ vimwrite[xiyan@hecs-34711 git_space]$ catwrite
绝知此事要躬行!
劝君惜取少年时!
知行合一!
[xiyan@hecs-34711 git_space]$ git checkout -- write# 注意--不能少!!![xiyan@hecs-34711 git_space]$ catwrite
绝知此事要躬行!
劝君惜取少年时!
# 情况二:[xiyan@hecs-34711 git_space]$ vimwrite[xiyan@hecs-34711 git_space]$ catwrite
绝知此事要躬行!
劝君惜取少年时!
知行合一!
[xiyan@hecs-34711 git_space]$ gitaddwrite[xiyan@hecs-34711 git_space]$ git reset --hard HEAD
HEAD is now at 56f2997 change line in wirte
[xiyan@hecs-34711 git_space]$ catwrite
绝知此事要躬行!
劝君惜取少年时!
[xiyan@hecs-34711 git_space]$ git status
# On branch master
nothing to commit, working directory clean
# 情况三:有个前提没有将代码push到远程仓库(请往后看),而是在本地仓库操作。[xiyan@hecs-34711 git_space]$ vimwrite[xiyan@hecs-34711 git_space]$ catwrite
绝知此事要躬行!
劝君惜取少年时!
知行合一!
[xiyan@hecs-34711 git_space]$ gitadd.[xiyan@hecs-34711 git_space]$ git commit -m"the add one line in wirte"[master 42006b8] the add one line in wirte
1file 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]$ catwrite
绝知此事要躬行!
劝君惜取少年时!
当我们有一个Git管理着文件被误删,或者就是要删除该文件,怎么办?
我们快速新建一个文件:
[xiyan@hecs-34711 git_space]$ touch input
[xiyan@hecs-34711 git_space]$ ll
total 4
-rw-rw-r-- 1 xiyan xiyan 0 Dec 2514:52 input
-rw-rw-r-- 1 xiyan xiyan 0 Dec 2321:12 read
-rw-rw-r-- 1 xiyan xiyan 50 Dec 2514:45 write[xiyan@hecs-34711 git_space]$ gitadd input
[xiyan@hecs-34711 git_space]$ git commit -m"add file input"[master 44a65f7]addfile input
1file 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 2514:55 input
-rw-rw-r-- 1 xiyan xiyan 0 Dec 2321:12 read
-rw-rw-r-- 1 xiyan xiyan 50 Dec 2514:45 write
我们就是要删除input文件,要将Git管理的工作区和本地库文件都要删除,使用git rm [file]命令并且 commit操作!
[xiyan@hecs-34711 git_space]$ gitrm 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
1file 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 2321:12 read
-rw-rw-r-- 1 xiyan xiyan 50 Dec 2514: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
1file 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 2321:12 read
-rw-rw-r-- 1 xiyan xiyan 50 Dec 2514:45 write
版权归原作者 希言JY 所有, 如有侵权,请联系我们删除。