Skip to content
On this page

Git Notes ​

設定 Git ​

  • git config --global user.name "<GitHub Username>":設定全域使用者名稱 ( 同 GitHub 的就好 )
  • git config --global user.email "<GitHub email>":設定全域使用者信箱 ( 同 GitHub 的就好 )

Git 基礎常用命令 ​

一般操作 ​

  • git clone <GitHub url>:把整個專案複製一份下來本地並存在同名的目錄裡

    所有整個專案的歷史紀錄、分支、標籤等內容都會複製一份下來 最後可以再加參數指定存放位置 ( 可以順便改名 )

  • git init:在當前目錄下初始化出一個空的本地儲存庫
  • git remote add origin <GitHub url>:設定端節的節點
  • git status:查看當前工作區與暫存區狀態
  • git log:查看當前本地儲存庫的 commit 紀錄
  • git log --oneline 用一行查看當前本地儲存庫的 commit 紀錄
  • git reflog:查看過去 HEAD 指向過去的 commit 清單
  • git stash list:查看目前的 Stash ( 可以放很多份 )

    WIP 字樣是「Work In Progress」就是工作進行中的意思

  • git remote:顯示已經設定好的遠端版本庫
  • git remote -v:更詳細地顯示已經設定好的遠端版本庫
  • git branch --remote:顯示遠端的分支

檔案處理 ​

  • git add <file name>:將 <file name> 的變更放入暫存區
  • git commit -m "<message>":將當前暫存區中的所有變更打包成一個版本,並附加版本敘述訊息,紀錄進本地儲存庫
  • git checkout <file name>:放棄在工作區中名為 <file name> 檔案的所有變更
  • git push <remote> <branch>:將本地儲存庫的狀態推到遠端儲存庫

    通常 <remote> 都是 origin

  • git push -u <remote> <branch>:將本地儲存庫的狀態推到遠端儲存庫

    -u 為將此指令設為預設,可縮寫為 git push

  • git fetch:本地更新遠端儲存庫的狀態,但遠端被刪除的本地不會跟著刪除

    如果遠端有新分支必須 fetch 才能 pull

  • git fetch -p:本地更新遠端儲存庫的狀態,遠端被刪除的本地會跟著刪除
  • git fetch <remote>:視狀況要不要指定 <remote> ( 可能設定兩個以上 )
  • git pull <remote> <branch>:將遠端儲存庫的狀態拉到本地儲存庫

    git pull = git fetch + git merge

  • git pull --rebase: Fetch 完成之後,便會使用 Rebase 方式進行合併

    如果不想要 merge 時額外產生的 Commit,可考慮使用 Rebase 方式來進行合併 如果線上版本的內容比本地還要新,Git 不讓你推上去時可用此方法 ( 先拉再推 )

  • git push -f:強迫硬推上去,把遠端更新的內容蓋掉

    如果線上版本的內容比本地還要新,Git 不讓你推上去時可用此方法 但是線上版本更新的部分將會被蓋掉!

  • git reset:將暫存區變更退回工作區
  • git reset [--mixed/--soft/--hard] <commit>:挪動本地儲存庫 HEAD 指向的位置
    • mixed:將指向位置相對未來紀錄的變更退回工作區
    • soft:將指向位置相對未來紀錄的變更退回暫存區
    • hard:將指向位置相對未來紀錄的變更刪除 ( 還有救 )
  • git revert <commit>:將指定的 commit 做反向操作並留下一筆紀錄

    被指定的 commit 的變更紀錄將會消失,但 commit 仍存在, 因為它是透過新增一個 commit 去反向操作將這些變更部分刪除

    • 如果反悔,可以再開一個新的 Revert,來 Revert 剛剛這個 Revert
    • 如果是要砍掉這個 Revert,直接使用 Reset 指令

cherry-pick ​

  • git cherry-pick <commit hash value>...:撿其他的分支的 Commit 過來跟現分支合併
  • git cherry-pick <commit hash value> --no-commit:撿過來的 Commit 不會直接合併,而是會先放在暫存區

stash ​

  • git stash:把目前的修改先暫存起來
  • git stash pop <stash>:把某個 Stash 拿出來並套用在目前的分支上

    套用成功之後,那個套用過的 Stash 就會被刪除

    • 如果後面沒有指定 Stash,預設為最後疊上去的那個
  • git stash drop <stash>:把這個 Stash 從列表裡刪掉
  • git stash apply <stash>:把這個 Stash 拿來套用在現在的分支上並不刪除

分支處理 ​

  • git branch <branch name>:創建名為 <branch name> 的分支
  • git branch -D <branch name>:刪除名為 <branch name> 的分支
  • git branch -m <branch name> <new branch name>:更改分支的名稱
  • git checkout <branch name>:切換到名為 <branch name> 的分支 ( 最新的 Commit )
  • git checkout -b <branch name>:創建並切換到名為 <branch name> 的分支
  • git branch <branch name> <commit hash value>:建立一個 <branch name> 分支指向 <commit hash value> 這個 Commit
  • git merge <target branch>:將名為 <target branch> 的 分支合併到當前所在的分支
  • git rebase <source branch>:將當前所在的分支的根節點挪到名為 <source branch> 的分支葉節點上
  • git branch <new branch name> <commit hash value>:尚未合併的分支被刪除後可透過建立一個新的的分支,讓它指向原分支上 <commit hash value> 這個 Commit
  • git checkout -t <remote branch>:切換到遠端分支 <remote branch name> 而不呈現 detached HEAD 狀態

    -t 或 --track 都可以 指會在本機建立一個名為追蹤分支(tracking branch)的東西

  • git remote add upstream <GitHub url>:加上另一個遠端節點 ( 通常是 Fork 時原作的專案 )
  • git push <remote> :<remote branch>:刪除遠端分支

