Skip to main content

Git 常用招

Git 可以說是比寫 code 還要重要的東西,現在的專案基本上都要共同協作,所以如何避免衝突,不在開發的時候發生災難,可以說是非常的重要,寫 code 寫不好可以問人,但 Git 不行的話可能連工作都沒有辦法一起 co-work 。另外如果對 vim 還沒有很熟的話建議去多了解一下 vim 的編輯、儲存、查尋方式,對你在使用 git 上會更加的得心應手。 # Git 常用 commend line

git 起手式

在專案位置下初使化 git ,表示可開始用 git 來管理你的專案,此時專案中會出現一個隱藏資料夾 .git ,然而你在開發的過程中也一定會有你不想要推到 remote 的東西,這個時候你可以建立一個 .gitignore 的檔案,在裡面編寫你不想要上傳的文件 or 資料夾

git init
# .gitignore 檔案
node_modules # 資料夾不推上 git
/dist
.env # 檔案不推上 git

在來你需要對專案說,你是誰,所以把你的 email 和名稱和 git 說,因此在 git.config 裡面建立資訊

 # 查看你目前的 config 清單
git config --list

# 建立名稱
git config --global user.name [YOUR_NAME]

# 建立 email
git config --global user.email [YOUT_EMAIL]

clone 專案

開發其它的專案,透過 clone 的方式,把 .git 的檔案一起抓下來

git clone [YOUR_PROJECT]

remote 相關指令

# 查詢remote相關指令
git remote -h

# 將遠端數據庫的名稱從 <old> 改為 <new>
git remote rename `<old>` `<new>`

# 在 <newurl> 內指定遠端數據庫的新地址
git remote set-url `<name>` `<newurl>`

# 加入 remote 資料
git remote add origin [YOUR_PROJECT]

# 移除 remote 資料
git remote remove origin

切換遠端分支

首先你應該不會知道專案中所有的 br 叫什麼名稱,所以可透過

# 查看所有 local 遠端 br
git branch -a

在確認完之後,在回到專案的位置上,進行切換分支

git checkout -b [BRANCH_NAME] [origin/BRANCH_NAME]

加入暫存區

把資料加入暫存區

 # add all file stage
git add .

# after everyone check, add file to stage
git add -p

取消加入暫存區

git checkout

檔案名稱大小寫修正

core.ignorecase 在做什麼?

  • 預設情況 (true):在 Windows 或 macOS 這類檔案系統「不區分大小寫」的環境中,Git 預設會忽略大小寫差異。例如把 index.html 改名成 Index.html,Git 可能顯示「沒事發生」。
  • 設為 false:強迫 Git 必須區分大小寫。對 Git 而言,index.htmlIndex.html 就像 apple.htmlbanana.html 一樣,是兩個不同的檔案。

設成 false 後會發生什麼?

  1. 若原本有 index.html,再手動新增一個 Index.html
  2. 執行 git status 時,Git 會顯示一個全新的未追蹤檔案 (Untracked file)
  3. 兩者都可以 git add,暫存區(Index)裡會同時存在這兩個檔案的紀錄。
⚠️ 潛在問題(Mac / Windows 使用者)

在非 Linux 系統上不建議手動把 core.ignorecase 設為 false

  • 「看得見,摸不著」:Git 紀錄裡可以有兩個檔名(只差大小寫),但 macOS/Windows 無法在同一個資料夾裡真的放兩個這樣的檔案git checkout 時可能其中一個被覆蓋,或 Git 報錯無法切換分支。
  • 遠端衝突:若團隊有人用 Linux(區分大小寫)並推了 index.htmlIndex.html,你在 Mac/Windows 上 pull 時可能造成混亂甚至檔案內容遺失。

正確做法:只改大小寫時用 git mv

若只是想將 index.html 改成 Index.html(且不打算同時存在兩個檔),不必core.ignorecase,用 git mv 最安全:

# 讓 Git 幫你完成改名,會自動處理大小寫切換
git mv index.html Index.html

