git 必需要熟練掌握的命令

由於結合了開發中可能遇到的場景,篇幅較長,不過我以爲頗有助於你理解 git 的運做機制,而不是死記硬背命令。linux

HEAD指針 始終指向的是當前分支的最新版本號,HEAD^, HEAD^^, ^ 的個數 n 或 HEAD~n,n 表明前 n 個版本號。git

在項目中直接使用 linux rm 只會刪除工做區的文件,git rm 同在刪除工做區文件的同時刪除 stage 中的,或使用 git rm --cached 只刪除 stage 中的。github

一些基本的操做fetch

#全局配置
git config --global user.name "your username"
git config --global user.email youremail@email.com
git config --global color.ui true

#
mkdir git_proj & cd git_proj
git init
echo "# readme.md" >> README.md
git add README.md
git commit -m "readme commit"
# 添加遠程倉庫 並給它取個別名 origin
git remote add origin git@github.com:username/repositoryName.git
# 將本地倉庫推送至 origin 的 master 分支並與此分支關聯(-u 的做用,後期沒必要在使用)
git push -u origin master

# 從遠程倉庫 origin 的 master 分支獲取最新源碼並下載到 tmp 分支
git fetch origin master:tmp
# 比對 tmp 分支於 master 分支作了哪些改動
git diff master tmp
# 合併 tmp 分支到 master 分支
git merge tmp

# clone copy 一個完整的遠端倉庫到本地
git clone git@github.com:username/repositoryName.git

# pull 獲取 origin 的 master 分支並直接和當前分支合併
# 因此可能會發生衝突
git pull origin master

checkout

checkout 命令有兩個主要做用:切換分支 和 回滾文件到當前的 stage 版本 或 repository 版本
一、切換分支ui

# 切換到 new_branch 分支
git checkout new_branch
# 建立並切換到 new_branch 分支
git checkout -b new_branch

二、回滾工做區的文件到最新 stage 版本 或 repository 版本,即從 stage 或 repository 中檢出最新版本spa

# -- 是文件標示符 表名後面的參數爲文件 避免產生切換 branch 的歧義
git checkout -- <filename>

回滾時會先檢查 stage 中是否有對應的文件,若是沒有才會使用 repository 中最新的版本。而當對某文件進行了屢次修改和 add 操做後,使用 checkout 咱們只能將文件回滾到最新一次的 add 的版本。
但在某些場景下咱們可能想回滾到 repository 中的最新版本,怎麼作呢?配合 reset 命令的能夠很容易作到。
先給出命令:設計

git reset HEAD <filename> & git checkout -- <filename>

這樣就能夠將工做區的 filename 回滾到 repository 中的最新版本了。具體原理咱們將在實例中詳細的講解。指針

reset

git 的 reset 命令比較繞,須要耐心的理解。簡單來講,reset 有三種重置級別,咱們須要準確理解每一個級別的做用。日誌

soft:回退版本號。做用於 repositorycode

mixed:回退版本號,重置 stage。做用於 repository 和 stage

hard :回退版本號,重置 stage,重置工做區源碼。做用於 repository,stage 和 workspace

咱們簡單展現下 repository 的版本號,咱們以此爲 demo 分別嘗試三個級別的 reset

git log

version D (HEAD) <-- HEAD指針
version C (HEAD^)
version B (HEAD^^)
version A (HEAD~3)

命令格式:

git reset [--soft|--mixed|--hard] version_no <filename>

--soft:只是單純的移動 repository 的 HEAD指針 到制定版本號。stage 和工做區沒有任何變化。

# 將 HEAD 指針回滾至上一版本 使用 git log 你會發現提交日誌退回到了上一版本號
git reset --soft HEAD^
#版本號現狀
version C <-- HEAD指針
version B
version A

--mixed:默認選項,移動 repository 的 HEAD指針 到指定版本號,同時用此版本重置 stage 區,因此可能會讓工做區的某些文件處於 unstage 狀態(當工做區的文件與 repository 中的版本不一致時)。注意,這裏是能夠指定文件的。soft 自己和文件無關,hard 則是不能單獨指定文件,只能所有重置。

# HEAD指針 仍是指向 HEAD 
git reset HEAD^2 <filename>
#版本號現狀
version B <-- HEAD指針
version A

HEAD指針 指向 version B,而且 stage 已經被 version B 的文件重置,工做區則不受影響。

