3. Git添加/删除/修改命令
前言
该文章只是记录了一些自己的见解,可能并不准确,只是为了学习时的一些记录,不喜勿喷,谢谢
内容比较啰嗦,主要是写该文章时,记录了其学习的过程
该文章中主要介绍 添加文件,修改文件,删除文件等对应的git命令以及bash命令的区别,以及修改,删除后如何还原等操作。
1. 添加操作
该操作在之前已经演示过了, 这里会演示如何从暂存区中移除掉刚才的git add提交
1.1 正常添加操作
使用命令 git add,会将新创建的文件交由git来跟踪,进入暂存区
[root@huangzb mygit]# echo 'hello' > a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# a.txt
nothing added to commit but untracked files present (use "git add" to track)
[root@huangzb mygit]#
[root@huangzb mygit]# git add a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: a.txt
#
[root@huangzb mygit]#
从上图可知,我们使用git add命令后,会将该文件由未跟踪状态---> 已跟踪状态,当我们再次使用 git status命令后,可以看到 git给我们的提示,有两种选择,要么提交文件,要么将该文件重新回滚到未跟踪的情况。
1.2 将暂存区文件回滚到未跟踪状态
使用命令 git reset HEAD [file]
在上述中,我们通过git add 将新增的文件添加到暂存区,交由git跟踪,如果我们想放弃此次提交,可以使用命令 git reset HEAD [file]的方式,将文件从暂存区回滚到未跟踪状态。如下图
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: a.txt
#
[root@huangzb mygit]#
[root@huangzb mygit]# git reset HEAD a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# a.txt
nothing added to commit but untracked files present (use "git add" to track)
[root@huangzb mygit]#
有上图可知,当我们使用git reset命令将暂存区文件回滚后,调用git status命令后,又看到了标识 Untracked fiels的情况,表明该文件又重新回到了未跟踪状态。
2. 修改操作
2.1 正常修改操作
为了演示修改操作后的变化,我们先将刚才创建的文件提交,再来修改,看看变化
先将上述创建的a.txt文件提交
[root@huangzb mygit]# git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# a.txt
nothing added to commit but untracked files present (use "git add" to track)
[root@huangzb mygit]#
[root@huangzb mygit]# git add .
[root@huangzb mygit]# git commit -m 'add a.txt file '
[master 673577c] add a.txt file
1 file changed, 1 insertion(+)
create mode 100644 a.txt
[root@huangzb mygit]# git status
# On branch master
nothing to commit, working directory clean
[root@huangzb mygit]#
现在我们来修改一下文件内容,然后添加到暂存区,看看变化
[root@huangzb mygit]# git status
# On branch master
nothing to commit, working directory clean
[root@huangzb mygit]#
[root@huangzb mygit]# echo 'hello java' > a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# cat a.txt
hello java
[root@huangzb mygit]# 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: a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@huangzb mygit]#
[root@huangzb mygit]#
可以看出,修改了a.txt文件后,再次调用 git status命令,发现现在有两种提示:
1. 要么使用 git add 将文件变化添加到暂存区
2. 要么使用 git checkout -- file 将修改的文件回滚到未修改前
我们先来看看第二种,放弃本次修改
[root@huangzb mygit]# git checkout -- a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
nothing to commit, working directory clean
[root@huangzb mygit]#
[root@huangzb mygit]#
[root@huangzb mygit]# cat a.txt
hello
[root@huangzb mygit]#
由上图可以看出,我们使用了 git checkout -- file命令,将工作空间中的文件变化还原到了最初的情况。因此我们要记住:如何将还未添加到暂存区的文件修改变化,还原到上次最新的工作空间的文件内容?使用 git checkout -- file 命令,注意 -- 后面有个空格,
我们再来看看第一种情况,将文件变化添加到暂存区
[root@huangzb mygit]#
[root@huangzb mygit]# git add .
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
#
[root@huangzb mygit]#
可以看到,提交到暂存区后,可以看到提示,依然跟添加操作一样,有两种:
- 要么使用 git commit命令 提交到本次仓库中
- 要么使用 git reset HEAD file 来取消本次修改,即丢弃本次修改
下面我们不演示直接提交到本地仓库了,因为没有可介绍,我们重点关注,如何将本次修改还原到最初的情况。
2.2 将工作空间的修改回滚到修改前的状态
目前工作空间中的文件修改已经提交到了暂存区,因此想还原到上次最新的工作空间状态需要有两步:
- 还原本次暂存区的记录
- 在工作空间中还原成最初的记录
因此,我们需要使用两个命令,先使用 git reset 命令还原本次暂存区的记录(如何还原,我们在之前可以看到暂存区只有保留一份记录,且后续操作会覆盖之前的记录,如果想还原,就需要指定分支来从指定分支来还原该记录,如果还没有commit过,就使用使用 git rm --cache来删除了),然后使用 git checkout 根据上次的暂存区数据来还原工作空间的数据,如何操作如下图:
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
#
[root@huangzb mygit]# git ls-files -s
100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0 a.txt
100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0 test.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git cat-file -p 3b18e
hello world
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
#
[root@huangzb mygit]#
[root@huangzb mygit]# git reset HEAD a.txt
Unstaged changes after reset:
M a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# 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: a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@huangzb mygit]#
[root@huangzb mygit]# git checkout -- a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# cat a.txt
hello
[root@huangzb mygit]#
从上图可以看出,已经使用 git add命令之后,将文件变化让暂存区识别后,如果工作空间想要还原回之前的状态,则需要两步,先使用 git reset HEAD file的方式,将数据从HEAD指针位置还原数据。然后使用 git checkout -- file 的方式,将暂存区的最新数据会显到工作空间,即达到了还原的状态。
3. 删除操作
3.1 正常删除操作
演示一下通过bash命令 rm 来删除已经被git跟踪的文件的情况
我们先来演示一波:
[root@huangzb mygit]# ll
total 8
-rw-r--r-- 1 root root 6 Mar 17 13:59 a.txt
-rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
nothing to commit, working directory clean
[root@huangzb mygit]#
[root@huangzb mygit]# cat a.txt
hello
[root@huangzb mygit]#
[root@huangzb mygit]# rm a.txt
rm: remove regular file ‘a.txt’? y
[root@huangzb mygit]#
[root@huangzb mygit]# ll
total 4
-rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
[root@huangzb mygit]#
[root@huangzb mygit]# 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: a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@huangzb mygit]#
由上图可知,我们将上文创建的 a.txt文件通过 bash命令 -- rm 来删除,删除后,我们可以看到有两种情况来处理:
1. 要么使用git add 来将该变化添加到暂存区
2. 要么使用 git checkout -- file 来回滚
我们先来看看 第二种情况场景
[root@huangzb mygit]#
[root@huangzb mygit]# git checkout -- a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# ll
total 8
-rw-r--r-- 1 root root 6 Mar 17 14:15 a.txt
-rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
[root@huangzb mygit]# cat a.txt
hello
[root@huangzb mygit]#
可以看到,通过 git checkout -- file 的方式,已经将 a.txt 还原回来了
再来看看第一种情况
我们再次删除掉 a.txt 文件,然后添加到 暂存区,如下图
[root@huangzb mygit]# rm -rf a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# 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: a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@huangzb mygit]#
[root@huangzb mygit]# git add a.txt
warning: You ran 'git add' with neither '-A (--all)' or '--ignore-removal',
whose behaviour will change in Git 2.0 with respect to paths you removed.
Paths like 'a.txt' that are
removed from your working tree are ignored with this version of Git.
* 'git add --ignore-removal <pathspec>', which is the current default,
ignores paths you removed from your working tree.
* 'git add --all <pathspec>' will let you also record the removals.
Run 'git status' to check the paths you removed from your working tree.
[root@huangzb mygit]#
[root@huangzb mygit]# git add -A a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: a.txt
#
[root@huangzb mygit]#
由上图可知,当我们使用 git add a.txt 将删除变化提交到暂存区的时候提示需要添加参数,因为针对删除操作需要提供参数,要么允许暂存区保留删除操作,要么不讲删除操作提交到暂存区。这里我们使用 -A 的方式,将删除操作提交到暂存区,然后通过 git status 查看后,有两种情况处理
1. 要么使用commit提交到本地仓库
2. 要么使用 git reset 还原
我们这里就不演示commit了,使用第二种方式,将文件还原,操作如下图
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: a.txt
#
[root@huangzb mygit]# git ls-files -s
100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0 test.txt
[root@huangzb mygit]#
[root@huangzb mygit]#
[root@huangzb mygit]# git reset HEAD a.txt
Unstaged changes after reset:
D a.txt
[root@huangzb mygit]# 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: a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@huangzb mygit]# git ls-files -s
100644 ce013625030ba8dba906f756967f9e9ca394464a 0 a.txt
100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0 test.txt
[root@huangzb mygit]# git checkout -- a.txt
[root@huangzb mygit]# ll
total 8
-rw-r--r-- 1 root root 6 Mar 17 14:59 a.txt
-rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
[root@huangzb mygit]#
从上图操作中我们可以看到,前面使用 git add 操作后,暂存区的a.txt文件已经被删除了。然后使用 git reset命令从HEAD指针所处分支还原了 a.txt到暂存区,最后使用 git checkout -- file 将a.txt文件从暂存区还原了。
3.2 使用 git rm 命令来进行删除操作
git rm 命令就是上述使用 bash命令 rm以及后续 git add操作的集合,等同使用一条命令就可以了完成两步操作
我们先来演示一波,如下图
[root@huangzb mygit]# ll
total 8
-rw-r--r-- 1 root root 6 Mar 17 14:59 a.txt
-rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git rm a.txt
rm 'a.txt'
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: a.txt
#
[root@huangzb mygit]#
从上图我们可以看到,通过 git rm 命令后,通过 git status 显示效果,直接提示我们可以进行 commit了,因此该操作是 rm a.txt 以及 git add -A a.txt 操作的组成,后面的操作跟上述的一样,简单写下,不早重复介绍。如下图
[root@huangzb mygit]# git reset HEAD a.txt
Unstaged changes after reset:
D a.txt
[root@huangzb mygit]# git checkout -- a.txt
[root@huangzb mygit]# ll
total 8
-rw-r--r-- 1 root root 6 Mar 17 15:09 a.txt
-rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
[root@huangzb mygit]#
3.3 注意点
在刚才我们使用 bash命令 rm命令删除后,使用 git add命令添加到暂存区的时候,针对删除操作需要提供一个额外的参数 -A
4. 移动操作
4.1 正常移动操作
我们先来使用正常的 bash命令来移动文件
新创建一个目录,将该文件移动到新目录中,操作如下:
[root@huangzb mygit]# mkdir m1 && mv a.txt m1
[root@huangzb mygit]#
[root@huangzb mygit]#
[root@huangzb mygit]# ll
total 8
drwxr-xr-x 2 root root 4096 Mar 20 12:09 m1
-rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
[root@huangzb mygit]#
[root@huangzb mygit]# tree
.
├── m1
│ └── a.txt
└── test.txt
1 directory, 2 files
[root@huangzb mygit]# 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: a.txt
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# m1/
no changes added to commit (use "git add" and/or "git commit -a")
[root@huangzb mygit]#
由上图可知,我们新创建了一个目录 m1,且将文件 a.txt 移动到了 m1 目录中,我们使用 git status可以看到其实移动文件造成了两步操作,删除原文件,创建新文件等两步,下面我们先提交到暂存区后,看看如何回滚到之前的操作。
[root@huangzb mygit]# git add -A .
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: a.txt -> m1/a.txt
#
[root@huangzb mygit]#
从上图可以看出,对于git来说,针对已跟踪文件的移动来说,起始就是一个 renamed操作。现在如果相对该文件进行还原,来看看如何操作
[root@huangzb mygit]# git reset HEAD a.txt
Unstaged changes after reset:
D a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: m1/a.txt
#
# 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: a.txt
#
[root@huangzb mygit]# git checkout -- a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: m1/a.txt
#
[root@huangzb mygit]# git reset HEAD m1/a.txt
[root@huangzb mygit]# git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# m1/
nothing added to commit but untracked files present (use "git add" to track)
[root@huangzb mygit]#
由上图可知,其实移动操作,在git中分成了两个步骤,
- 删除了 a.txt 文件,
- 添加了 m1/a.txt 文件,
因此如果想要还原到最初的状态,也需要对着两步分别还原,我们知道单独的从一步,从暂存区还原数据,也是需要两步
- 使用 git reset 从版本库中更新为最新的数据到暂存区,变相的还原了暂存区的修改
- 使用 git checkout 从暂存区中恢复工作目录数据,达到恢复最初数据的目的
因此,上图,也分别使用了这两步,将 a.txt 进行了还原,同时 看最后的结果,针对新添加的文件,我们已经从暂存区中删除了跟踪,即 m1/a.txt 该文件已经变成了未跟踪文件,此时还原,只要通过bash命令直接删除即可。如下图:
[root@huangzb mygit]# rm -rf m1
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
nothing to commit, working directory clean
[root@huangzb mygit]#
这样,就完成了正常移动操作的还原步骤
4.2 使用 git mv 命令来进行移动操作
同 删除操作一样,同样的针对移动操作,git也提供了 一个 git mv 命令来帮助我们优化bash命令的移动操作。同4.1 而言,我们使用 bash命令 mv 来移动文件后,还需要手动的使用 git add 来将文件变化添加到暂存区,而使用 git mv 命令就可以直接帮我们将变化提交到暂存区。如下图
[root@huangzb mygit]# ll
total 8
-rw-r--r-- 1 root root 6 Mar 21 19:35 a.txt
-rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
[root@huangzb mygit]#
[root@huangzb mygit]# mkdir m2
[root@huangzb mygit]# git mv a.txt m2/
[root@huangzb mygit]# tree
.
├── m2
│ └── a.txt
└── test.txt
1 directory, 2 files
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: a.txt -> m2/a.txt
#
[root@huangzb mygit]#
由上图可以看出,直接使用命令 git mv 就达到了上述的效果,下一步就是使用 git commit来进行提交到版本库,这里就不演示了,下面来快速的进行还原,还原操作其实同 4.1 一致,如下图:
[root@huangzb mygit]# git reset HEAD a.txt
Unstaged changes after reset:
D a.txt
[root@huangzb mygit]# git checkout -- a.txt
[root@huangzb mygit]# git reset HEAD m2/a.txt
[root@huangzb mygit]# git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# m2/
nothing added to commit but untracked files present (use "git add" to track)
[root@huangzb mygit]# rm -rf m2/
[root@huangzb mygit]# tree
.
├── a.txt
└── test.txt
0 directories, 2 files
[root@huangzb mygit]# git status
# On branch master
nothing to commit, working directory clean
[root@huangzb mygit]#
5. 重命名操作
重命名操作本质上就是一个 移动操作,快速的使用 git mv 命令来演示一下
如下图:
[root@huangzb mygit]# git mv a.txt b.txt
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: a.txt -> b.txt
#
[root@huangzb mygit]#
[root@huangzb mygit]# git reset HEAD a.txt
Unstaged changes after reset:
D a.txt
[root@huangzb mygit]# git checkout -- a.txt
[root@huangzb mygit]# git reset HEAD b.txt
[root@huangzb mygit]# git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# b.txt
nothing added to commit but untracked files present (use "git add" to track)
[root@huangzb mygit]#
[root@huangzb mygit]# rm -rf b.txt
[root@huangzb mygit]# ll
total 8
-rw-r--r-- 1 root root 6 Mar 21 19:56 a.txt
-rw-r--r-- 1 root root 12 Mar 15 21:17 test.txt
[root@huangzb mygit]#
由上图可知,我们使用 git mv命令 将 a.txt 重命名为 b.txt ,其实还是使用了 git mv 命令,效果跟 4.x步骤一样,还原操作也是一样的。