git
設定 git
-
查看 git 版本
$ git --version
-
設定
$ git config --global user.name [你的名字] $ git config --global user.email [你的email]
-
查詢設定
$ git config --list
初始化
-
建立資料夾
$ mkdir demo
-
移動至資料夾
$ cd demo
-
建立本地倉庫
$ git init
-
可以選擇建立本地倉庫或是複製遠端倉庫到本地
$ git clone [遠端數據庫網址]
忽略檔案
- 新增 .gitignore 檔案
$ touch .gitignore
-
編輯 .gitignore 檔案
$ vi .gitignore
-
將要忽略的檔案寫入 .gitignore
node_modules/
遠端倉庫操作
-
連結遠端倉庫
$ git remote add origin [遠端數據庫網址]
-
複製遠端倉庫到本地
$ git clone [遠端數據庫網址]
-
查詢遠端數據庫
$ git remote
-
將本地分支推送到遠端分支
$ git push [遠端數據庫名稱] [遠端分支名稱]
-
將遠端分支拉下來與本地分支進行合併
$ git pull
查詢 git 狀態
-
查詢狀態
$ git status
-
或使用簡寫
$ gst
新增檔案至索引
-
新增全部檔案
$ git add .
-
新增部分檔案
$ git add [檔案名稱]
提交變更 / 建立版本至本地倉庫
-
提交
$ git commit -m "[版本紀錄的說明文字]"
查詢歷史紀錄
-
查詢歷史紀錄
$ git log
-
只要透過一個減號 ( - ) 與一個數字,就可以限定輸出最近幾筆紀錄:
$ git log -10
-
精簡的 log
$ git log --oneline --graph
-
我想要找某個人或某些人的 Commit…
$ git log --oneline --author="Tom\|Elaine"
-
我想要找 Commit 訊息存在特定字串的紀錄
$ git log --oneline --grep="hello"
-
我要怎麼找到哪些 Commit 的檔案內容有提到 「Ruby」 這個字?
$ git log -S "Ruby"
-
找到特定時間的 Commit
-
「今天早上 9 點到 12 點之間所有的 Commit」
$ git log --oneline --since="9am" --until="12am"
-
「從 2017 年 1 月之後,每天早上 9 點到 12 點的 Commit」
$ git log --oneline --since="9am" --until="12am" --after="2017-01"
-
-
查看這行程式碼是誰寫的
-
整個檔案
$ git blame index.html
-
只會顯示第 5 ~ 10 行的資訊
$ git blame -L 5,10 index.html
-
還原指令
- reset 模式
- mixed 模式
- 這個模式會把暫存區的檔案丟掉,但不會動到工作目錄的檔案,也就是說 Commit 拆出來的檔案會留在工作目錄,但不會留在暫存區
- soft 模式
- 這個模式下的 reset,工作目錄跟暫存區的檔案都不會被丟掉,所以看起來就只有 HEAD 的移動而已,也因此,Commit 拆出來的檔案會直接放在暫存區
- hard 模式
- 在這個模式下,不管是工作目錄以及暫存區的檔案都會丟掉
- mixed 模式
-
取消全部檔案索引,將更改的文件丟到工作目錄
$ git reset HEAD
-
取消單一檔案索引,將更改的文件丟到工作目錄
$ git reset HEAD [檔案名稱]
-
還原工作目錄與索引,會和最後一次 Commit 保持一樣 (更改文件的文件會不見)
$ git reset --hard
-
刪除最近一次 commit
$ git reset --hard HEAD^
-
刪除最近一次 commit,但保留異動內容
$ git reset --soft HEAD^
-
【狀況題】不小心使用 hard 模式 Reset 了某個 Commit,救得回來嗎?
$ git reset --hard ORIG_HEAD
-
還原其中一個被改壞的檔案(回復到上一次 Commit 的狀態)
$ git checkout [檔案名稱]
-
如果想一口氣把所有被異動的檔案救回來
$ git checkout .
-
還原其中一個被改壞的檔案,例如把 master 分支中最新版的 index.html 給還原
$ git checkout master index.html
特殊符號
-
HEAD 是啥?
- HEAD 本身是一個指標,它通常會指向某一個本地端分支或是其它 commit
- 你在哪,HEAD 就在哪
- 通常會指向目前所在的分支
-
^
和~
的差別?-
如果有 merge 的時候,
^
有分主要的與次要的…等等A^
=> 上一個(主要的) =>B
A^2
=> 上一個(次要的,合併進主要的) =>C
A^^
=> 上一個(主要的)的上一個(主要的) =>D
A^^2
=> 上一個(主要的)的上一個(次要的) =>E
A^^3
=> 上一個(主要的)的上一個(次次要的) =>F
-
~
都是主要的A~1
=>B
A~2
=>D
A~3
=>G
-
-
HEAD^
=HEAD^1
=HEAD~1
=HEAD~
Git HEAD^与 HEAD~ git 理解 HEAD^与 HEAD~
分支
-
查看分支
$ git branch
-
切換分支
$ git checkout [分支名稱]
-
新增分支並切換到該分支
$ git checkout -b [分支名稱]
-
重新命名分支
$ git branch -m [舊分支名稱] [新分支名稱]
-
刪除分支
$ git branch -d [分支名稱]
只有「現在目前所在的分支」不能刪而已(因為刪了的話要去哪裡?),不過只要先切到別的分支就可以刪掉它了
-
直接切換到某個 Commit 點
$ git checkout [版本號]
比較版本差異
$ git diff commit1 commit2
$ git diff // 工作目錄 vs 索引
$ git diff HEAD // 工作目錄 vs HEAD
$ git diff --cached HEAD // 索引 vs HEAD
$ git diff --cached // 索引 vs HEAD
$ git diff HEAD^ HEAD // HEAD^ vs HEAD (最新版的前一版vs最新版)
暫存
-
會將所有已列入追蹤(tracked)的檔案建立暫存版
$ git stash
-
會包括所有已追蹤或未追蹤的檔案,全部都建立成暫存版
$ git stash -u
-
列出所有暫存
$ git stash list
-
還原暫存
$ git stash pop
-
清除最新暫存
$ git stash drop
-
清除所有暫存
$ git stash clear
合併分支
-
假如我現在在 master,想合併 feature 分支
$ git merge feature
-
合併後刪除不必要的分支
$ git branch -d feature
-
當你發生衝突的時候,切莫慌張,先執行 git diff 自動比對出到底哪些檔案的哪幾行發生衝突了
$ git diff
-
如果是兩個比較大的分支發生衝突的話,很有可能會有一大堆檔案有衝突的狀況。這時你可能會想一個一個檔案的來查看衝突的狀況
$ git status $ git ls-files -u $ git diff a.text
rebase
-
重新定義分支的參考基準
$ git rebase [分支名稱]
-
怎麼取消 rebase? ORIG_HEAD 會記錄「危險操作」之前 HEAD 的位置 例如分支合併或是 Reset 之類的都算是所謂的「危險操作」
$ git reset ORIG_HEAD --hard
revert
在版本控管過程中,還有個常見的狀況,那就是當執行了多個版本之後,才發現前面有幾個版本改錯了,例如你不小心把測試中的程式碼也給 commit 進去,導致目前這個版本發生了問題
在開始說明前,我們一樣先用以下指令建立一個練習用的工作目錄與本地儲存庫。我們先建立一個 a.txt 的檔案,內容為 1。然後修正一版,內容改為 2。接著在新增一個 b.txt 檔案,內容為 1。所以一共有三個版本:
假設我們這個時候發現,在我們上一個版本 ( HEAD~ 或 HEAD~ 或 6351ff0 ) 被改錯了,你希望可以將該版本還原就好,而不是把版本重置到第一版在重改一次,那麼你可以試試 git revert 指令,他可以把某個版本的變更,透過「相反」的步驟把變更給還原
- 使用 git revert 命令
假設我們從 git log 顯示的歷史記錄中,發現有個版本有問題,那麼我們可以先看看這個版本的變更紀錄。如下圖示,你可以先用 git log 查出版本編號,然後再用 git show [commit_id] 查出該版本的相關資訊
- 使用 git revert 命令的注意事項 請注意:執行 git revert 命令之前,請先確保工作目錄是乾淨的!如果有改到一半的檔案,建議可透過 git stash 建立暫存版本
從上圖你可以看到 6351ff0 這個版本的 a.txt 檔案,是將第 1 行的內容從 1 修改成 2 的,那也代表著「相反」的步驟則是把 2 改成 1 才對。這時,如果我想把這個版本的變更給「還原」,則可以輸入 git revert 6351ff0 這個指令,執行成功後會額外再建立一個新版本。如下圖示:
執行過程中會讓你編輯最後要 commit 的訊息,預設會加上 Revert 字樣,還有會在第三行的地方加上 This reverts commit xxxx 告訴你說這個版本主要目的是從 xxxx 版本還原的
cherry-pick
cherry-pick 的英文是「撿櫻桃」的意思,代表你可以從其他籃子(分支)「挑」一些好的櫻桃到自己的籃子(分支)裡!
在版本控管過程中,還有個常見的狀況,那就是當你在一個分支中開發了一段時間,但後來決定整個分支都不要了,不過當中卻有幾個版本還想留下,這時要刪除分支也不是,把這個分支合併回來也不是,那該怎麼辦呢?本篇文章將說明你該如何利用 git cherry-pick 指令「手動挑出」你想套用的變更
- 使用 git cherry-pick 命令的注意事項
首先,你的「工作目錄」必須是乾淨,工作目錄下的「索引」不能有任何準備要 commit 的檔案 (staged files) 在裡面,否則將會無法執行
今天我想套用 branch1 的 dc07017 Add b.txt! 這個版本到目前的 master 版本上,可以執行 git cherry-pick dc07017 命令,若成功執行,則會在目前的 master 分支建立一個新版本
不過,與 git revert 最大的不同之處,就在於執行完 git cherry-pick 命令後,其建立的版本訊息,將會與你指定挑選的那些版本一模一樣,其中包括 Author 與 Date 欄位,都會一模一樣,並不會用你在選項設定中指定的 user.name 與 user.email 參數。這點你必須特別注意!
不小心刪除分支
如果真的不小心刪除分支,可以利用以下指令先找到對應的版本號 (commit 號碼)
$ git log -g
之後利用 git checkout -b [分支名稱][commit號碼] 救回該分支
$ git checkout -b test
git 忽略的檔案被提交
必須先使用 git rm --cached
指令把這些想被忽略但是已經被追蹤的檔案移除 git
discard 丟棄某個檔案
$ git checkout -- package-lock.json