這裏有個很實用的小技巧:

git reset version_no <filename> & git checkout -- <filename>

這兩個命令組合在一塊兒可讓工做區的指定文件回滾到 repository 中對應的 version_no 版本。
若是 version_no 是 HEAD 的話那就能夠回滾文件到最新一次的提交。


--hard:謹慎使用!!!移動 repository 的 HEAD指針 到指定版本號,同時用此版本重置 stage 區 和 工做區源碼。這裏要特別注意,工做區的源碼也會被覆蓋重置掉,你的修改會所有丟失。簡單來講就是將代碼完全恢復到指定版本。hard 是沒辦法指定文件的,要麼回滾,要麼全回滾。

# HEAD指針 仍是指向 HEAD 
git reset --hard HEAD^3
#版本號現狀
version A <-- HEAD指針

此時,HEAD指針 指向 version A,而且 stage 和 工做區的文件已經被 version A 的文件重置。整個項目的狀態徹底回到提交 version A 時按下回車鍵的那一刻。

rm

git rm 不一樣於直接使用 rm,git rm 會刪除工做區 和 stage 區的內容。注意:這裏你沒辦法再使用 git checkout -- <filename> 來回滾操做了,由於工做區也沒有 filename 文件了,沒辦法與 repository 作關聯,只能使用 git reset HEAD <filename> 來重置 stage 中的此文件,而後 git checkout -- <filename>

git rm [--cached] [-r] [-f] <filename>

這裏就提示一點,只想把 stage 中的文件刪除掉讓文件脫離 git 的管理,可使用

git rm --cached <filename>

此時工做區的 filename 並不會被刪除,但狀態會被改成 untracked,同時 stage 會記錄下 filename 的狀態爲刪除,提交的話版本庫將新增一個 filename 被刪除掉的版本。
刪除 stage 中的文件和使用 reset命令 重置 stage 中的文件是有區別的,刪除會讓文件狀態更改成 untracked,而重置會讓文件狀態更改成 unstage(若是工做區和 stage 文件內容不一致)。

小實例場景:

一、回滾工做區某文件到指定的 repository 版本

工做中,咱們可能會針對某文件作屢次修改和 add 到 stage 的操做,然後發現思路徹底錯了,須要從新設計開發。

好比文件 foo 的 A版 我提交了一次後,又進行了 B版 和 C版 的兩次修改並 add 到了 stage 區。第三次修改後 D版 我發現一開始思路就錯了,須要從新設計。那此時直接使用 git checkout -- foo 是拿不到最初的 A版 的,由於 stage 區還存放着 foo 的 C版。此時咱們即可以使用 git reset HEAD foo 命令,repository 最新版本號中存放着 foo 的 A版,命令會在不移動 HEAD 的前提下,使用 foo A版 去重置 stage 區。命令執行後 stage 區的 foo 文件已是 A版 了。咱們再使用 git checkout -- foo 即可以將工做區的 foo D版 回滾至 A 版。即:

git reset HEAD foo & git checkout -- foo

HEAD 表明當前版本,因此 HEAD指針 不會移動。同時 stage 區會被 repository 的當前版本的 filename 重置,也就說 stage 區 存放的 filename 與 repository 中相同了。此時咱們再使用 git checkout -- <filename> 即可以回滾工做區的 filename 到 repository 的當前版本。其實就是利用 reset --mixed 會重置 stage 區,而後 checkout 會將 stage 區的文件檢出到工做目錄。固然,reset 很靈活,能夠回滾任意指定的版本。

其實若是隻是回滾至當前版本的話,還有個命令能實現相同的功能

git rm --cached <filename> & git checkout -- <filename>

git rm --cached <filename> 會將 stage 中的此文件刪除,文件狀態會變爲 untracked,而後 checkout 時發現 stage 中木有此文件,故會去 repository 的當前版本中檢出此文件。

diff

git diff -- <filename> 工做區 比較 暫存區
git diff --cached -- <filename> 暫存區 比較 本地庫當前版本
git diff HEAD~N -- <filename> 工做區 比較 本地庫第N個版本
git diff HEAD HEAD^ -- <filename> HEAD 比較 HEAD^
git diff master tmp -- <filename> master 比較 tmp
git diff SHA1 SHA2 -- <filename> 比較兩個歷史版本之間的差別

還沒結束...未完成...待更新....

相關文章
相關標籤/搜索