Git一二三,版控真簡單
本文最後更新於:2024年11月19日 11:00
Git是一個多工團隊協作版控的好用工具,雖然一開始的概念有點小複雜,我也是花了好一陣子才漸漸搞懂它。因此,對於初學者而言,在了解Git指令之前,先要有 local
(本地)、 remote
(遠端) repository
(儲存庫)及各自的 branch
(分支)概念,還有就是多跟同事在實務上運用練習,才會更快上手。
Git指令全集
概念
初始化git工作目錄
狀態:未初始化
1
git init
初始化後,目錄下新增.git目錄。
工作區(Working Directory)
狀態:未追蹤(Untracked files,對於新加入檔案或提交後新建立檔案)、已更改(Changes not staged for commit,對於提交後再被修改之檔案)
直接編輯的地方,在桌機上可直接操作檔案。
1
2# 工作區 -> 暫存區
$ git add . # 將檔案從工作目錄加入至暫存區暫存區(Staging Area)
狀態:等待提交(Changes to be committed)
數據暫時存放的區域,介於工作區與儲存庫之間。
1
2
3
4
5# 暫存區 -> 儲存庫
$ git commit # 新開編輯器編輯提交訊息
$ git commit -m "提交訊息" # 將暫存區內容移至儲存區
$ git commit -am "提交訊息" # 從工作區移至儲存庫,對已在儲存庫的檔案有效
$ git commit --amend # 編輯最新已提交訊息儲存庫/數據庫(Repository,簡稱repo)
狀態:已提交(Committed)
存放已經提交的數據。
本地端儲存庫(Local)
為了方便自己使用的儲存庫,通常是個人開發的電腦或機台。
1
2# 本地端複製
$ git clone <本地目錄名稱> <新本地目錄名稱|路徑> # 複製本地儲存庫至指定目錄遠端儲存庫(Remote)
為了讓多人共享而建立的儲存庫,通常是一個共用的伺服器。
1
2
3
4
5
6
7
8
9
10
11
12# 遠端 -> 本地端儲存庫
$ git fetch <遠端名稱> <遠端分支名稱> # 下載遠端指定分支
$ git fetch --all # 下載遠端所有分支
$ git clone <遠端名稱> # 下載遠端預設分支
$ git clone <遠端名稱> -b <本地分支名稱> # 下載遠端預設分支至指定本地分支
$ git clone <遠端名稱> <目錄名稱|路徑> # 下載遠端預設分支至指定目錄
# 遠端儲存庫 -> 工作區
$ git pull <遠端名稱> <遠端分支名稱>:<本地分支名稱> # git fetch + git merge
# 本地端 -> 遠端儲存庫
$ git push [遠端名稱] [遠端分支名稱] # 推送到遠端儲存庫
常用指令
1 |
|
將存放庫初始化
首先必須要先將Git本地的存放庫初始化啦!
到了想要透過Git監控的目錄 git init
,此時在目錄下會多出.git的隱藏目錄,這就相當於在VS code下在原始檔控制中的「將存放庫初始化」的功能。
1 |
|
查看當前git狀態
先透過 git status
來查看當前git狀態。
1 |
|
從輸出的內容,可以看到目前本地的分支名稱為master、沒有任何commit(提交),以及哪些檔案還沒被add(加入)追蹤(untracked)。
目錄下可加入.gitignore檔案,裡面的內容可以加入不想同步追蹤的檔案名稱,以將這些檔案排除在git的檢查之外。
目錄下加入.gitkeep則是強制git在檢查時,將空目錄也涵蓋進來。
一、add(加入)untracked(未追蹤)檔案至暫存的變更
當在目錄當中新增的檔案,只要是非空目錄、未被.gitignore排除檢查的檔案,或者並非是另一個含有.git的目錄,都會被列為檢查對象。
利用VS code的原始檔控制,會自動偵測已變更的檔案(新增的檔案右方會顯示A(Add)、新增後變更的檔案會顯示M(Modified)),在「變更」欄的右方「+」號則可以將新增或變更的檔案加入到暫存的變更;在「暫存的變更」右方「-」號則是可以選擇取消變更的檔案,等修改好再加進去。
如果利用指令列,則須透過 git status
來看各個檔案的情況。
假設我們先新增一個test.md檔,這時候git status會列在untracked,於是我們 git add
:
1 |
|
這時候再git status,會看到檔案已被加入:
1 |
|
如果再修改test.md檔案中的文字,再次git status則會看到:
1 |
|
代表有一個版本已經加入暫存的變更等待提交,而另一個則是因為我們後來的修改而產生的版本,尚未加入提交的行列。
若是目錄中含有其他git監測的目錄,則無法加入追蹤。
1 |
|
像是Hexo部分目錄本身即含有git版控功能,因此部分目錄無法同步加入追蹤。
二、新增訊息並commit(提交)
當我們新增檔案或修改某些檔案裡的文字時,可以利用 git commit
分批提交更新訊息,把每一次的更新訊息記錄下來:
1 |
|
提交之後會顯示提交的分支名稱、提交ID、提交訊息、幾個檔案新增或者被改變。
每次修改檔案之後,都要記得將檔案再度git add到要提交的行列當中。
在提交之後,會發現本地端也新增了master分支,代表我們提交的內容會在我們本地的master分支裡。每修改某個檔案都可以在訊息欄做備註。但我們要推送的是遠端分支,而不是本地分支,要確定要提交上去的是哪一個分支。
三、push(推送)至remote repo(遠端儲存庫)
緊接著,你在工作目錄中陸陸續續新增的檔案,要放到遠端儲存庫供他人使用,就必須先將遠端儲存庫加入路徑之中。Github儲存庫URL在頁面右上角的「code」當中,使用HTTPS或SSH都可以,將想要放置檔案的Github儲存庫URL透過 git remote add
加入即可。
1 |
|
以名稱為github加入遠端儲存庫為例:
1 |
|
如果想推送至第2個遠端儲存庫的話,也可以再加入:
1 |
|
此時透過指令 git remote -v
就可以看到有兩個remote repo了。
如果要查看本地分支與遠端分支的對應可以透過以下指令:
1 |
|
從上面 git branch -a
當中,可以看到因為目前本地端是在master分支底下,而遠端則在github底下有自動抓到2個分支。
如果要將目前的本地分支的fetch及push與遠端分支對應,使得每次 git fetch
/ git pull
或 git push
不用指定remote repo與branch,可以使用以下指令:
1 |
|
利用 git checkout
則可以切換分支,若要新建分支並切換過去,要加 -b
。
1 |
|
例如我們如果想將本地端main分支的檔案同步到遠端的main分支上:
1 |
|
其他常用指令
更動repo或branch相關
1
2
3
4
5
6
7
8
9
10git branch <分支名稱> # 建立本地分支
git branch (-d | --delete) <分支名稱> # 刪除本地分支
git branch (-D | --delete --force) <分支名稱> # 強制刪除本地分支
git branch (-m | --move) [<舊分支>] <新分支> # 移動/更名分支
git branch (-M | --move --force) [<舊分支>] <新分支> # 強制移動/更名分支
git push [遠端名稱] [遠端分支名稱] # 推送至遠端分支(若upstream有指定,可省略名稱)
git push <遠端名稱> --delete <遠端分支名稱> # 刪除遠端分支
git push <遠端名稱> :<遠端分支名稱> # 刪除遠端分支
git clone <遠端專案URL> -b <分支名稱> # 複製遠端分支
git pull <遠端名稱> <遠端分支名稱>:<本地分支名稱> # git fetch + git merge查看log相關
1
2
3git log # 查看已提交commit
git log --oneline # 僅顯示commit標題
git log --graph # 以圖形顯示branch之間的commit回復到某個commit
1
2
3
4
5
6
7git reset --hard [HEAD] # 回復到最新提交版本(預設為HEAD)
git reset --hard HEAD~ # 回復到前一個提交版本
git reset --hard HEAD~n # 回復到前n個提交版本
git reset --hard <commit_id> # 回復到指定commit
git reflog # 查看所有變動訊息
git reset --soft [HEAD | <commit_id>] # 回復到提交版本但會保留工作區及暫存區內容
git revert [HEAD | <commit_id>] # 撤銷到提交版本但會留下commit暫存目前進度切換成新任務
1
2
3
4
5
6git stash # 暫存目前進度
git stash -u # 暫存目前進度(包含untracked的檔案)
git stash list # 查看stash列表
git stash apply stash@{n} # 把某個stash套用回來目前分支
git stash drop stash@{n} # 把某個stash刪除
git stash pop stash@{n} # 把某個stash套用回來目前分支並刪除stash(apply + drop)
關於git組態設定
git的組態設定分為三個階層,有
System
、Global
、Local
,相關的設定檔路徑如下:System:
/etc/gitconfig
Global:
$home/.gitconfig
Local:
$repo/.git/config
常用設定如下:
1
2
3
4
5
6
7git config --list [--system | --global | --local] # 列出所有組態設定
git config --global user.name "xxx" # 使用者名稱
git config --global user.email "xxx@xx.com" # 使用者電子郵件
git config --global core.autocrlf true # 自動轉換CRLF
git config remote.<repo name>.url "<repo url>" # 更改遠端儲存庫URL
git config core.editor "vim" # 設定編輯器為Vim
git config push.default [upstream|current|simple] # 預設推送到[upstream|同名分支|同名分支但會拒絕推送到不同名分支]For Gerrit:
1
git config remote.<repo name>.push "HEAD:refs/for/<branch name>%r=<reviewer email>,cc=<cc email>,topic=<topic>" # 設定要推到哪個branch,以及指定reviewer、cc,或topic
git忽略追蹤
- 狀況一:新增過濾條件後新增的檔案
- 符合規則 Git 就不會去追蹤。
- 狀況二:新增過濾條件前新增的檔案
- 沒有額外處理還是會被追蹤。
於專案根目錄新增
.gitignore
檔案。於檔案內新增需要忽略的檔案、目錄等,例如:
1
2*.conf # 檔案
__pycache__/ # 目錄若以 git status 查看,會發現記錄只有新增一個檔案而已,而這就是因為先有 Git 記錄才新增 .gitignore 檔案,因此進行以下步驟清除快取並重新加入追蹤,才會套用新的 .gitignore 設定:
1
2
3
4
5
6# 清除本機 Git 的快取,就是將所有檔案移除 Git 的追蹤,但沒有刪除檔案
$ git rm -r --cached .
# 重新加入 Git 追蹤,這時就會重新套入 .gitignore 設定
$ git add .
# 重新 commit ,並會忽略設定在 .gitignore 的檔案
$ git commit -m 'update .gitignore'