Git Cheat Sheet

Git-Cheat-Sheet

Pro Git

此為精進 Git 技巧的書籍,有善心人士幫忙翻譯成中文電子版,幾乎所有的用法和技巧裡面都有交代到。

Pro Git in Chinese

gitignore 大全

基本指令

建立 Repository

$ git init
$ git add README
$ git status
$ git commit -m "First Commit"

常用指令

$ git status # 查看發生改動的文件列表
$ gitk # 圖形化工具查看文件改動,Git 自帶的圖形化界面
$ git checkout . # 取消所有修改
$ git checkout xxxFile # 取消某個文件的修改
$ git add -A # 新增所有修改
$ git commit -m 'commit message' # 提交修改

$ git push # 提交程式碼到遠程分支, 預設使用 origin 作為名稱
$ git pull # 從遠程倉庫獲取最新程式碼

$ git fetch # 從遠程獲取 branch/tag 訊息
$ git branch # 查看本地分支, -r 查看遠程分支, -a 查看所有
$ git checkout develop # 切換到 develop 分支, -b 新建並切換到分支
$ git merge develop # 將 develop 分支 merge 到當前分支

$ git tag # 查看 tag
$ git tag -a v1.0 -m 'tag message' # 新增 tag
$ git push --tags # 同時推送 tag 到遠程倉庫

$ git help xxxCmd # 查看幫助文件, 會用瀏覽器打開 html 文件
$ git config --global user.name "User-Name" # Git 設定, --global 全局生效

使用 Stash 暫存功能

$ git stash # 暫存本地修改
$ git stash pop # 恢復暫存的修改

進階指令

檔名大小寫的重新命名

Git 對於檔名的處理是大小寫不分的(case-insensitive) 如果只是把 program.cs 改為 Program.cs,用 git status 會看不到任何改變,請使用下列命令列處理

$ git mv -f program.cs Program.cs

如果是資料夾名稱要做大小寫修改了話,則需要兩個步驟,才能變更成功

$ git mv -f folder temp
$ git mv -f temp FOLDER

修改版控資料夾名稱

使用 renamemove 做資料夾更名

git mv <old name> <new name>

拋棄所有尚未 Commit 的資料

$ git reset --hard    #to discard changes made to versioned files
$ git clean -xdf      #to erase new (untracked) files, including ignored ones (the x option). d is to also remove untracked directories and f to force.

簽出 PR 的程式碼

參考:How can I check out a GitHub pull request?

Pull Request(PR) 不是 Commit 點也不是分支,要將 PR 程式碼簽出至本機,可以透過下列兩種方式:

# 指定遠端的 PR ID,例如 939
$ git pull origin pull/939/head
# 取得遠端 PR 資訊並建立分支,BRANCHNAME 為自訂的分支名稱
$ git fetch origin pull/ID/head:BRANCHNAME
# 再切換到該分支
$ git checkout BRANCHNAME 

以上的動作,是會將 PR 的提交抓下來後,將 HEAD 切到該 PR 的提交點,作為當前的工作目錄。

刪除遠端和本地端的分支

http://stackoverflow.com/questions/2003505/delete-a-git-branch-both-locally-and-remotely As of Git v1.7.0, you can delete a remote branch using

$ git push origin --delete <branchName>

更新成符合 .gitignore 設定的追蹤狀態

只要檔案有被提交過,就會持續被 Git 所追蹤,因此再建立 .gitignore 之前,就已經提交檔案了話,那麼即使再從 .gitignore 內加入新規則,也無法排除已經被追蹤的檔案。

.gitignore 只能忽略那些沒有被追蹤的檔案 (Untracked Files)。

如果想要使更新後的 .gitignore 設定生效,排除已經被追蹤過的檔案時,可以參考以下步驟:

  1. 清除本機 Git 的快取,相當於將所有檔案移除,但沒有刪除檔案
  2. 重新加入 Git 追縱,這時會套用 .gitignore 設定
  3. 提交,這個提交內容會是將排除的檔案刪除
git rm -r --cached .
git add .
git commit -m 'update .gitignore'

透過 https 下載套件,取代 git protocol

現在前端套件幾乎都會透過 Bower 來下載,而 Bower 預設使用 git protocol 來下載原始檔案,如果遇到 timeout 逾時,也就是無法透過 git:// 方式,就必須要切換成 https:// 下載,切換方式很容易,請在 Console 鍵入底下指令:

$ git config --global url."https://".insteadOf git://

移除 Git 歷史紀錄

參考本站文章

移除前次 commit

git reset 可以砍掉 commit 重來,但修改的程式依然存在:

git reset HEAD^

執行上列指令就會回到前一版本,其中 ^ 表示是前一版,可以使用多個 ^ 來回到多前 n 版。

此指令常用於發現前一次 commit 有問題時,可以回到前一次 commit,並於修改後再重新 commit。

將檔案加入上一個 commit

REF: How to add a file to the last commit in git?

如果已經 commit 了,但想將再加入檔案時,可以下列指令

git add THE_FILE_YOU_WANT_TO_ADD
git commit --amend --no-edit

--no-edit 參數允許你修改上一個 commit 的內容,而不修改其 commit 訊息

設定 Git 自訂指令

可以使用 git config alias.CUSTOME CUSTOM_COMMAND 來設定自訂指令,之後執行 git CUSTOME 就可以了

推薦執行下列指令,建立 git ll 顯示簡易的命令列線圖

$ git config --global alias.ll "log --pretty=format:'%h %ad | %s%d [%Cgreen%an%Creset]' --graph --date=short"

git ll

協作專案時常用指令

  • 自訂 push/fetch 不同的來源
    • 透過 git config 設定
      • git config --local remote.origin.url <fetchurl>
      • git config --local remote.origin.pushurl <pushurl>
    • 透過 git remote 設定
      • git remote set-url origin <fetchurl>
      • git remote set-url origin --push <pushurl>
    • 查看遠端儲存庫設定
      • git remote -v

Git 內部細節

.git 資料夾

  • .git 資料夾包含整個版控的設定及歷史紀錄
    • 這也是完整的儲存庫備份

資料結構

整個 Git 的資料結構主要由四種物件組成

  • 物件(Object)
    • 執行 git add, git tag 指令就會產生物件
    • 查看物件的指令 git cat-file -t [SHA-1]
      • SHA-1 是使用檔案內容做 HASH 所產生的
      • -t 顯示該物件的類別
      • -s 內容大小
      • -p 顯示內容
    • blob
      • 紀錄資料快照,不存檔名
    • tree
      • 這裡面會有檔名和 Object 的對照
    • commit
      • 裡面的 author 和 committer 可能是不同的
      • 當使用 rebase 的時候,會重新 commit 原作者的內容,這時候 cimmitter 就會是新的人
      • 在 GUI 工具中看到的線圖,就是 commit 物件的資訊
    • tag
      • 指向某一個 commit
      • tag 有兩種樣態,一個是這裡的 Object,另一個是參考的指標,存放在 refs/tags
  • 索引(Index)
    • 索引檔內會有所有版控中的檔案,保存要進儲存庫之前的所有檔案狀態
    • 當資料要寫入 Git 的時候,會需要索引檔
    • 空的資料夾是無法加入版控的,如果硬要加入版控了話,至少要有一個檔案,建議用 .gitkeep
  • 分支(Branch)
    • 記錄在 .git\refs\heads 資料夾下,例如 master
    • 內容是一個 SHA-1 的指標,指向一個 commit

Git Client Tools

指令視作強大的,但畢竟人是視覺動物,有時候看到畫面(線圖)會感覺比較親切。


參考資料:


Poy Chang

Trial and Error