若已經弄亂(Git 顯示兩個檔但資料夾只有一個),可先重設索引再重新加入:

git rm -r --cached .
git add .

除非在開發僅在 Linux 上跑的軟體,否則建議維持預設:

git config --local core.ignorecase true

若只是「改名後 Git 沒反應」,用 git mv 才是正解,不需動 core.ignorecase

加入本地儲存區

把資料加入本地儲存區,方法其實有很多種,但主要就是要把你的資料寫到 git 裡面,如果你所要寫的東很多的話,建議你可以用 vim 的方式去作編輯歐

git commit # 會直接進到 vim IDE 中
git commit -m 'msg content'

退回本地儲存區

# get commit id
git log

# 本地數據庫不見
git reset --hard `<id>^`

# 本地數據庫還在
git reset --soft `<id>^`

commit 訊息邏輯以大寫開頭以<動詞> + <受詞> + <內容> 的文法撰寫內容不宜過長內容需要據有代表性

如要編輯 head 的 commit 的話

git commit --amend

stash

會使用它最常有的情境是,你開發到一半,但是 BOSS 請你趕快的去處理另一件是,這個時候你也還沒有到可下 commit 的時候,這個時候,可用 stash 把你開發的 code 先到一個地方,之後只要回來,在把東西 stash 回來便可繼續開發。

在 stash 之前建議先把所有的 code 放到暫區,因有時候我們是新建檔,直接 stash 的話新檔就會被遺留在,原本的 br 上面 git add . 為了確保我們所寫的東西不要被分別放在不同的 stash list 裡面

暫時存現狀

git stash save 'msg ...'

顯示暫存清單

git stash list

回復暫清單,通當你會去看一下你的清單有什麼,然後確定是第幾個之後用 stash@{0} 的方式來還原你想的的暫存。

這裡的 0 是表示,你最一次 stash 起來的東西,1 的話就是倒數第二次的東西,依此類推

 # 拿回最後一次 stash 的 code
git stash pop shash@{0}

# delete stash data
git stash pop `<shash ID>`

git stash apply `<shash ID>`

刪除暫檔

git stash drop `<shash ID>`
git stash clear # clear all

合併分之

通常在有規模的專案下面開發,比較不會用到 merge ,因為主要都是透過 lib 去發 merge request ,而不是自己在本地,就把 code merged 到其它的分支。

merge

git merge [BRANCH_NAME]

但是我們在拉分支的時候,其實就是常常在用 merge 的指令,只是被合併在一起了。

rebase

git rebase [BRANCH_NAME]
info

這兩個都是把 br 作合並的效果,但是 rebase 是直接把原本的分支合回到另一個 br 的分支上,變成一個,也就是說,有些 commit 你可能會沒有辦法在 tree 上面直接的看到,因為被合到另一個 tree 上面了

rebase 的 squash(壓縮 commit)

interactive rebase-i)可以把多個 commit 合併成一個,常用在整理分支歷史、送 MR 前把「修正 typo」「再改一下」這類小 commit 壓成一個清楚的 commit。

# 從目前分支「往前數 N 個 commit」做互動式 rebase
git rebase -i HEAD~N

# 或指定要 rebase 的基底 commit(不包含該 commit)
git rebase -i [COMMIT_HASH]

執行後會開啟編輯器,列出這 N 個 commit,例如:

pick abc1234 feat: 新增登入 API
pick def5678 fix: 修正 typo
pick ghi9012 docs: 補充註解

把要「壓進前一個」的 commit 前面的 pick 改成 squash(或簡寫 s),保留最上面一個為 pick,其餘改為 squash:

pick abc1234 feat: 新增登入 API
squash def5678 fix: 修正 typo
squash ghi9012 docs: 補充註解

存檔離開後,Git 會把這三個 commit 合成一個,並再開一次編輯器讓你編輯合併後的 commit message