注意

分支只是一個指向某個 Commit 的指標!

合併衝突 ​

  • git reset <commit hash value> --hard:取消 rebase,選擇 rebase 前的最後動作的 Commit 的雜湊值
  • git reset ORIG_HEAD --hard:取消 rebase,ORIG_HEAD 會記錄「危險操作」之前 HEAD 的位置
  • git rebase --continue:若 rebase 發生衝突,檔案修正後繼續 rebase
  • git rebase --abort:若 rebase 發生衝突,放棄這次的 rebase
  • git checkout --ours <image>:若是圖片之類的檔案產生衝突,決定使用當前分支的檔案
  • git checkout --theirs <image>:若是圖片之類的檔案產生衝突,決定使用對方分支的檔案

互動模式 ​

  • git rebase -i <commit hash value>:-i 參數是指要進入 Rebase 指令的「互動模式」,而後面的 <commit hash value> 是指這次的 Rebase 指令的應用範圍會「從現在到 <commit hash value> 這個 Commit」,這個指令會跳出一個 Vim 編輯器。

WARNING

請注意 Commit 的順序!

Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit

修改 Commit 順序 只要將內容順序做變換就好 ( 越新的 Commit 在越下面 )

刪除 Commit 把原本的 pick 改成 drop,或甚至直接把那行刪掉

pick & reword ​

更改 Commit 訊息

  1. 前面的 pick 的意思是保留這次的 Commit,不做修改
  2. 將pick 改成 reword 表示修改此 Commit 的訊息
  3. 存檔並離開之後,立馬就會再跳另一個 Vim 編輯器畫面去編輯 Commit 訊息內容
  4. 被更改的 Commit 根本就是全新的 Commit ( 雜湊值已更新 )
  5. 在它之後的 Commit 會因為前面的歷史改了,所以後面整串的 Commit 全部都重新做出新的 Commit 出來替代舊的 Commit

squash ​

將多筆 Commit 紀錄合併

  1. 將pick 改成 squash 表示將此 Commit 併到前一個 Commit
  2. 存檔並離開 Vim 編輯器後,它會開始進行 Rebase
  3. 而在 Squash 的過程中,它還會跳出 Vim 編輯器讓你編輯一下 Commit 訊息

edit ​

將單筆 Commit 拆成多筆 Commit

  1. 將pick 改成 edit 表示將對此 Commit 停留做修改 ( HEAD 會指向此 commit )
  2. git reset HEAD^ reset 回到上一個 Commit,並將原本的變更退回工作區
  3. 重新 add 和 commit
  4. git rebase --continue 完成後要記得讓 Rebase 繼續跑完

在某些 Commit 之間再增加一些其它的 Commit

  1. 將pick 改成 edit 表示將對此較舊的 Commit 停留做修改 ( HEAD 會指向此 commit )
  2. 新增需要的 commit
  3. git rebase --continue 繼續剛剛中斷的 Rebase

Git Flow ​

長期分支 ​

  • master

    主要用來放穩定、隨時可上線的版本。
    這個分支的來源只能從別的分支合併過來,開發者不會直接 Commit 到這個分支。
    因為是穩定版本,所以通常會在這個分支上的 Commit 上打上版本號標籤。

  • develop

    主要是所有開發的基礎分支。
    要新增功能時,所有的 feature 分支都是從這個分支切出去的。
    而 feature 分支的功能完成後,也都會合併回來這個分支。

短期分支 ​

  • hotfix

    當線上產品發生緊急問題的時候,會從 master 分支開一個 hotfix 分支出來進行修復。
    hotfix 分支修復完成之後,會合併回 master 分支,也同時會合併一份到 develop 分支。

為什麼要合併回 develop 分支?

如果不這麼做,等到 develop 分支完成並且合併回 master 分支的時候,問題再次出現了。

為什麼不直接從 develop 分支切出來修?

因為 develop 分支的功能可能尚在開發中,這時候硬是要從這裡切出去修再合併回 master 分支,只會造成更大的災難。

  • release

    當認為 develop 分支足夠成熟了,就可以把 develop 分支合併到 release 分支,在這邊進行算是上線前的最後測試。
    測試完成後,release 分支將會同時合併到 master 以及 develop 這兩個分支上。
    master 分支是上線版本,而合併回 develop 分支的目的是因為可能在 release 分支上還會測到並修正一些問題,所以需要跟 develop 分支同步,免得之後的版本又再度出現同樣的問題。

  • feature

    需要新增功能時就是使用 feature 分支。
    feature 分支都是從 develop 分支來的,完成之後會再併回 develop 分支。

Commit 提交描述 ​

  • feat:新功能
  • fix:修復 bug
  • docs:文件
  • style:coding style 的調整,例如:空白、分號、空格等,不影響程式碼的內容
  • refactor:重構現有程式碼,不屬於新增新功能或是修 bug
  • perf:提升效能的改進
  • test:新增或修改測試
  • build:和打包或外部依賴相關的修改,例如:npm、gulp、broccoli
  • ci:與 CI 設定檔或 script 相關的修改,例如:Travis、Circle、BrowserStack、SauceLabs
  • chore:其他,並且也不會修改原始碼或是測試,例如:storybook 的新增或變更
  • revert:回復前一個提交的 commit

其他技巧 ​

來源參考 ​

⋯ Git 基礎筆記⋯ 為你自己學 Git