文章目录
1. git入门与实践(2)
2. 删除文件
可能大家第一想到的是手动删除:
手动删除mytest
文件
此时删除的文件,仅仅删除的工作区的,而git
仓库中的文件仍然存在!
2.1 命令行删除
git rm <file>
删除git
仓库中记录的文件,并且不保留在工作目录中
此时执行完删除后,提示提交到仓库。
此时不仅删除了工作区的文件,仓库中也同样删除了!
我们不需要先手动删除工作区的文件,git rm <file>
会同时删除工作区和仓库中的文件。
2.2 强制删除
git rm -f(force) <file>
强制删除
2.3 手动删除工作目录中的文件
windows
可直接手动删除,无需借助命令。
2.4 删除Git仓库中的,保留工作目录中的文件
git rm --cache <file>
假如我们现在工作区有两个文件一个y.txt
,一个z.txt
。我们不想提交z.txt
,但是误提交了,直接用git rm
会同时删除工作区和仓库的文件。
git rm --cache z.txt
z.txt
文件就回到了未被追踪的状态了,
如果我们修改了a.txt
文件,然后想用git rm
删除,发现失败了。
git
为了防止误操作,它有一个安全机制,假如有文件发生了修改等,还没被提交,如果你删除这个文件,很容易造成,你对该文件的修改丢失,因为还没被提交就删除了,就会导致后面如果想找回修改的内容,就查不到记录了。git
为了防止出现这种类似问题,git
要求修改后的文件先提交后删除才行。
git
官方说明,如果想找回任何记录,就详细提交每一次记录,只要提交了,就一定可以找回。
如果确定以后再也不用这个文件,非要删除,可以使用强制删除命令:
git rm -f a.txt
注意:不要随便就强制删除,因为很容易导致一些修改你没有提交,就会丢失这些暂存信息。
3. 移动文件
3.1 移动文件的妙用
-
重命名
-
移动文件
git mv file_from file_to
以上命令相当于以下三条
mv file_from file_to
git rm file_from
git add file_to
我们新建一个文件夹:mkdir first
git mv d.txt .\first\
rename d.txt => first/d.txt (100%)
这里即为重命名操作!
3.1.1 重命名(移动)文件原理
我们修改y.txt
的文件名:
mv z.txt b.txt
从这里我们可以发现,重命名一个文件,系统其实是先删除z.txt
,再创建一个b.txt
,并同时把z.txt
的内容复制进去。因此这里才会有一个删除文件操作,以及未追踪的文件b
。实际移动文件和重命名文件的原理一样。
接下来,我们还需要删除仓库的z.txt
文件,并把b.txt
放入暂存区。git
通过我们的操作,就可以判断我们此时是进行重命名的操作。
实际上git
根据我们的操作,就知道我们的最终目的也是重命名了。
3.1.2 git上移动文件(或重命名文件)原理
git mv file_from file_to
以上命令相当于以下三条
mv file_from file_to
git rm file_from
git add file_to
要想实现移动文件的原理,我们要是先删除文件,再添加文件是不行的,git
是无法判断我们是想移动文件的,必须先告诉它我们要移动文件了才行 (mv file_from file_to
)。
new-item 2.txt
git add 2.txt
git rm 2.txt
git add 22.txt
git
不会认为是再改名字,只能认为是将其加入暂存区。失败的原因就是找不到这个文件。
正确操作如下:
new-item 3.txt
git add .
git commit -m ‘...’
mv 3.txt 33.txt
(实际告知git
现在进行重命名操作了)
git rm 3.txt
git add 33.txt
git commit -m ‘完成看33重命名’
对比以上三条命令和git mv file_from file_to
是等同的。
实际移动文件就是重命名文件
4. 查看功能
4.1 git status
git status
打印文件状态(未追踪、已修改、已暂存)
我们其实可以发现,我们做每一步的操作,git
都给了我们命令提示。
如果修改了文件内容。
其实,我们也发现每一步的提示太多了,假若这里处理的文件很多,提示太长,那有没有简便地文件状态呢?
4.1.1 git status -s
git status -s = git status --short
简化文件状态打印内容
4.1.1.1 short状态码
??
代表未追踪的文件 3.txt
AM
代表添加到暂存区的且被修改但是未放入暂存区 0.txt
A
代表添加到暂存区的 2.txt
我们再看看其他状态:
未追踪状态
变为添加到暂存区
修改3.txt
内容
代表添加到暂存区的
且被修改但是未放入暂存区
add
后,代表添加到暂存区的
提交后,就没有当前任何状态信息了。
再修改3.txt
内容
状态:被修改但是未放入暂存区
(靠右边的M
)
add
后,代表被修改后放入暂存区
(靠左边的M
)
再修改3.txt
内容
MM
修改后放入暂存区,并且又再次修改
4.1.1.2 扩展
简化文件状态除了上图的还有其他的。
手动删除0.txt
D
(靠右边) 代表delete
,表示在工作区删除了0.txt
git rm 0.txt
D
(靠左边) 代表delete
,表示在仓库(包括工作区)删除了0.txt
git mv 1.txt first/111.txt
R
(靠左边)代表重命名(移动文件)
4.1.1.3 状态码总结
A
: 你本地新增的文件(服务器上没有).
C
: 文件的一个新拷贝.
D
: 你本地删除的文件(服务器上还在).
M
: 文件的内容或者mode
被修改了.
R
: 文件名被修改了。
T
: 文件的类型被修改了。
U
: 文件没有被合并(你需要完成合并才能进行提交)。
X
: 未知状态(很可能是遇到git
的bug
了,你可以向git
提交bug report
)
官网说明:(常用的小迪已经列出了,如果今后大家遇到奇葩的提示,再查看文档说明即可)
Ignored files are not listed, unless --ignored
option is in effect, in which case XY
are !!
.
X Y Meaning
-------------------------------------------------
[AMD] not updated
M [ MD] updated in index
A [ MD] added to index
D deleted from index
R [ MD] renamed in index
C [ MD] copied in index
[MARC] index and work tree matches
[ MARC] M work tree changed since index
[ MARC] D deleted in work tree
[ D] R renamed in work tree
[ D] C copied in work tree
-------------------------------------------------
D D unmerged, both deleted
A U unmerged, added by us
U D unmerged, deleted by them
U A unmerged, added by them
D U unmerged, deleted by us
A A unmerged, both added
U U unmerged, both modified
-------------------------------------------------
? ? untracked
! ! ignored
-------------------------------------------------
4.2 git diff
git diff
查看当前文件的修改(主要看工作区)
新建一个diff.txt
,提交暂存区,再修改其内容后,我们想查看它的变化记录。
git diff
有的朋友可能会出现乱码!注意:记事本保存应以utf-8方式保存!
---
代表之前提交到暂存区的内容。
+++
代表修改之后,未提交至暂存区的内容(在工作区)。
将其添加至暂存区,在对比,发现没有记录了。是因为git diff
只是比较工作目录与暂存、提交之间的差别,工作目录是关键。工作目录东西都提交,git
就认为没有东西可对比了,执行git diff
后,就看不到任何变化了。
我们再修改文件!查看diff
。
实际只是在第二行添加了内容,但是显示两行都变化了,因此git
是全部覆盖。
@@ -1
代表暂存区第一行,+1、2
@@ 代表在工作目录中的操作为第一、二行。实际就是指明,红色和绿色部分分别在暂存区和工作目录的第几行。(具体参考下方)
再修改文件,如下:
diff --git a/diff.txt b/diff.txt
该行显示git
版本的diff
下两个文件的对比。a
版本(修改前)的文件 diff.txt
,
和 b
版本(修改后)文件 diff.txt
index 0e2f2d7..a19cbac 100644
index
后面两个数字表示两个文件的hash
值(index
区域的0e2f2d7
对象与工作区域的a19cbac
对象对比)
最后面的数字表示文件的属性,权限(文件权限为644
)
@@ -1 +1,3 @@
$ @@ -4,3 +4,5 @@
该行表示接下来,下面显示的内容所在位置。
-
表示修改前,+
表示修改后;-1
表示修改前的diff.txt
文件,从第1
行开始显示,到第1
行截止。
如:
-4,3
从第4
行开始显示,一直
到第6
行(上面的4
为起始行,3
为向后偏移的行数。即显示修改前该文件第4
至第6
行的内容)
+1,3
表示接下来要显示的内容为修改后的diff.txt
文件,从第1
行开始显示,一直到
第3
行(从第1
行开始,延续到向后偏移3
行)。
如:
+4,5
则表示接下来要显示的内容为修改后的README.md
文件,从第4
行开始显示,一直到
第8
行(从第4
行开始,延续到向后偏移5
行)
提交后,同理diff
也是打印不出东西的。
4.2.1 git diff --staged
查看暂存区和提交区域之间的差异
再修改文件:
假如提交到暂存区,我们想看暂存区与提交的对比记录。
git diff --staged
11111111111111111111111111111
第二次修改!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
以上是之前提交的内容!
-第三次改!
以上是最新提交的内容。
+第四次修改!
+a
+b
+c
以上是在暂存区的修改还没有提交。
4.3 git log 查看日志
commit 68566241c1ac163e4e82f710009070648c1bdb00
提交后跟着的数字,实际上可以认为是id
(唯一的),它就可以完全代表此次的commit
提交了,它是通过git
计算出来的,严格意义上应该称为校验和
(或ssha-1
),这里包含文件内容、名字整合出来的,它有40
个字符。
后面紧跟着作者和提交日期、记录。
如果log
很多的话,就进入了日志打印模式。可以看到最下面的:
,是不能再输入命令的,按下q
,即可退出到终端原界面。
4.3.1 git log -p
查看详细信息,加上之前git log
打印的信息,还加上了diff
的信息。
4.3.2 git log -n
查看最近的n
条信息
4.3.3 git log --stat
列出所有被修改的文件,以及简略的统计信息 => 看到此次提交,有几处修改
4.3.4 git log --pretty
设置打印内容的格式
4.3.4.1 -oneline 哈希和描述
git log --pretty=oneline
打印哈希和描述
4.3.4.2 -short 哈希、作者、描述
git log --pretty=short
打印哈希、作者、描述
4.3.4.3 -full 哈希、作者、提交者、描述
git log --pretty=full
打印哈希、作者、提交者、描述
此处的作者:实际修改的人
提交者:最后将此工作成果提交到仓库的人
注意作者和提交者不一定是同一个人!
4.3.4.4 -fuller 哈希、作者、日期、提交者、提交日期、描述
git log --pretty=fuller
打印哈希、作者、日期、提交者、提交日期、描述
4.3.4.5 -format 定制要显示的记录格式
选项 | 说明 |
---|---|
%H | 提交对象(commit)的完整哈希字串 |
%h | 提交对象的简短哈希字串 |
%T | 树对象(tree)的完整哈希字串 |
%t | 树对象的简短哈希字串 |
%P | 父对象(parent)的完整哈希字串 |
%p | 父对象的简短哈希字串 |
%an | 作者(author)的名字 |
%ae | 作者的电子邮件地址 |
%ad | 作者修订日期(可以用 -date= 选项定制格式) |
%ar | 作者修订日期,按多久以前的方式显示 |
%cn | 提交者(committer)的名字 |
%ce | 提交者的电子邮件地址 |
%cd | 提交日期 |
%cr | 提交日期,按多久以前的方式显示 |
%s | 提交说明 |
git log --pretty=format:"%H %h"
打印详细哈希和简短哈希
5. HEAD和master
什么是HEAD
?什么是master
?
5.1 提交对象
Git
保存的并不是文件的变化或差异,而是一系列的不同时刻的文件快照。
快照是什么呢?
打开网盘的百度快照,这里是2020年6月5日,13点拍摄的一个快照状态。
回归正题,其实git
进行提交的时候就会拍照,即成为快照。
提交操作时Git
会保存一个提交对象,该对象中包含一个指向暂存内容快照的指针(理解为编程语言的指针或引用是完全没问题的)、作者姓名、邮箱、父对象指针以及提交输入信息。
- 首次提交的对象没有父对象
- 普通的提交有一个父对象
- 多个分支合并的有多个父对象
实际git
保存的并不是文件的差异,而是一系列不同时刻的文件快照。
第n
次提交实际就是提交对象,存在指向快照的指针,下次提交的对象存在一个指向父对象的指针(左侧箭头)。
5.1.1 搜索引擎快照
搜索引擎快照,是指在访客在无法打开某个搜索结果,或者打开速度特别慢的情况下,为访客提供的之前保存在搜索引擎服务器上对应网页内容的纯文本。不过,搜索引擎保存的快照内容一般只包括文本数据,图片及其他多媒体等非文本数据不会被保存。因此,在来源网站无法访问的情况下,图片及其他多媒体在快照中将无法显示。
5.1.2 存储快照
全球网络存储工业协会SNIA
(StorageNetworking Industry Association)对快照(Snapshot)的定义是:关于指定数据集合的一个完全可用拷贝,该拷贝包括相应数据在某个时间点(拷贝开始的时间点)的映像。快照可以是其所表示的数据的一个副本,也可以是数据的一个复制品。
快照的作用主要是能够进行在线数据备份与恢复。当存储设备发生应用故障或者文件损坏时可以进行快速的数据恢复,将数据恢复某个可用的时间点的状态。快照的另一个作用是为存储用户提供了另外一个数据访问通道,当原数据进行在线应用处理时,用户可以访问快照数据,还可以利用快照进行测试等工作。所有存储系统,不论高中低端,只要应用于在线系统,那么快照就成为一个不可或缺的功能。
5.2 master分支
主分支名称,Git
的分支本质上仅仅指向提交对象的可变指针。
Git默认分支名:master
,它会在每一次的提交中自动前移。(git init
自动默认生成一个master
分支)
master
指向的就是第n
次提交对象呢?其实是不对的,实际master
代表指向一个类似链表一样的结构,它实际指从第1
次提交到第n
次提交对象的整个一串糖葫芦(分支)。将master
理解为一个分支即可。
C
代表每次提交,下方箭头代表快照指针,底部则是指向的快照。
Git
的分支 master
并不是一个特殊分支,它和其他的分支完全没有区别,之所以每个分支都是有master
是git init
命令默认创建,而大部分人又懒得去更改。
5.3 HEAD
Git
保存着一个名为 HEAD
的特殊指针。在 git
中,它是一个指向你正在工作中的本地分支的指针,即指向当前所在分支,可以将 HEAD
想象为当前分支的别名。HEAD
是唯一的!
(后续待补充)