常用指令
  • pick:保留該 commit
  • squash / s:合併到前一個 commit,並保留兩邊的 message 讓你編輯
  • fixup / f:合併到前一個 commit,但丟棄這個 commit 的 message(適合「只是小修正」的 commit)

若已經 push 過該分支,squash / rebase 後會改寫歷史,需要強推(請確認沒有其他人依賴該分支):

--force-with-lease(有條件強推)

git push --force-with-lease

刪除 branch

-d(安全刪除)

  • 只在分支已合併到當前分支時才會刪除
  • 若未合併會報錯,避免誤刪未合併的工作
git branch -d [BRANCH_NAME]

-D(強制刪除)

  • 等同 git branch -d -f不論是否合併都會強制刪除
  • 適用於確定要丟棄該分支的變更時
  • ⚠️ 未合併的變更會遺失,使用時請謹慎
git branch -D [BRANCH_NAME]

建議

情境建議指令
確定分支已合併git branch -d
確定要丟棄未合併的工作git branch -D

重新 rename

git branch -m [oldname] [newname]
git branch -m [new_name]

遠端數據庫

fetch

主要只執行拉 code 的動作,但它不會把 code 和你現在的 br 進行合併,所以執行完後你是會在 HEAD 上面的

# 把你在遠端的 br 拉下來
git fetch

pull

那 pull 的這個動作,就是我們把 fetch + merge 的動作一起作完,把 code 拉下來,然後 merge 到你現在的 branch 中

# git fetch + git merge
git pull

# 當然你也可選擇 rebase
git pull --rebase

NOTE 在開發過程中如果你遇到需要設定 config 你可能會看到這個畫面

# bla... bla...

push

把你所 commit 好的的檔案往上傳到 remote 端,但是需先確認是否已設定好 origin 的 remote 位置

git push origin [BRANCH_NAME]

改寫歷史(例如 rebase、squash)後需要強推時,兩者差別如下:

選項行為風險
--force無條件覆蓋遠端,不檢查是否有他人新提交高,可能蓋掉別人的 code
--force-with-lease先檢查遠端是否與本地紀錄一致,一致才覆蓋、不一致則拒絕低,可避免意外蓋掉他人提交

建議優先使用 --force-with-lease。詳見 `--force-with-lease`(有條件強推)

tag

若要添加標示標籤,可以在 tag 命令加上 -a 參數執行,執行後會啟動編輯器,請輸入要給予的註解。也可以用 -am 參數來直接添加註解。

git tag -a [TAG_NAME]

在 HEAD 指向的提交裡增加名為 [TAG_NAME] 的標籤,請執行以下的命令。

git tag -am 'msg...' [TAG_NAME]
git tag -n # 可以顯示出標籤和註解

fork 專案

github 選擇 fork ,需在把你的 remote 專案名稱修正,因為通常 origin 指的是自己的開發 remote。然後在把 fork 的 repositories 設定到你的 origin 裡面。

確認 remote 的名稱 ⇒ 修正名稱 ⇒ 加入新的 fork repositories ⇒ 確認 remote 的名稱

它會產生一個新的專案,然有過去一樣整的 commit (這個很種要不然會沒有辦法 merge code 進來 fork 的專案)

git remote add upstream [UPSTRESM_PROJECT]

fetch 一下有沒有新的 code 和改變

git fetch upstream

切而你要的 branch , 然後 merge 原本的 upstream/main 進來現在的 code

git checkout [TARGET_BR]
git merge upstream/main ## merge upstream branch code
git rebase upstream/main ## 也是可以,就是讓 git tree 在 clear 一點

檢查 git

下列這些指令是在你開發到一半,想要回去查東西時很用的指令

 # 看一下還有多少東西沒有進暫存區
git status

# 確認這個 br commit 的狀況
git log

# 確認一下遠端
git remote -v

# stash 的清單
git stash list

# 可以檢看一下指令
git remote -h

參考文章

Git 環境設定 小技巧

搬移檔案

git commit message 的格式

git commit message 的格式

https://zlargon.gitbooks.io/git-tutorial/content/