git入門與實踐(2)
1. 刪除文件
可能大家第一想到的是手動刪除:
手動刪除mytest
文件
此時刪除的文件,僅僅刪除的工作區的,而git倉庫中的文件仍然存在!
1. 1 命令行刪除
git rm <file>
刪除git倉庫中記錄的文件,並且不保留在工作目錄中
此時執行完刪除後,提示提交到倉庫。
此時不僅刪除了工作區的文件,倉庫中也同樣刪除了!
我們不需要先手動刪除工作區的文件,git rm <file>
會同時刪除工作區和倉庫中的文件。
1. 1. 1 強制刪除
git rm -f(force) <file>
強制刪除
1. 1. 2 手動刪除工作目錄中的文件
windows可直接手動刪除,無需藉助命令。
1. 1. 3 刪除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
注意:不要隨便就強制刪除,因爲很容易導致一些修改你沒有提交,就會丟失這些暫存信息。
2. 移動文件
2. 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%)
這裏即爲重命名操作!
2. 1. 1 重命名文件原理
我們修改y.txt 的文件名:
mv z.txt b.txt
從這裏我們可以發現,重命名一個文件,系統其實是先刪除z.txt
,再創建一個b.txt
,並同時把a.txt
的內容複製進去。因此這裏纔會有一個刪除文件操作,以及未追蹤的文件b。
接下來,我們還需要刪除倉庫的z.txt
文件,並把b.txt
放入暫存區
實際上git根據我們的操作,就知道我們的最終目的也是重命名了。
2. 1. 2 git上移動文件(或重命名文件)原理
git mv file_from file_to
以上命令相當於以下三條
mv file_from file_to
git rm file_from
git add file_to
要想實現移動文件的原理,我們要是先刪除文件,再添加文件是不行的,git是無法判斷我們是想移動文件的,必須先告訴它我們要移動文件了纔行。
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 rm 3.txt
git add 33.txt
對比以上三條命令和git mv file_from file_to
是等同的。
實際移動文件就是重命名文件,
3. 查看功能
3. 1 git status
git status
打印文件狀態(未追蹤、已修改、已暫存)
我們其實可以發現,我們做每一步的操作,git都給了我們命令提示。
如果修改了文件內容。
其實,我們也發現每一步的提示太多了,假若這裏處理的文件很多,提示太長,那有沒有簡便地文件狀態呢?
3. 1. 1 git status -s
git status -s = git status --short
簡化文件狀態打印內容
3. 1. 1. 1 short狀態碼
??
代表未追蹤的文件 3.txt
AM
代表添加到暫存區的且被修改但是未放入暫存區 0.txt
A
代表添加到暫存區的 2.txt
我們再看看其他狀態:
未追蹤狀態
變爲添加到暫存區
修改3.txt
內容
代表添加到暫存區的
且被修改但是未放入暫存區
add
後,代表添加到暫存區的
提交後,就沒有當前任何狀態信息了。
再修改3.txt
內容
狀態:被修改但是未放入暫存區
(靠右邊的M
)
add
後,代表被修改後放入暫存區
(靠左邊的M
)
再修改3.txt
內容
MM
修改後放入暫存區,並且又再次修改
3. 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
(靠左邊)代表重命名(移動文件)
3. 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
-------------------------------------------------
3. 2 git diff
git diff
查看當前文件的修改(主要看工作區)
新建一個diff.txt
,提交暫存區,再修改其內容後,我們想查看它的變化記錄。
git diff
有的朋友可能會出現亂碼!注意:記事本保存應以utf-8方式保存!
---
代表之前提交到暫存區的內容。
+++
代表修改之後,未提交至暫存區的內容(在工作區)。
將其添加至暫存區,在對比,發現沒有記錄了。是因爲git diff
只是比較工作目錄與暫存、提交之間的差別,工作目錄是關鍵。工作目錄東西都提交,git就認爲沒有東西可對比了,執行git diff
後,就看不到任何變化了。
我們再修改文件!查看diff
。
我們再修改文件!
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
也是打印不出東西的。
3. 2. 1 git diff --staged
查看暫存區和提交區域之間的差異
再修改文件:
假如提交到暫存區,我們想看暫存區與提交的對比記錄。
git diff --staged
11111111111111111111111111111
第二次修改!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
以上是之前提交的內容!
-第三次改!
以上是最新提交的內容。
+第四次修改!
+a
+b
+c
以上是在暫存區的修改還沒有提交。
3. 3 git log 查看日誌
commit 68566241c1ac163e4e82f710009070648c1bdb00
提交後跟着的數字,實際上可以認爲是id(唯一的),它就可以完全代表此次的commit
提交了,它是通過git計算出來的,嚴格意義上應該稱爲校驗和
(或ssha-1),這裏包含文件內容、名字整合出來的,它有40個字符。
後面緊跟着作者和提交日期、記錄。
如果log
很多的話,就進入了日誌打印模式。可以看到最下面的:
,是不能再輸入命令的,按下q
,即可退出到終端原界面。
3. 3. 1 git log -p
查看詳細信息,加上之前git log
打印的信息,還加上了diff
的信息。
3. 3. 2 git log -n
查看最近的n條信息
3. 3. 3 git log --stat
列出所有被修改的文件,以及簡略的統計信息
3. 3. 4 git log --pretty
設置打印內容的格式
3. 3. 4. 1 -oneline 哈希和描述
git log --pretty=oneline
打印哈希和描述
3. 3. 4. 2 -short 哈希、作者、描述
git log --pretty=short
打印哈希、作者、描述
3. 3. 4. 3 -full 哈希、作者、提交者、描述
git log --pretty=full
打印哈希、作者、提交者、描述
此處的作者:實際修改的人
提交者:最後將此工作成果提交到倉庫的人
注意作者和提交者不一定是同一個人!
3. 3. 4. 4 -fuller 哈希、作者、日期、提交者、提交日期、描述
git log --pretty=fuller
打印哈希、作者、日期、提交者、提交日期、描述
3. 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"
打印詳細哈希和簡短哈希
4. HEAD和master
什麼是HEAD
?什麼是master
?
4. 1 提交對象
Git保存的並不是文件的變化或差異,而是一系列的不同時刻的文件快照。
快照是什麼呢?
打開網盤的百度快照
迴歸正題,其實git進行提交的時候就會拍照,即成爲快照。
提交操作時Git會保存一個提交對象,該對象中包含一個指向暫存內容快照的指針(理解爲編程語言的指針或引用是完全沒問題的)、作者姓名、郵箱、父對象指針以及提交輸入信息。
-
首次提交的對象沒有父對象
-
普通的提交有一個父對象
-
多個分支合併的有多個父對象
第n次提交實際就是提交對象,存在指向快照的指針,下次提交的對象存在一個指向父對象的指針。
4. 1. 1 搜索引擎快照
搜索引擎快照,是指在訪客在無法打開某個搜索結果,或者打開速度特別慢的情況下,爲訪客提供的之前保存在搜索引擎服務器上對應網頁內容的純文本。不過,搜索引擎保存的快照內容一般只包括文本數據,圖片及其他多媒體等非文本數據不會被保存。因此,在來源網站無法訪問的情況下,圖片及其他多媒體在快照中將無法顯示。
4. 1. 2 存儲快照
全球網絡存儲工業協會SNIA(StorageNetworking Industry Association)對快照(Snapshot)的定義是:關於指定數據集合的一個完全可用拷貝,該拷貝包括相應數據在某個時間點(拷貝開始的時間點)的映像。快照可以是其所表示的數據的一個副本,也可以是數據的一個複製品。
快照的作用主要是能夠進行在線數據備份與恢復。當存儲設備發生應用故障或者文件損壞時可以進行快速的數據恢復,將數據恢復某個可用的時間點的狀態。快照的另一個作用是爲存儲用戶提供了另外一個數據訪問通道,當原數據進行在線應用處理時,用戶可以訪問快照數據,還可以利用快照進行測試等工作。所有存儲系統,不論高中低端,只要應用於在線系統,那麼快照就成爲一個不可或缺的功能。
4. 2 master分支
Git的分支本質上僅僅指向提交對象的可變指針。
Git默認分支名:master
,它會在每一次的提交中自動前移。
master
指向的就是第n次提交對象呢?其實是不對的,實際master
代表指向一個類似鏈表一樣的結構,它實際指從第1次提交到第n次提交對象的整個一串糖葫蘆(分支)。將master
理解爲一個分支即可。
Git的分支 master
並不是一個特殊分支,它和其他的分支完全沒有區別,之所以每個分支都是有master
是git init
命令默認創建,而大部分人又懶得去更改。
4. 3 HEAD
Git保存着一個名爲 HEAD
的特殊指針。在 git 中,它是一個指向你正在工作中的本地分支的指針,即指向當前所在分支,可以將 HEAD
想象爲當前分支的別名。HEAD
是唯一的!
(後續待補充)