①②①Git 版本控制入門(3)

Beginning Git: Ep. 7 ~ 8 — Ignoring Files,Viewing History

Min
14 min readJan 9, 2024

接續上一篇:

線上課程資源:

以下跟著課程實做用 zsh 練習 git。

Ep. 7 Ignoring Files

有方法能讓 Git 忽略一些檔案,不過為什麼需要 Git 去忽略他們呢?

誰需要 git ignore?

像是 API Key 或密碼這些比較私密、 App 需要但不應該放在 repository 中的資料,一但曾經放到 repository 中,之後就算刪掉他們了,但仍可能拿回來,因此要十分謹慎,不要 commit 他們到 Git repo 之中。

通常透過環境變數儲存 App 需要的秘密,再將他們存在不會被 Git 注意到的檔案中。剛好在做飲料 App 的時候遇過 API 存放的問題:

另一種可能是在 build 過程中生成了大量只有在連結階段才需要的元數據(metadata),這些也不需要被 Git 追蹤。

AI 解釋:許多檔案,如編譯過程中產生的物件檔案(.obj, .o)或中間檔案,可以在每次建置(build)過程中自動重新生成。由於它們是衍生品,可以從源代碼中重新產生,因此沒有必要將它們加入版本控制。

還有第三方套件( third party dependencies),像在 iOS 中,如果使用 CocoaPods 這樣的套件,對於需不需要將他們存到 git repo 中是有爭議的。

另外,像是作業系統生成器檔案,例如使用 vim 創建一個暫存檔紀錄當前編輯狀態,MacOS 創建 .DS_Store 檔案等等,這些也不用存到 git repo 中。

.gitignore

對於以上種種不需要存到 git repository 中的檔案,使用 git ignore 的方式應對。這是一個空白的文字檔案:.gitignore,使用它列出一系列希望 Git 完全忽略的路徑模式。

global ignore

global ignore 指的是設定 Git 全域性地忽略特定檔案或路徑模式的機制。這意味著這些設定會應用到使用者所有的 Git repository,而不只是某個特定的repository。這樣做可以方便地避免將不需要的檔案(如編輯器的暫存檔、作業系統生成的檔案等)加入到 Git 中。

實做

使用 git ignore 防止 html 檔案被存到 git 中。

建立新檔案:

touch allTODOs.html

使用 git status 檢查狀態:

產生 .gitignore 檔案:

vim .gitignore

在檔案中輸入 *.html 。在.gitignore 檔案裡,用來指定 Git 應該忽略所有以 .html 結尾的檔案。

*.html

儲存後離開編輯模式,再次用git status 檢查,會發現 allTODOs.html 不再被視為未被追蹤的檔案,因為它被忽視了。不過 .gitignore 檔案被視為未被追蹤的檔案,準備被 commit:

建立另一個 html 檔案:

touch videos/videos.html

仍然沒被追蹤:

如果回去.gitignore 檔案把那一行*.html 刪掉,則這兩個 html 檔案又會被 Git 看見了:

剛剛的方法講的是在專案的 top level(頂層) 中可以 ignore 所有 html 檔案,接著要來講如何在 subdirectories (子目錄)中建立。

在子目錄 videos 中建立一個.gitignore 檔案,並也在檔案裡輸入 *.html

vim videos/.gitignore

git status 檢查,發現在 top level 的檔案還是被看見,但在 videos 資料夾內的 videos/videos.html 就沒被 Git 追蹤到:

移除 videos/.gitignore:

rm videos/.gitignore

videos/videos.html 又回到 Git 的視線中:

一直在看得見、看不見,讓人想起索倫之眼…

再次回到頂層建立 .gitignore

vim .gitignore

.gitignore檔案內輸入 */*.html ,代表著 Git 應該忽略所有子目錄中的 .html 檔案,但不忽略頂層目錄(根目錄)中的 .html 檔案:

*/*.html

git status檢查,發現頂層的 html 檔還在,但videos/videos.html 被忽略:

