前言
該文章只是記錄了一些自己的見解,可能並不准確,只是為了學習時的一些記錄,不喜勿噴,謝謝
內容比較啰嗦,主要是寫該文章時,記錄了其學習的過程
該文章中主要介紹 添加文件,修改文件,刪除文件等對應的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步驟一樣,還原操作也是一樣的。
