为了区分Linux操作系统的命令,git的所有命令都以git开头,后面跟着具体的命令。如git init就是初始化仓库。
git下载安装、初始配置我们直接略过,直接开始使用
新建git仓库(init)
通过新文件来新建仓库,一步一步来
新建git-learn文件,进入该文件,让git管理该文件(本质是生成一个.git的隐藏文件)
mkdir git-learn
cd git-learn
git init
使用指令查看learn-git的文件发现已经产生了.git文件,说明真的成功了
(.git是隐藏文件,因此使用ls -a查看包括隐藏文件)
ls -a
.git文件存放了git所有数据,我们通过命令查看一下
cd .git
ls -altr
这些文件都是git仓库的重要组成部分,不要随意删除和修改里面的内容,否则会破坏仓库,这也就是为什么.git目录要隐藏起来。
所以如果我们将.git文件删除,该文件就和普通文件没有区别了。
git工作区域与文件状态
git的三个工作区域
- 工作区
- 暂存区
- 本地仓库
三个区域分别的作用
- 工作区:实际上就是我们操作的文件
- 暂存区:工作区操作完成后,可以先将文件添加到暂存区,当你认为暂存区内容可以作为一个版本时,一起提交到本地仓库
- 本地仓库:存储各个版本的文件,可以通过git指令来查看、比较或撤销,来保证版本控制的准确性和完整性
而文件也有四种状态
- 未跟踪:在工作区文件夹中,但未被git管理
- 未修改:通常是commit之后的状态
- 已修改:未修改文件修改了
- 已暂存:已修改文件add到暂存区了
工作区(未修改、已修改)
暂存区(已暂存)
(如果想要未跟踪文件被git管理,可直接add至暂存区,即 未跟踪--->已暂存)
git添加和提交文件(add/commit)
先通过cd指令回到仓库目录
查看仓库的状态
git status
但目前仓库什么都没有什么
那我们先用Linux的echo指令,新建文件并添加内容
用Linux的ls查看一下文件夹有哪些文件
用cat查看该文件的内容
echo "第一个文件" > file1.txt
ls
cat file1.txt
再查看一下仓库的状态
git status
将该未跟踪文件add到暂存区,再查看状态
git add file1.txt
git status
发现该文件是已暂存的状态了
暂存区文件commit到本地仓库
我们会把暂存区所有文件一起提交
git commit -m "第一个版本"
我们还需要额外的-m来添加提交信息,这个提交信息会被记录到仓库中
如果不使用-m,则在执行之后commit之后需要通过vim添加提交信息
再来查看一下仓库的状态
git status
发现已经没有刚才的file.txt文件了
实际上是暂存区的文件状态被重置成未修改状态了(但还是内容还是一样)
git add指令可以一个一个添加,也可以用通配符一并add到暂存区
新建几个文件试试看
echo "第二个文件" > file2.txt
echo "第三个文件" > file3.txt
echo "第四个文件" > file4.txt
echo "第五个文件" > file5.sh
git status
git add *.txt
git status
所有以 .txt结尾 的工作区文件都被添加到了暂存区
git add还可以接受以文件夹作为参数,将所有工作区文件add到暂存区
git add .
这里的.就表示当前目录
这次我们不使用-m来添加提交信息
git commit
会默认我们需要用vim来添加提交信息,vim是一个强大的文本编辑器,只讲操作就不具体介绍
- 可以使用方向键来移动光标
- 使用i键进入编辑模式,输入提交信息
- 然后esc键进入命令模式,输入“:wq”保存退出
可以使用git log指令查看提交记录
git log
关于 add 和 commit 可能产生的误解
当工作区文件添加到暂存区时,实际发生的不是将工作区文件剪切到暂存区,而是将工作区文件状态拷贝覆盖到暂存区。工作区的文件不会有任何改变。
即
- 工作区有AB文件,暂存区有AB文件,在工作区新增C文件后,执行add .指令,暂存区会新增C文件
- 工作区有ABC文件,暂存区有ABC文件,修改了工作区的C文件后,执行add .指令,暂存区的C文件会被修改
- 工作区有ABC文件,暂存区有ABC文件,删除了工作区的C文件后,执行add .指令,暂存区的C文件会被删除
这三个例子可以很好的理解文件状态覆盖的具体含义了
同样的,当暂存区commit到本地仓库时,实际发生的是暂存区文件拷贝到本地仓库中,不过本地仓库之前版本都会备份
git版本回退(reset)
接下来我们来了解一下git reset指令,在日常开发中我们经常会需要撤销一些修改内容,或者回退到之前的某一个版本,这时我们就需要使用git reset指令
git reset的三种模式
- git reset --soft
- git reset --hard
- git reset --mixed(默认)
这三种模式都是将本地仓库的版本回退,区别在于工作区和暂存区的操作
- git reset --soft:工作区和暂存区均不变
- git reset --hard:工作区和暂存区均被回退版本覆盖
- git reset --mixed:工作区不变,暂存区被回退版本覆盖
让我们一起来操作一下:新生成一个仓库,模拟三次提交,每次提交多一个文件
mkdir repo
cd repo
git init
echo 111 > file1.txt
echo 222 > file2.txt
echo 333 > file3.txt
git add file1.txt
git commit -m "第一次提交"
git add file2.txt
git commit -m "第二次提交"
git add file3.txt
git commit -m "第三次提交"
为了方便三种模式的演示,我们将刚才的仓库拷贝三份
cd ..
cp -rf repo repo-soft
cp -rf repo repo-hard
cp -rf repo repo-mixed
进入git-soft仓库先查看一下提交历史
cd repo-soft
git log
我们来回退一下版本,然后再查看一下log
git reset --soft 版本回退id
git log
看到本地仓库只有两个版本了,指针也指向第二次提交
查看一下工作区的内容,会发现没有改变
ls
查看一下暂存区的内容,会发现也没有改变
git ls-files
查看一下仓库的状态
git status
会提示我们file3是一个新文件。
稍微解释一下:因为我们使用的是soft参数,所以回退到上一个版本的时候,工作区和暂存区的文件都不会变。但是我们回退了第二个版本,而file3是在第三个版本添加的,所以对于第二个版本来说,这个file3文件就是一个新文件。这时我们就可以重新修改file3文件,然后重新暂存和提交就可以了。
OK,接下来执行一下git reset --hard模式
进入到目录,执行git reset --hard
cd ..
cd repo-hard
git reset --hard 回退版本id
查看一下log,只剩下两次提交了
git log --oneline
再查看一下工作区和暂存区的文件,会发现都被本地仓库第二个版本文件覆盖了
ls
git ls-files
接下来执行一下git reset --mixed模式
进入到目录,执行git reset --mixed
cd ..
cd repo-mixed
git reset --mixed 回退版本id
查看一下log,只剩下两次提交了
git log --oneline
再查看一下工作区和暂存区的文件
会发现工作区的文件内容不变,暂存区的文件被第二个版本覆盖了
ls
git ls-files
三种模式的使用场景
soft和mixed的作用基本一致,区别在于是否保留暂存区里的内容。
一般来说当我们提交多个版本,但是又觉得这么多次提交没有太大意义,可以合并成一个版本的时候,就可以通过这两种参数回退再重新提交。它们主要的区别在于在重新提交之前,mixed需要重新将文件add到暂存区,而soft就不需要了,因为暂存区的内容并没有被清空。
而hard参数的使用场景,则一般是你真的要放弃目前本地所有的修改内容的时候。建议大家谨慎使用hard参数,因为他会删除两个版本之间的所有修改内容。
但是如果误操作的话也不用太担心,可以通过git reflog查看我们操作的历史记录,然后找到误操作的版本id,然后在进行git reset --hard就可以了(把工作区和暂存区也覆盖回来)
我们来尝试一下,先进入文件,查找之前的版本id
cd repo-hard
git reflog
回退到误操作版本,查看一下工作区和暂存区的文件,发现都回来了
git reset --hard 回退版本id
ls
git ls-files
git查看文件差异(diff)
接下来我们来学习一下git diff。它可以查看文件在工作区、暂存区和版本库之间的差异,还可以查看文件在两个特定版本之间的差异,或者文件在两个分支之间的差异。
通常情况下我们可以在一些图形化界面上查看文件之间的差异,但是有时候我们也需要在没有图形化界面的服务器上使用git,所以学习git diff还是很有必要的。
查看文件在工作区、暂存区和版本库之间
- git diff:工作区vs暂存区
- git diff HEAD:工作区vs版本库
- git diff --cached:暂存区vs版本库
我们来实操一下
就用之前仓库来举例,这么仓库目前有三次提交,每一次提交有一个新增文件
我们将file3.txt修改一下(修改的是工作区)
vi file3.txt
我们使用git diff来查看一下 工作区和暂存区的差异
git diff
可以看到git diff的补丁输出
我们再将文件add到暂存区,再来查看一下
git add .
git diff
可以看到没有任何内容了
我们再来比较下工作区和版本库,以及暂存区和版本库 的差异
git diff HEAD
git diff --cached
这是因为工作区和暂存区的内容同步了,但是还没有同步到版本库。
我们先commit,再来查看差异
git commit -m "第四次提交"
git diff HEAD
git diff --cached
可以看到也没有任何内容了
表示我们工作区、暂存区和版本库的内容是一致的
git diff还可以比较两个特定版本之间的差异,用法就是在后面添加比较的两个版本id就行了
先查看一下提交记录
git log --oneline
两个参数,分别是 旧版本(左边的id)相比于新版本(右边的id)
我们来比较一下第三次提交与第四次提交
我们来详细了解一下每行的内容代表什么
-
diff --git a/file3.txt b/file3.txt
:- 这行表示我们正在比较的文件是
file3.txt
,a
表示旧版本,b
表示新版本。
- 这行表示我们正在比较的文件是
-
index 55bd0ac..45f05b0 100644
:55bd0ac
和45f05b0
是Git中旧文件和新文件的哈希索引,表示文件内容的差异。100644
表示文件权限,是普通的可读可写文件(对所有者)。
-
--- a/file3.txt
:--- a/file3.txt
表示这是变化前的旧文件路径。
-
+++ b/file3.txt
:+++ b/file3.txt
表示这是变化后的新文件路径。
-
@@ -1 +1 @@
:- 这行是“hunk头”,显示变化发生的上下文。
-1
表示旧内容从第1行开始。+1
表示新内容从第1行开始。
-
-333
:- 开头的
-
表示这一行在旧文件中存在但在新文件中被删除。 333
是旧文件中的内容。
- 开头的
-
+被修改后的333
:- 开头的
+
表示这一行是新文件中添加的内容。 被修改后的333
是新文件中替换后的内容。
- 开头的
再来比较一下第二次提交与第三次提交
同样的来分析一下
-
diff --git a/file3.txt b/file3.txt
:- 表示正在比较的文件是
file3.txt
。 a/file3.txt
和b/file3.txt
表示相对路径,其中a
是旧版本,b
是新版本。在添加新文件的情况下,a
表示文件之前不存在。
- 表示正在比较的文件是
-
new file mode 100644
:- 指示
file3.txt
是一个新文件。 100644
是Unix权限模式,表示这是一个普通的可读写文件(对所有者可读写,对组和其他用户只读)。
- 指示
-
index 0000000..55bd0ac
:0000000
表示旧版本不存在,因此用全零表示。55bd0ac
是新文件内容的Git哈希值。
-
--- /dev/null
:- 表示旧文件路径。由于文件之前不存在,所以用
/dev/null
表示,就像来自空设备。
- 表示旧文件路径。由于文件之前不存在,所以用
-
+++ b/file3.txt
:- 表示新文件的路径,即当前的文件状态。
-
@@ -0,0 +1 @@
:@@
表示hunk头(差异的范围)。-0,0
表示旧文件从第0行开始有0行(实际上文件不存在,因此为0行)。+1
表示新文件从第1行开始有变化,有1行变更。
-
+333
:+
表示这行是在新文件中添加的。333
是添加的内容。
除了使用版本id以外,我们还可以使用HEAD指针
HEAD是git中一个非常重要的概念,它指向分支的最新提交节点,在后面的使用我们会经常遇到。
我们也可以使用HEAD指针来比较
HEAD表示最新提交节点
HEAD~/HEAD^表示上一个节点
HEAD~n表示前n个节点
我们来试一下
git diff HEAD^ HEAD
git diff HEAD~2 HEAD
如果我们后面再跟上文件名,那么就只会查看这个文件的差异内容
git diff HEAD^ HEAD file3.txt
diff还有一些分支相关的差异,到时候在详细讲解
git删除文件(rm)
- rm 文件名:删除工作区的该文件
- git rm 文件名:删除工作区和暂存区的该文件
我们来试一下
rm 文件名
如果要暂存区也删除的话,实际上不是直接删除,而是我们之前讲的:文件状态覆盖
也是用add来操作
如果想要工作区和暂存区一起删除,那么使用git rm指令
git rm 文件名
发现只剩下file3.txt了
如果想要删除该文件的版本保存到版本库里的话,git commit就好了
还有一些其他类型的git删除指令
标签:file3,文件,git,实践,暂存区,版本,侧重,txt From: https://blog.csdn.net/m0_71931019/article/details/143504977