繼續實驗其他的 ignore 句法,vim .gitignore 回去編輯.gitignore ,刪除原本的 */*.html,加上這兩行:

*.html
!/*.html

.gitignore 中,以驚嘆號 (!) 開頭的模式用來指定不應該被忽略的檔案或路徑。在這個例子中,!/*.html 指的是不要忽略位於頂層目錄中的 .html 檔案。

結合這兩條規則,意味著 Git 會忽略所有子目錄中的 .html 檔案,但會追蹤頂層目錄中的 .html 檔案。這樣的設定常見於想要追蹤根目錄中的主要 HTML 檔案(例如項目的首頁或文檔),但想忽略子目錄中可能由工具生成或不重要的 HTML 檔案的情況。

git status檢查,頂層的 html 檔還在,但videos/videos.html 被忽略:

接著 stage 跟 commit:

git add .
git commit -m "Adding .gitignore"

針對作業系統生成器檔案的 .gitignore

創建一個全域性忽略檔案:

touch ~/.gitignore_global

檔案中先寫下以下兩者:

*~
.DS_Store

設定 Git 以使用指定的路徑作為全域性忽略檔案,這個 .gitignore_global 包含了希望 Git 在所有專案中都自動忽略的檔案模式:

 git config --global core.excludesfile ~/.gitignore_global

使用 cat 顯示檔案的全部內容:

cat  ~/.gitignore_global

先思考一件事,當開啟一個新的專案時,什麼東西要放到 git ignore 裡?這種專案的標準為何?

Github 有一個充滿範例 .gitignore 檔案的 repository,適合任何不同類型的專案。在裡面可以針對自己的作業系統找到屬於自己的 global git ignore。

本課挑戰

github.com/github/gitignore 找到屬於自己作業系統的 global git ignore,並安裝它。

如果要用 Swift,在 Swift.gitignore 中有很多使用 Swift 可用的句法:

由於現在要找 global gitignore,因此進入 Global:

找到我用的 MacOS 系統,全選複製內容:

回到 terminal,vim ~/.gitignore_global 在剛剛兩行之後貼上:

儲存離開

從現在開始, Git 在任何新建立的 repo 中都不會追蹤任何系統檔案。

Ep. 7 重點 git 指令

git config --global core.excludesfile 檔案路徑

使用 Git 配置命令將這個檔案設定為全域性的忽略檔案。

Ep. 8 Viewing History

本章練習查找 repo 的 commit 歷史紀錄,聚焦在強大的 git log 。這個指令提供了 repo 歷史中各個 commit 的詳細資訊,包括提交者的名字和電子信箱、提交日期和時間,以及提交訊息:

git log

view

在之前已經多次使用 git log,都看到這個模式:

透過 git log -4 指定只要看到四個 commits:

git log -數字

git log --oneline 指定每個 commit 只顯示一行資訊,hash 值與標題:

git log --oneline

使用 git log --decorate ,加上其他資訊,如對應的分支(branch)名稱、標籤(tags)或其他參考(如 HEAD)。若還沒有分支名稱,增加名稱:

git log --decorate

git log --graph 提供類似 ASCII(美國資訊交換標準碼)的格式,圖形化呈現:

 git log --graph

可以將這些指令拼接使用:

git log --oneline --graph --decorate --all

將顯示結合 ASCII 的 repo 全部資訊,包含 remote branches and merges 的分支:

顯示連續 Commits 之間的 diff:

git log -p

git shortlog 只顯示每個 commit 的第一行,以作者分組:

git shortlog

git shortlog -4 只顯示四個 commit 的第一行:

git shortlog -數字

使用 git shortlog origin/master..HEAD 看 origin master 與目前所在位置 HEAD 之間的 commits:

git shortlog origin/master..HEAD

Search

前面講的都是直接看 commit 歷史,接著要講直接搜尋歷史,可以使用不同的 filter,也可以只在一個 commit 中找尋。

使用 git log --author=”Sam” 搜尋 Sam 的 commit:

git log --author="作者名"

看到的都是 Sam 的部分:

使用 git log --grep=”idea” 搜尋全部 commit 訊息中出現 idea 的地方(不包含檔案內容,只是 commit 時填寫的資訊):

git log --grep="關鍵字"

超多:

當只想看特定一個檔案的 log,比如 READ.md,使用 git log -- README.md

git log -- README.md

git log -S”Fortran”,用於搜索代碼變更中添加或移除 Fortran 的 commit:

git log -S"關鍵字"

更進一步,使用 git log -S”Fortran” -p 取得 DIFF:

git log -S"關鍵字" -p

本章練習

使用 git log 完成以下四件事:

  1. Find all of the commits that involve checking off a to-do item.
  2. Find all of the commits whose messages mention streaming.
  3. Give a potted history of what on in the books directory.
  4. Find all of the content that mention Windows 10.

Find all of the commits that involve checking off a to-do item.

使用 git log -S”[x]” -p 尋找 Checking off a to-do item 的 commit:

Find all of the commits whose messages mention streaming.

使用 git log --grep=”streaming” 尋找 message 中包含streaming 這個字的 commit:

Give a potted history of what on in the books directory.

要尋找 books directory 中的所有歷史紀錄,使用 git log --books/ :

因為 books 是這個 path 的開頭,所以 books 內所有檔案都會顯示出來

使用 git log -p --books/ 看 diff:

Find all of the content that mention Windows 10.

使用 git log -p --all -S”Windows 10" 發現怎麼找不到東西,原來我的articles/clickbait_ideas.md 檔案是空的?自己新增 Windows 10 之後 Stage 跟 Commit 之後再次搜尋,就出現了:

不要忘記使用--all 搜尋全部分支,沒用 --all 的話, log 只會搜尋當前分支。

Ep. 8 重點 git 指令

git log      提供 commit 歷史紀錄
git log -數字 指定看到幾個 commits
git log --oneline 每個 commit 只顯示一行資訊
git log --decorate 加上其他資訊
git log --graph 提供類似 ASCII(美國資訊交換標準碼)的格式
git log -p 顯示連續 Commits 之間的 diff
git shortlog 只顯示每個 commit 的第一行
git shortlog -數字 只顯示幾個 commit 的第一行
git shortlog origin/master..HEAD 看 origin master 與目前所在位置 HEAD 之間的 commits

git log --author="作者名" 搜尋指定作者的 commit
git log --grep="關鍵字" 搜尋全部 commit 訊息中出現關鍵字的地方
git log -- 檔名 只看指定檔名的 log
git log -S"關鍵字" 用於搜索代碼變更中添加或移除關鍵字的 commit
git log -S"關鍵字" -p 取得關鍵字的 DIFF

謝謝收看,下一篇將是重要的 Branching:

--

--