前言:
本文記錄學(xué)習(xí)使用 Git 版本管理工具的學(xué)習(xí)筆記,通過閱讀參考鏈接中的博文和實(shí)際操作,快速的上手使用 Git 工具。
本文參考了引用鏈接博文里的內(nèi)容。
引用:
Git使用教程-配置管理
git reset詳解-CSDN博客
3、Git使用不完全指南:git/github/gitlab/gitee的區(qū)別,原理和常用命令總結(jié)_gitlab github gitee-CSDN博客
正文
1. Git的3棵樹
在本地倉庫中Git維護(hù)三棵樹,這是Git的核心構(gòu)架。這三棵樹分別是:工作區(qū)域,暫存區(qū)域,和Git倉庫。
- 工作區(qū)域(Working Directory),就是你平時存放項(xiàng)目代碼的地方
- 暫存區(qū)域(Stage),用于臨時存放你的改動,事實(shí)上它只是一個文件,保存即將提交的文件列表信息。
- Git倉庫(Repository),就是安全村行數(shù)據(jù)的位置,這里有你提交的所有版本的數(shù)據(jù)。其中,HEAD指向最新放入倉庫的版本(這第3棵樹,確切的說,應(yīng)該是Git倉庫中的HEAD指向的版本)。
Git的一般工作流程是:
- 在工作目錄中添加,修改文件
- 將需要進(jìn)行版本管理的文件放入暫存區(qū)
- 將暫存區(qū)的文件提交到Git倉庫
因此,Git管理的文件有三種狀態(tài):已修改(modified),已暫存(staged),和已提交(commited),依次對應(yīng)上面的每一個流程。
2. Git初始化一個倉庫
###創(chuàng)建一個目錄,這個目錄將會作為git repository 倉庫
dimon@dimon-VirtualBox:~$ mkdir gittest
###進(jìn)入這個目錄
dimon@dimon-VirtualBox:~$ cd gittest/
###執(zhí)行'git init'命令初始化git項(xiàng)目,初始化成功之后會有一個隱藏的'.git'文件
dimon@dimon-VirtualBox:~/gittest$ git init
已初始化空的 Git 倉庫于 /home/dimon/gittest/.git/
###
dimon@dimon-VirtualBox:~/gittest$ git add README.md
fatal: 路徑規(guī)格 'README.md' 未匹配任何文件
###在當(dāng)前目錄里創(chuàng)建一個文件'README.md',md表示Markdown文件
dimon@dimon-VirtualBox:~/gittest$ touch README.md
###'git add'命令把文件加入暫存區(qū)
dimon@dimon-VirtualBox:~/gittest$ git add README.md
###'git commit'命令把文件提交到git倉庫repository,'-m'后面是提交日志
dimon@dimon-VirtualBox:~/gittest$ git commit -m "add a readme file"
[master (根提交) d7c707d] add a readme file
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 README.md
dimon@dimon-VirtualBox:~/gittest$
3. Git使用教程--狀態(tài)
怎么知道哪些文件是新添加的,哪些文件已經(jīng)加入到暫存區(qū)?總不能自己用文本記錄下來吧?
當(dāng)然不,作為通用的版本管理系統(tǒng),我們遇到的問題,Git都已經(jīng)有了解決方案,可以用 'gti status‘ 命令查看當(dāng)前狀態(tài)。
dimon@dimon-VirtualBox:~/gittest$ git status
On branch master
nothing to commit, working tree clean
dimon@dimon-VirtualBox:~/gittest$
on branch master:我們位于一個叫做'master’的分支里,這個是默認(rèn)的分支。
nothing to commit, working directory clean:說明你的工作目錄當(dāng)前是“干凈的”,沒有需要提交的文件(意思就是自上次提交之后工作目錄中的內(nèi)容壓根就沒有改動過)。
在工作目錄里添加 LICNESE 文件,并用Notepad++修改文件'LICENSE'的內(nèi)容。輸入 'git status'命令,提示如下:
###在工作目錄下創(chuàng)建了新文件'LICENSE'
dimon@dimon-VirtualBox:~/gittest$ touch LICENSE
dimon@dimon-VirtualBox:~/gittest$ ls
LICENSE README.md
###編輯文件的內(nèi)容
dimon@dimon-VirtualBox:~/gittest$ vi LICENSE
dimon@dimon-VirtualBox:~/gittest$
###'git status'命令查看文件的狀態(tài)
dimon@dimon-VirtualBox:~/gittest$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
LICENSE
nothing added to commit but untracked files present (use "git add" to track)
dimon@dimon-VirtualBox:~/gittest$
Untracked files 說明存在未追蹤文件(下面紅色的那個)
所謂的“未追蹤”文件,是指那些新添加的并且未被加入到暫存區(qū)域或者提交的文件。它們處于一個逍遙法外的狀態(tài),但你一旦將它們假如暫存區(qū)或提交到Git倉庫,他們就開始受到Git的“跟蹤”。
圓括號是的提示是 git 給用戶的提示:使用 git add <file> 命令將待提交的文件添加到暫存區(qū)域。
dimon@dimon-VirtualBox:~/gittest$ git add LICENSE
dimon@dimon-VirtualBox:~/gittest$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: LICENSE
dimon@dimon-VirtualBox:~/gittest$
‘use git reset HEAD <file>? to unstage’ 的意思是,如果你反悔了,你可以使用? git reset HEAD 命令恢復(fù)暫存區(qū)域。如果后面接文件名,表示恢復(fù)該文件;如果不接文件名,則表示上一次添加的文件。
再次添加到“暫存區(qū)域”,然后執(zhí)行 'git commit -m "add a license file"'命令:
###把文件'LICENSE'加到暫存區(qū)
dimon@dimon-VirtualBox:~/gittest$ git add LICENSE
###查看當(dāng)前文件狀態(tài),暫存區(qū)有文件未提交
dimon@dimon-VirtualBox:~/gittest$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: LICENSE
###把暫存區(qū)提交到Git 倉庫
dimon@dimon-VirtualBox:~/gittest$ git commit -m "add a license file"
[master a588543] add a license file
1 file changed, 6 insertions(+)
create mode 100644 LICENSE
###查看當(dāng)前文件狀態(tài)
dimon@dimon-VirtualBox:~/gittest$ git status
On branch master
nothing to commit, working tree clean
dimon@dimon-VirtualBox:~/gittest$
??
關(guān)于修改
突然發(fā)現(xiàn)版權(quán)那塊忘記寫上自己名字了...
打卡LINCESE文件,修改"Copyrith (c) 2024 dimon",保存。
執(zhí)行 git status 命令:
dimon@dimon-VirtualBox:~/gittest$ vi LICENSE
dimon@dimon-VirtualBox:~/gittest$ 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: LICENSE
no changes added to commit (use "git add" and/or "git commit -a")
dimon@dimon-VirtualBox:~/gittest$
由于對工作目錄中的文件進(jìn)行了修改,導(dǎo)致這個文件和“暫存區(qū)域”的文件不匹配了,所以Git提了兩條建議
- 使用 git add 將工作目錄的新版本覆蓋暫存區(qū)域的幾版本,然后提交
- 使用 git checkout將暫存區(qū)域的舊版本覆蓋工作目錄的新版本(危險(xiǎn)操作:相當(dāng)于丟棄工作目錄的修改)
還有一種情況沒有分析,大家先把新版本文件覆蓋掉暫存區(qū)域的舊版本:
dimon@dimon-VirtualBox:~/gittest$ git add LICENSE
dimon@dimon-VirtualBox:~/gittest$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: LICENSE
dimon@dimon-VirtualBox:~/gittest$
然后我們打開LINCENSE文件,將 Dimon 修改為 Dimon.chen?
dimon@dimon-VirtualBox:~/gittest$ vi LICENSE
dimon@dimon-VirtualBox:~/gittest$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: LICENSE (綠色)
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: LICENSE (紅色)
dimon@dimon-VirtualBox:~/gittest$
?這次的情況:被綠的LINCENSE文件存放在暫存區(qū)(待提交),同時紅色的LICENSE說明文件還在工作目錄等待添加到暫存區(qū)域。
這種情況你應(yīng)該意識到這里存在兩個不同版本的 LICENSE 文件,如果此時你直接執(zhí)行了 commit 命令,那么提交的是暫存區(qū)域的版本,如果你希望提交工作目錄的新版本,那么你先執(zhí)行 add 米寧覆蓋暫存區(qū)域,然后在提交。
一步到位
從工作目錄一步添加到Git倉庫: git commit -am "說明"
dimon@dimon-VirtualBox:~/gittest$ git commit -am "change the license file"
[master 1657372] change the license file
1 file changed, 1 insertion(+), 1 deletion(-)
dimon@dimon-VirtualBox:~/gittest$
-a的已是是add。
git log 查看歷史操作記錄
3. Git使用教程5
?有關(guān)回退的命令有兩個: reset 和 checkout
先執(zhí)行Git log命令,將此事的Git倉庫可視化
三棵樹的情況
回滾快照
注:快照即提交的版本,每一個版本我們稱之為一個快照。
現(xiàn)在我們利用 reset 命令回滾快照,幫看看Git倉庫和三棵樹分別發(fā)生了什么。
執(zhí)行: git reset HEAD ~ 命令:
主: HEAD 表示最新提交的快照,而 HEAD ~表示HEAD的上一個快照,HEAD~~表示上上個快照。如果表示10個快照可以使用 HEAD~10?
###現(xiàn)在'git log'能看到3個版本,HEAD指向第3次提交
dimon@dimon-VirtualBox:~/gittest$ git log
commit 1657372baaca2c3c797d3e2f1676b087810e655b (HEAD -> master)
Author: dimon <1181302388@qq.com>
Date: Fri Mar 15 10:48:34 2024 +0800
change the license file
commit a588543db607cffd7ec6d2a6504175639d8ed61b
Author: dimon <1181302388@qq.com>
Date: Fri Mar 15 10:13:20 2024 +0800
add a license file
commit d7c707d2c4b2dc4c332e252c419f47c4eabc4846
Author: dimon <1181302388@qq.com>
Date: Thu Mar 14 18:21:33 2024 +0800
add a readme file
dimon@dimon-VirtualBox:~/gittest$ git reset HEAD~
Unstaged changes after reset:
M LICENSE
dimon@dimon-VirtualBox:~/gittest$ 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: LICENSE
no changes added to commit (use "git add" and/or "git commit -a")
###現(xiàn)在'git log'能看到2個版本,HEAD指向第2次提交
dimon@dimon-VirtualBox:~/gittest$ git log
commit a588543db607cffd7ec6d2a6504175639d8ed61b (HEAD -> master)
Author: dimon <1181302388@qq.com>
Date: Fri Mar 15 10:13:20 2024 +0800
add a license file
commit d7c707d2c4b2dc4c332e252c419f47c4eabc4846
Author: dimon <1181302388@qq.com>
Date: Thu Mar 14 18:21:33 2024 +0800
add a readme file
dimon@dimon-VirtualBox:~/gittest$
此時我們回滾到第二課樹(暫存區(qū)域)
?
第一次執(zhí)行reset后的Git倉庫
git reset HEAD~ 命令其實(shí)是 git rest --mixed HEAD~ 的縮寫,--mixed選型是默認(rèn)的。
git reset HEAD~ 命令其實(shí)影響了兩棵樹:首先是移動 HEAD 的指向,將其指向上一個快照(HEAD~);然后再講該位置的快照回滾到暫存區(qū)域。
--soft 選項(xiàng)
git reset --soft HEAD~ 命令就相當(dāng)于只移動 HEAD 的指向,但并不會將快照回滾到暫存區(qū)。相當(dāng)于撤銷了上一次的提交(commit)。以不小心提交了,后悔了,那么你就執(zhí)行 git reset --soft HEAD~ 命令(此時執(zhí)行命令 git log 命令,也不會再看到已經(jīng)撤銷的那個提交)。
--hard選項(xiàng)
reset不僅移動HEAD的指向,將快照回滾到暫存區(qū),它還將暫存區(qū)的文件還原到工作目錄。
回滾指定快照
reset 不僅可以回滾指定快照,可以可以回滾個別文件
命令格式: git reset 快照 文件名/路徑
這樣,它就會忽略移動HEAD指向這一步(因?yàn)槟阒R回滾快照的部分內(nèi)容,并不是整個快照,所以HEAD的指向不應(yīng)發(fā)生改變),直接將指定快照的指定文件回滾到暫存區(qū)域。
不僅可以往回滾,還可以往前滾。
這里需要強(qiáng)調(diào)的是: reset 不僅是一個“復(fù)古”的命令,它不僅可以回到過去,還可以到“未來”。
唯一的前提條件是:你需要指導(dǎo)指定快照的ID號。
哪如果不小心把命令窗口關(guān)了不記得ID號怎么辦?
命令: git reflog
Git揭露的每一次操作的版本號ID。
4. Git使用教程6--版本對比
目的:對比版本之間有哪些不同。
準(zhǔn)備工作
創(chuàng)建一個叫做MyProject2的新文件作為此次演示的目錄,初始化Git。
創(chuàng)建一個game.py的文件,將下面代碼拷貝進(jìn)去。
再新建一個README文件,寫清楚這是第一個課后作業(yè)。
執(zhí)行 git add README game.py 命令將文件添加到暫存區(qū),緊著執(zhí)行 git commit -m '猜數(shù)字游戲' 提交一個項(xiàng)目快照。
dimon@dimon-VirtualBox:~/MyProject2$ git init
Initialized empty Git repository in /home/dimon/MyProject2/.git/
dimon@dimon-VirtualBox:~/MyProject2$ touch game.py
dimon@dimon-VirtualBox:~/MyProject2$ vi game.py
dimon@dimon-VirtualBox:~/MyProject2$ touch README
dimon@dimon-VirtualBox:~/MyProject2$ vi README
dimon@dimon-VirtualBox:~/MyProject2$ git add README game.py
dimon@dimon-VirtualBox:~/MyProject2$ git commit -m "猜數(shù)字游戲"
[master (root-commit) c1df484] 猜數(shù)字游戲
2 files changed, 22 insertions(+)
create mode 100644 README
create mode 100644 game.py
dimon@dimon-VirtualBox:~/MyProject2$ vi game.py
dimon@dimon-VirtualBox:~/MyProject2$ vi README
dimon@dimon-VirtualBox:~/MyProject2$ git diff
然后修改 game.py 文件內(nèi)容化和 README文件內(nèi)容。
比較暫存區(qū)域域工作目錄的差異:
直接執(zhí)行 git diff 命令是比較暫存區(qū)域與工作目錄的文件內(nèi)容。
現(xiàn)在來解釋一下上面每一行的含義:
第一行: diff --git a/README b/README
表示對比的存放在暫存區(qū)域的README和工作目錄的README
第二行: index 2146df9..7d37b6e 100644
表示對應(yīng)的文件ID分別是2146df9 和7d37b6e,左邊暫存區(qū)域與,右邊當(dāng)前目錄。最后的100644是指定文件的類型和權(quán)限。
第三行:--- a/README
---表示的是就文件(存放在暫存區(qū)域)
第四行:+++ b/README
+++表示該文件是新文件(存放在工作區(qū)域)
第五行:@@ -1 +1,2 @@
以@@開頭和結(jié)束,總監(jiān)的-表示舊文件,+表示新文件,后面的數(shù)字表示開始行號,顯示行數(shù)。
第6,7行:?
home work 2024-03-15 11:37
+《零基礎(chǔ)入門學(xué)習(xí)Git》
這是將兩個文件合并顯示的結(jié)果,前面有+的綠色一行說明是新文件所獨(dú)有的,淺灰色的說明是兩個文件共享的。所有,+1,2 表示線文件合并顯示中從第一行開始,顯示2行內(nèi)容。那為啥-1后面沒有顯示行數(shù)?因?yàn)樵诤喜@示結(jié)果中,舊文件已經(jīng)完全包含在新文件中了(也就是舊文件沒有自己的“獨(dú)有”內(nèi)容)。
最后的(:)是什么?
意思是窗口太小,沒有辦法完全顯示,正在等待命令(Vim編程知識)
移動命令:
- j,k:向下/向上一行
- f,b:向下翻頁/向上翻頁
- d,u:向下翻半頁/向上翻半頁
跳轉(zhuǎn)命令
g, G:跳轉(zhuǎn)到第一行/跳轉(zhuǎn)到最后一行
搜索命令
輸入反斜杠(/)或問號(?),后面搜索關(guān)鍵字
區(qū)別:斜杠(/)表示從當(dāng)前位置向下搜索,問號(?)表示從當(dāng)前位置向上搜索
接著輸入n表示順著當(dāng)前的搜索方向快速調(diào)到下一個匹配位置,大寫的N則是與當(dāng)前搜索方向相反。
退出和幫助
在點(diǎn)點(diǎn)(:)后面輸入q,表示退出diff;輸入h表示進(jìn)入幫助頁面,你會看看到很多命令和功能,輸入q可以退出幫助頁面。
比較兩個歷史快照
我們執(zhí)行命令 git commit -am "添加功能:玩家只有三次機(jī)會”命令,添加并提交目錄中的所有文件。執(zhí)行g(shù)it log命令,可以看到Git倉庫中已經(jīng)有連個快照了。
###查看當(dāng)前'git status'狀態(tài)
dimon@dimon-VirtualBox:~/MyProject2$ 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: README
modified: game.py
no changes added to commit (use "git add" and/or "git commit -a")
###‘git commit -am’ 一次性提交工作目錄到暫存目錄和Git倉庫
dimon@dimon-VirtualBox:~/MyProject2$ git commit -am "添加功能:玩家只有三次機(jī)會"
[master 7e3a972] 添加功能:玩家只有三次機(jī)會
2 files changed, 9 insertions(+), 4 deletions(-)
dimon@dimon-VirtualBox:~/MyProject2$
###‘git log’查看當(dāng)前Git倉庫快照,當(dāng)前有兩個快照
dimon@dimon-VirtualBox:~/MyProject2$ git log
commit 7e3a9725b0e348a938153d37b6450eb74eb5febb (HEAD -> master)
Author: dimon <1181302388@qq.com>
Date: Fri Mar 15 14:37:26 2024 +0800
添加功能:玩家只有三次機(jī)會
commit c1df484caeee134d604a08e6957b28fb836c1ea3
Author: dimon <1181302388@qq.com>
Date: Fri Mar 15 11:38:14 2024 +0800
猜數(shù)字游戲
dimon@dimon-VirtualBox:~/MyProject2$
執(zhí)行命令 git diff?7e3a972?c1df484 命令,既可以比較Git倉庫中兩個快照的差異
?git diff 7e3a9725b0e348a938153d37b6450eb74eb5febb? ?c1df484caeee134d604a08e6957b28fb836c1ea3
比較當(dāng)前工作目錄和Git倉庫中的快照
我們稍微改動一下README的內(nèi)容
目前我們的Git倉庫應(yīng)該是
三棵樹應(yīng)該是
比較之前版本和快照與當(dāng)前工作目錄的內(nèi)容
輸入: git diff ed3708c 命令即可
比較當(dāng)前版本庫快照與當(dāng)前工作目錄的內(nèi)容,
輸入: git diff HEAD 命令即可
比較Git倉庫與暫存區(qū)域
執(zhí)行 git add README.md命令,將第三版的README文件添加到暫存區(qū)域。
然后三棵樹就是這樣的了:
如果希望比較最新提交的快照和暫存區(qū)域的文件,只需要執(zhí)行命令 diff --cached 命令;當(dāng)前艷也可以指定其他快照,就是需要多協(xié)商一個ID值,即 git diff --cached ID號。
哈哈,感覺有點(diǎn)亂,實(shí)際上就是這三棵樹之間相互比較,最后附上一個總結(jié)圖片。
?
5. Git使用教程7--修改最后一次提交,刪除文件和重命名文件
問題出現(xiàn)
Situation one: 版本一提交(commit)到倉庫,突然想起漏掉了兩個文件還沒有添加(add)
Situation two: 版本一提交(commit)到倉庫,突然興起版本說明寫的不夠全面,無法彰顯你本次修改的重大意義....
由于使用 reset 命令過于繁瑣,需要提交一個新的版本,這里可以使用帶 --amend 選項(xiàng)的 commit 命令(即 git commit -amend) Git 會“更正”最近一次的提交。由于這里沒有-m說明,會進(jìn)入一下頁面。
這個編輯界面知識讓你編輯提交說明而已。如果不需要修改,可以連續(xù)按兩次大寫Z來退出,或者先按下(:),再輸入q!退出,Git會保留舊的提交說明。如果需要提交說明又不想出現(xiàn)這么繁瑣的方式,輸入 git commit --amend -m "新的提交說明"就可以。
刪除文件
問題1:不小心刪除文件怎么辦?
現(xiàn)在從工作目錄總手動刪除 README 文件,然后執(zhí)行 git status命令:
提醒使用 checkout 命令可以將暫存區(qū)域的文件恢復(fù)到工作目錄:
dimon@dimon-VirtualBox:~/MyProject2$ git checkout -- README
dimon@dimon-VirtualBox:~/MyProject2$
注意 "--"兩端各有一個空格。
問題2:如何徹底刪除一個文件哪?
假如不小心把小黃圖下載到工作目錄,然后又不小心提交到了Git倉庫。
dimon@dimon-VirtualBox:~/MyProject2$ touch yellow.jpg
dimon@dimon-VirtualBox:~/MyProject2$ git add yellow.jpg
dimon@dimon-VirtualBox:~/MyProject2$ git commit -m "有一次偉大的改進(jìn)"
[master eeba2c4] 有一次偉大的改進(jìn)
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 yellow.jpg
dimon@dimon-VirtualBox:~/MyProject2$
執(zhí)行 git rm yellow.jpg 命令
dimon@dimon-VirtualBox:~/MyProject2$ git rm yellow.jpg
rm 'yellow.jpg'
dimon@dimon-VirtualBox:~/MyProject2$
此時工作目錄中的小黃圖(yellow.jpg)已經(jīng)被刪除了...
但是執(zhí)行 git status 命令,你仍然發(fā)現(xiàn)Git還不肯松手
dimon@dimon-VirtualBox:~/MyProject2$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: yellow.jpg
dimon@dimon-VirtualBox:~/MyProject2$
意思說它在倉庫快照里發(fā)現(xiàn)有一個 'yellow.jpg'的文件,但似乎在暫存區(qū)域和當(dāng)前工作目錄不見了。
此時可以執(zhí)行 git reset -- soft HEAD~ 命令將快照回滾到上一個位置,然后重新提交,Git就不會再提小黃圖的事了。
dimon@dimon-VirtualBox:~/MyProject2$ git reset --soft HEAD~
dimon@dimon-VirtualBox:~/MyProject2$ git status
On branch master
nothing to commit, working tree clean
dimon@dimon-VirtualBox:~/MyProject2$
注意:rm命令刪除的只是工作目錄和暫存區(qū)的文件(即取消跟蹤,下一次提交是不納入版本管理)
問題3:我在工作目錄里中增加了一個 test.py 文件,然后執(zhí)行 git add test.py 命令將其加入到暫存區(qū),此時我修改了test.py文件的內(nèi)容,那么暫存區(qū)和工作目錄就是兩個不同的test.py文件了,此時如果我執(zhí)行 git rm test.py 命令,Git會下意識的阻止我,這怎么辦?
dimon@dimon-VirtualBox:~/MyProject2$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: test.py
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: test.py
dimon@dimon-VirtualBox:~/MyProject2$
dimon@dimon-VirtualBox:~/MyProject2$ git rm test.py
error: the following file has staged content different from both the
file and the HEAD:
test.py
(use -f to force removal)
dimon@dimon-VirtualBox:~/MyProject2$
因?yàn)閮蓚€不同內(nèi)容的同名文件,誰知道你是不是搞清楚了都要刪除?還是提醒一下好,別等一下出錯又要賴機(jī)器。。。
根據(jù)提示,執(zhí)行 git rm -rf test.py 命令就可以把兩個都是刪除
問題4:我只想刪除暫存區(qū)域的文件,保留工作目錄,應(yīng)該怎樣操作?
執(zhí)行 git rm --cached “文件名” 命令。
重命名文件
直接在工作目錄重命名文件,執(zhí)行 git status 會出錯
正確的姿勢應(yīng)該是:
git mv 舊文件名 新文件名
dimon@dimon-VirtualBox:~/MyProject2$ git mv test.py TEST.py
dimon@dimon-VirtualBox:~/MyProject2$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: test.py -> TEST.py
dimon@dimon-VirtualBox:~/MyProject2$ git commit -m 'rename test.py to TEST.py'
教程彩蛋6:
如何讓Git識別某些格式的文件,然后自動不跟蹤他們?
比如工作目錄里有三個文件 1.temp, 2.temp, 3.temp ,我們不希望后綴名為 .temp 的文件被跟蹤,可是每次 git status 都會出現(xiàn)
6. Git使用教程7--創(chuàng)建和切換分支
分支是什么?
假設(shè)你的大項(xiàng)目已經(jīng)上線了(有上百萬人在使用),過了一段時間及突然覺得應(yīng)該添加一些新功能,但是為了保險(xiǎn)起見,你肯定不能再當(dāng)前項(xiàng)目上直接開發(fā),這時候你就有創(chuàng)建分支的必要了。
對比其他版本控制系統(tǒng)而言,創(chuàng)建分支常常需要創(chuàng)建一個源代碼目錄的副本,項(xiàng)目越大,耗費(fèi)的時間就越多;而Git由于每一個節(jié)點(diǎn)都已經(jīng)是一個完整的項(xiàng)目,所以只需要創(chuàng)建多一個“指針”(像master)指向分支開始的位置即可。
創(chuàng)建分支
來到之前創(chuàng)建的項(xiàng)目MyProject2,
當(dāng)前項(xiàng)目狀態(tài)如下
執(zhí)行Git status查看狀態(tài)
可以看到README文件被修改并添加到暫存區(qū)域(還沒有提交),所以當(dāng)前三棵樹應(yīng)該是這樣:
創(chuàng)建分支,使用 “git branch 分支名” 命令:
dimon@dimon-VirtualBox:~/MyProject2$ git branch feature
dimon@dimon-VirtualBox:~/MyProject2$
沒有任何提示說明分支創(chuàng)建成功(一般也不會失敗,除非創(chuàng)建了同名的分支會提醒你一下),此時執(zhí)行 git log --decorate 命令查看:
如果希望以“精簡版”的方式顯示,可以加上一個 --oneline 選項(xiàng)(即 git log --decorate --oneline),這樣就只用一行來顯示快照記錄。
可以看到最新的快照后面多了一個(HEAD->master,fature)
它的意思是:目前有兩個分支,一個是主分支(master),一個是我們剛才創(chuàng)建的新分支(feature),然后HEAD指針仍然指向默認(rèn)的master分支。
目前倉庫中的快照應(yīng)該是這樣的。
切換分支
現(xiàn)在我們需要將工作目錄環(huán)境切換到新創(chuàng)建的分支(feature)上,使用的是我們之前語言又止的checkout命令。執(zhí)行 git checkout feature 命令:
dimon@dimon-VirtualBox:~/MyProject2$ git checkout feature
M README
Switched to branch 'feature'
dimon@dimon-VirtualBox:~/MyProject2$
這樣HEAD指針就指向了 feature 分支了:
dimon@dimon-VirtualBox:~/MyProject2$ git log --decorate --oneline
d97db41 (HEAD -> feature, master) rename test.py to TEST.py
4bd1779 add faile test.py
67d158e 添加功能:玩家只有三次機(jī)會
c1df484 猜數(shù)字游戲
dimon@dimon-VirtualBox:~/MyProject2$
現(xiàn)在我們再進(jìn)行一次提交(暫存緩沖區(qū)還有一個更改的文件沒有提交呢):
dimon@dimon-VirtualBox:~/MyProject2$ git commit -m "修改了說明文件"
[feature d158dfb] 修改了說明文件
1 file changed, 1 insertion(+)
dimon@dimon-VirtualBox:~/MyProject2$
現(xiàn)在倉庫中的快照應(yīng)該是這個樣子(提交的快照由當(dāng)前HEAD指針指向的分支來管理)
?
?然后我們再講 HEAD 指針切回 master 分支
dimon@dimon-VirtualBox:~/MyProject2$ git checkout master
Switched to branch 'master'
dimon@dimon-VirtualBox:~/MyProject2$
細(xì)心的朋友會發(fā)現(xiàn)上一次對 README 文件的修改已經(jīng)當(dāng)然無存了,這是因?yàn)槲覀児ぷ髂夸浺呀?jīng)回到了 master 分支的狀態(tài)。
現(xiàn)在對 README 文件做修改(隨意修改),然后執(zhí)行 git commit -m "再次修改說明文件":
dimon@dimon-VirtualBox:~/MyProject2$ git commit -am "再次修改說明文件"
[master 756c48b] 再次修改說明文件
1 file changed, 1 insertion(+)
dimon@dimon-VirtualBox:~/MyProject2$
目前倉庫快照變成了這樣
執(zhí)行 git log --oneline --decorate --graph --all 命令
--graph 選項(xiàng)表示讓 Git 繪制分支圖,--all 表示顯示所有分支
?7. Git使用教程9-合并和刪除分支
合并分支
當(dāng)一個子分支的使命完成后,它就應(yīng)該回歸到主分支中去。
合并分支我們使用 merge 命令,執(zhí)行 git merge feature 命令,將 feature 分支合并到 HEAD 所在的分支(master)上:
dimon@dimon-VirtualBox:~/MyProject2$ git merge feature
Auto-merging README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then commit the result.
dimon@dimon-VirtualBox:~/MyProject2$
從Git提示的內(nèi)容來看,我們知道這次合并并沒有成功,Git提示:
合并 README 時出現(xiàn)了沖突。
所以自動合并失?。徽埿薷臎_突的內(nèi)容請從新提交快照。
意思是說現(xiàn)在你需要先解決沖突的問題,Git才能進(jìn)行合并操作。所謂沖突,無非就是像兩個分支中存在同名但內(nèi)容卻不相同的問價(jià),Git不知道你要舍棄哪一個或者保留哪一個,所以需要你自己來決定。
此時執(zhí)行 git status 命令也會顯示需要你解決沖突:
然后Git會在有沖突的文件中加一些標(biāo)記,可以打開 README 文件查看一下:
以 ‘=====’為界,上到"<<< HEAD"表示當(dāng)前分支,下到">>> fature"表示 待合并的 feature 分支,之間的內(nèi)容就是沖突的地方。
現(xiàn)在我們將README 同意修改掉(去掉 <<<< HEAD 等內(nèi)容)
保存文件,然后提交快照
dimon@dimon-VirtualBox:~/MyProject2$ git add README
dimon@dimon-VirtualBox:~/MyProject2$ git commit -m '解決沖突'
[master 90086a5] 解決沖突
dimon@dimon-VirtualBox:~/MyProject2$
執(zhí)行 git log --decorate --all --graph --oneline 命令,可以看到此時分支已經(jīng)自動合并了
?
當(dāng)然,如果不存在沖突,就不用搞這么多了... ,舉個例子:
執(zhí)行: git checkout -b feature2 命令,(相當(dāng)于 git branch feature2 和 git checkout feature2 兩個命令的合體)
dimon@dimon-VirtualBox:~/MyProject2$ git branch feature2
dimon@dimon-VirtualBox:~/MyProject2$ git checkout feature2
Switched to branch 'feature2'
dimon@dimon-VirtualBox:~/MyProject2$
在工作目錄隨便創(chuàng)建一個文件 feature2.txt 并提交快照。
dimon@dimon-VirtualBox:~/MyProject2$ git add feature2.txt
dimon@dimon-VirtualBox:~/MyProject2$ git commit -m "我就是試試"
[feature2 11c5b05] 我就是試試
1 file changed, 1 insertion(+)
create mode 100644 feature2.txt
dimon@dimon-VirtualBox:~/MyProject2$
執(zhí)行 git log --decorate --oneline --graph --all 命令:?
可以看到, feature 分支比master分支快了一步?,F(xiàn)在我們切換回 master 分支,并將 feature2 分支合并進(jìn)來:
###當(dāng)前工作目錄切換到 master 分支
dimon@dimon-VirtualBox:~/MyProject2$ git checkout master
Switched to branch 'master'
dimon@dimon-VirtualBox:~/MyProject2$
###'git merge'合并 feature2 分支到 master 分支
dimon@dimon-VirtualBox:~/MyProject2$ git merge fature2
merge: fature2 - not something we can merge
dimon@dimon-VirtualBox:~/MyProject2$ git merge feature2
Updating 90086a5..11c5b05
Fast-forward
feature2.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 feature2.txt
dimon@dimon-VirtualBox:~/MyProject2$
這次 git 只顯示了 fast-forward (快進(jìn))這個詞,這是因?yàn)?feature2 這個分支的父節(jié)點(diǎn)是 master 分支,所以 git 只需要簡單的而移動 master 的指向就可以。
執(zhí)行 git log --decorate --all --graph --oneline 命令:
刪除分支,使用 git branch -d "分支名" 命令:
dimon@dimon-VirtualBox:~/MyProject2$ git branch -d feature
Deleted branch feature (was d158dfb).
dimon@dimon-VirtualBox:~/MyProject2$
執(zhí)行 git log --decorate --all --graph --oneline 命令:
用于Git的分支原理實(shí)際上只是通過一個指針記載,所以創(chuàng)建和刪除分支都幾乎是瞬間完成。
注意:如果試圖刪除為合并的分支,Git會提示你“該分支未完全合并,如果你確定要刪除,請使用 git branch -D 分支名”命令。
彩蛋:Git的兩種合并方式--Fast-forward和Three-way-merge
Fast-forward
所謂的 Fast-forward 就是當(dāng)待合并的分支位于目標(biāo)分支的直接上游時,Git只需要把目標(biāo)分支的指針直接移動既可以實(shí)現(xiàn)合并。
如下圖 master 分支就是位于 feature2 分支的直接下游:
將 fearture2 分支合并到 master 分支,只需要移動 master 分支即可。
Three way Merge
如果待合并的兩個分支不在同一條線上,那么進(jìn)行合并就需要解決一個根本的問題--沖突!
為何兩個分支在同一條線上就不會出現(xiàn)沖突?
因?yàn)镚it的快照是按時間順序提交的,所以在同一條時間線上的兩個快照,他們是有先后順序,盡管兩者可能出現(xiàn)同名文件不同內(nèi)容,Git會認(rèn)賊這是“改變”而不是“沖突”。
舉個例子:
合并 C3 和 C4 得到C5,但C5應(yīng)該如何處理沖突哪?
SVN會把問題拋給用戶,讓用戶自行解決;Git則顯得更為高明,它會找到第三個快照,然后綜合三者特點(diǎn)自動解決沖突。
那第三個虧按照應(yīng)該如何決定哪?
沒錯,應(yīng)該找兩者的共同“祖先”作為參照物,一比較就知道兩個分支都干了什么?
圖片中C3, C4的共同祖先是C1,可以看到C3和C4分別增加了 test2.py 和 test1.py 兩個文件。因?qū)Ρ戎蟀l(fā)現(xiàn)三者并沒有沖突,所以C5應(yīng)該是三者的合體,集同事?lián)碛?comm.py test1.py 和 test2.py 三個文件。
另外,值得一提的是,Git的這種合并方式也適用于同名文件的不同更改。
舉個例子:
這里C3和C4都只有一個文件 test.txt ,但是內(nèi)容卻不一樣。如果這樣合并,你猜Git會不會報(bào)“沖突”?
答案是不會的!
因?yàn)?Git 找到了它們的共同祖先 C1,可以看到C3 和 C4 都是在 C1 的基礎(chǔ)上機(jī)型添加(C4在第二行添加了"I",C3在第四行添加了"FishC",C1的第三行“Love”是他們共同擁有的),同時在每一行并沒有產(chǎn)生沖突的地方,所以Git會自動合并的C5是這樣的。
#test.txt
I
Love
FishC
注意:如果Git檢測到同一行有不同的內(nèi)容,還會報(bào)沖突并讓你自行決定去誰留誰的。
8. Git使用教程10--匿名分支和chekout命令
再論checkout
事實(shí)上,checkout 命令有兩種功能。
- 從歷史快照(或暫存區(qū)域)中拷貝文件到工作目錄
- 切換分支
從歷史快照(或暫存區(qū))中拷貝文件到工作目錄
當(dāng)給定某個文件名時,Git會從指定的提交中拷貝文件到暫存區(qū)域和工作目錄。比如執(zhí)行 git checkout HEAD~ README 命令會將上一個快照中的 README 文件復(fù)制到工作目錄和暫存區(qū)域中。
如果命令中沒有指定具體的快照ID,將從暫存區(qū)域恢復(fù)指定文件到工作目錄(git checkout README)
有些朋友會問:“上一次看你在文件前面有加兩個橫杠 -- ,這次怎么就沒有了呢?”
問題的好?Git提醒你寫成 git checkout -- README 的形式,那是為了預(yù)防你恰好有一個分支叫做 REDME,那么它就搞不懂你要恢復(fù)文件還是要切換分支了,所以約定兩個橫杠(--)后面跟的是文件名。
反過來說,如果你確保你沒有一個叫做 README 的分支,你直接寫 git checkout README 也是妥妥沒有問題的。
切換分支
首先我們知道 Git 的分支其實(shí)就是添加一個指向快照的指針,其次我們知道切換分支除了修改 HEAD 指針的的指向,還會改變暫存區(qū)域和工作目錄的內(nèi)容。
所以執(zhí)行 git chekout 373c0 命令,Git 主要做了下面兩件事(當(dāng)然事實(shí)上Git還做了更多)
那回過頭來 ,如果我們只想恢復(fù)指定的文件/路徑,那么我們只需要指定具體的文件,Git就會忽略第一步修改HEAD指向的操作,這不正是根之前講的reset命令一致的么?
checkout 命令和 reset 命令的區(qū)別
恢復(fù)文件
下面開始劃重點(diǎn):
它們的區(qū)別是 reset 命令只將指定文件恢復(fù)到暫存區(qū)域(--mixed),而 checkout 命令同時覆蓋暫存區(qū)域和工作目錄。
注意:也許你師徒使用 git rest --hard HEAD~ README 命令讓 reset 同時覆蓋工作目錄,但Git會告訴你這是徒勞的(此時 reset 不允許使用 --sort 或 hard 選項(xiàng))
這樣看來,在恢復(fù)文件方面, reset 命令要比 chekout 命令更安全一些。
恢復(fù)快照
reset 命令是用來“回到過去”的,根據(jù)選項(xiàng)的不同,reset命令將移動 HEAD 指針(--soft)-> 覆蓋暫存區(qū)域(--mixed,默認(rèn))->覆蓋工作目錄(--hard)。
checkout 命令雖說是用于切換分支,但前面你也看到了,它事實(shí)上也是通過移動 HEAD 指針和覆蓋暫存區(qū)域,工作目錄來實(shí)現(xiàn)的。
哪問題來了:他們有什么區(qū)別哪?
下面開始haul重點(diǎn)了:文章來源:http://www.zghlxwxcb.cn/news/detail-841814.html
- 第一個區(qū)別是,對于 reset --hard 命令來說,checkout命令更安全。因?yàn)?Chekout命令在切換分支前會先檢查一下當(dāng)前工作狀態(tài),如果不是'clean'的話,Git不會允許你這樣做;而 'reset --hard'命令則是直接覆蓋掉所有數(shù)據(jù)。
- 另一區(qū)別是如何更新 HEAD 的指向,reset 命令會移動 HEAD 所在的分支指向,而checkout命令只會移動HEAD自身來指向另外一個分支。
看到文字你肯定懵,我們舉例說明:文章來源地址http://www.zghlxwxcb.cn/news/detail-841814.html
到了這里,關(guān)于Git版本管理工具的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!