專為技術(shù)寫作人員提供的七條 Git 技巧
作為 ATIX 的技術(shù)作家,我的任務(wù)包括為 Foreman 創(chuàng)建和維護(hù)存放在 github.com/theforeman/foreman-documentation 的文檔。Git 幫助我跟蹤內(nèi)容的版本,并與開源社區(qū)進(jìn)行協(xié)作。它是我存儲(chǔ)工作成果、共享和討論改進(jìn)的重要工具。我主要使用的工具包括瀏覽器、用 OpenSSH 連接 Foreman 實(shí)例、用 Vim 編輯源文件,以及使用 Git 進(jìn)行版本控制。
本文重點(diǎn)介紹在開始使用 Git 和為 Foreman 文檔做貢獻(xiàn)時(shí)經(jīng)常遇到的挑戰(zhàn)。適用于中級(jí) Git 用戶。
先決條件
你已在系統(tǒng)上安裝和配置了 Git。你至少需要設(shè)置用戶名和電子郵件地址。
你在 github.com 上擁有一個(gè)帳戶。GitHub 本身并不是一個(gè)開源項(xiàng)目,但它是許多開源 Git 存儲(chǔ)庫(kù)的托管站點(diǎn)(包括 Foreman 的文檔)。
你已將 foreman-documentation 存儲(chǔ)庫(kù)復(fù)刻到你自己的賬戶或組織(例如,github.com/<My_User_Account>/foreman-documentation,這里 <My_User_Account> 是你的 GitHub 用戶名)。
你已將你的 SSH 公鑰添加到 GitHub。這是將你的更改推送到 GitHub 所必需的。
對(duì) Foreman 文檔做出貢獻(xiàn)
Foreman 是一個(gè)開源項(xiàng)目,依靠社區(qū)的貢獻(xiàn)而發(fā)展壯大。該項(xiàng)目歡迎所有人的參與,并且只有一些要求才能做出有意義的貢獻(xiàn)。這些要求和慣例在 README.md 和 CONTRIBUTING.md 文件中有詳細(xì)記錄。
以下是在處理 Foreman 文檔時(shí)最常見(jiàn)的一些任務(wù)。
我想開始貢獻(xiàn) Foreman 文檔
1、從 github.com 克隆存儲(chǔ)庫(kù):
$ git clone git@github.com:theforeman/foreman-documentation.git
$ cd foreman-documentation/
2、重命名遠(yuǎn)程存儲(chǔ)庫(kù):
$ git remote rename origin upstream
3、可選:確保你的本地主分支跟蹤 theforeman 組織的 foreman-documentation 存儲(chǔ)庫(kù)的 master 分支:
$ git status
這將自動(dòng)將你置于默認(rèn)分支(本例中為 master)的最新提交上。
4、如果你的賬戶或組織中尚未有該存儲(chǔ)庫(kù)的 復(fù)刻Fork,請(qǐng)創(chuàng)建一個(gè)。前往 github.com/theforeman/foreman-documentation 并點(diǎn)擊 “復(fù)刻Fork” 按鈕。
5、將你的復(fù)刻添加到你的存儲(chǔ)庫(kù)中:
$ git remote add github git@github.com:<My_User_Account>/foreman-documentation.git
你的本地存儲(chǔ)庫(kù)現(xiàn)在有兩個(gè)遠(yuǎn)程存儲(chǔ)庫(kù):upstream 和 github。
我想擴(kuò)展 Foreman 文檔
對(duì)于簡(jiǎn)單的更改,比如修正拼寫錯(cuò)誤,你可以直接創(chuàng)建一個(gè)拉取請(qǐng)求(PR)。
1、創(chuàng)建一個(gè)分支,例如 fix_spelling。git switch 命令用于切換當(dāng)前所在的分支,-c 參數(shù)用于創(chuàng)建分支:
$ git switch -c fix_spelling
2、進(jìn)行你的更改。
3、添加你的更改并進(jìn)行提交:
$ git add guides/common/modules/abc.adoc
$ git commit -m "Fix spelling of existing"
良好的 Git 提交消息的重要性無(wú)需再?gòu)?qiáng)調(diào)。提交消息告訴貢獻(xiàn)者你做了哪些工作,因?yàn)樗c代碼庫(kù)的其余部分一起保存,所以它在查看代碼時(shí)起到歷史注釋的作用,幫助了解代碼的演化過(guò)程。有關(guān)優(yōu)秀的 Git 提交消息的更多信息,請(qǐng)參閱由 cbeams 撰寫的 《創(chuàng)建完美的 Git 提交信息的 7 條規(guī)則》。
4、可選但建議的操作:查看并驗(yàn)證與默認(rèn)分支的差異。foreman-documentation 的默認(rèn)分支稱為 master,但其他項(xiàng)目可能有不同的命名(例如 main、dev 或 devel)。
$ git diff master
5、將分支推送到 GitHub。這將發(fā)布你的更改到你的代碼庫(kù)副本:
$ git push --set-upstream github fix_spelling
6、點(diǎn)擊終端中 Git 提供的鏈接來(lái)創(chuàng)建一個(gè)拉取請(qǐng)求(PR):
remote: Create a pull request for 'fix_spelling' on Github by visiting:
remote: https://github.com/_My_User_Account_/foreman-documentation/pull/new/fix_spelling
7、在解釋中說(shuō)明社區(qū)為什么應(yīng)該接受你的更改。對(duì)于修正拼寫錯(cuò)誤等簡(jiǎn)單 PR,這并不是必需的,但對(duì)于重大更改則很重要。
我想將我的分支變基到 master
1、確保你的本地 master 分支跟蹤的是 github.com/theforeman/foreman-documentation 的 master 分支,而不是你自己命名空間下的 foreman-documentation:
$ git switch master
此時(shí)應(yīng)該顯示 Your branch is up to date with 'upstream/master',其中 upstream 是指向 github.com/theforeman/foreman-documentation 的遠(yuǎn)程存儲(chǔ)庫(kù)的名稱。你可以通過(guò)運(yùn)行 git remote -v 來(lái)查看遠(yuǎn)程存儲(chǔ)庫(kù)設(shè)置情況。
2、從遠(yuǎn)程獲取可能的更改。git fetch 命令會(huì)從遠(yuǎn)程下載被跟蹤的分支,并且使用 --all 選項(xiàng)可以同時(shí)更新所有分支。在使用其他分支時(shí)這是必要的。--prune 選項(xiàng)會(huì)刪除對(duì)已不存在的分支的引用。
$ git fetch --all --prune
3、將可能的更改從 upstream/master 拉取到你的本地 master 分支。git pull 命令將跟蹤的分支上的提交復(fù)制到當(dāng)前分支。這用于將你的本地 master 分支“更新”為遠(yuǎn)程(在本例中為 GitHub)master 分支的最新?tīng)顟B(tài)。
$ git pull
4、將你的分支 變基rebase 到 master。
$ git switch my_branch
$ git rebase -i master
我在 master 分支上意外地提交了代碼
1、創(chuàng)建一個(gè)分支來(lái)保存你的工作:
$ git switch -c my_feature
2、切換回 master 分支:
$ git switch master
3、回退 master 分支上的最后一次提交:
$ git reset --soft HEAD~1
4、切換回 my_feature 分支并繼續(xù)工作:
$ git switch my_feature
我想修改我的提交消息
1、如果你的分支只有一次提交,可以使用 git amend 來(lái)修改你的最后一次提交:
$ git commit --amend
這假設(shè)你沒(méi)有將其他文件添加到暫存區(qū)(即,沒(méi)有運(yùn)行過(guò) git add My_File,并且沒(méi)有進(jìn)行提交)。
2、使用 --force 選項(xiàng)將你的 “更改” 推送到 GitHub,因?yàn)?Git 提交消息是你現(xiàn)有提交的一部分,所以你正在更改分支上的歷史記錄:
$ git push --force
我想重新整理單個(gè)分支上的多個(gè)更改
1、可選但強(qiáng)烈推薦:從 GitHub 獲取更改。
$ git switch master
$ git fetch
$ git pull
這確保你將其他更改按照它們被合并到 master 中的順序直接合并到你的分支中。
2、若要重新整理你的工作,請(qǐng)對(duì)你的分支進(jìn)行變基并根據(jù)需要進(jìn)行更改。對(duì)于將分支變基到 master,這意味著你需要更改你的分支上第一個(gè)提交的父提交:
$ git rebase --interactive master
使用你喜歡的編輯器打開變基交互界面,將第一個(gè)單詞 pick 替換為你要修改的提交。
- 使用 e 來(lái)對(duì)你的提交進(jìn)行實(shí)際更改。這會(huì)中斷你的變基操作!
- 使用 f 將一個(gè)提交與其父提交合并。
- 使用 d 完全刪除一個(gè)提交。
- 移動(dòng)行以改變你更改的順序。
成功進(jìn)行變基后,你自己的提交將位于 master 上最后一個(gè)提交的頂部。
我想從其他分支復(fù)制一個(gè)提交
1、從穩(wěn)定分支(例如名為 3.3 的分支)獲取提交的 ID,請(qǐng)使用 -n 選項(xiàng)限制提交數(shù)量:
$ git log -n 5 3.3
2、通過(guò)挑選提交來(lái)復(fù)制更改到你的分支。-x 選項(xiàng)將提交的 ID 添加到你的提交消息中。這僅建議在從穩(wěn)定分支挑選提交時(shí)使用:
$ git switch My_Branch
$ git cherry-pick -x Commit_ID
更多技巧
在 ATIX,我們運(yùn)行一個(gè) GitLab 實(shí)例,用于內(nèi)部共享代碼、協(xié)作以及自動(dòng)化測(cè)試和構(gòu)建。對(duì)于圍繞 Foreman 生態(tài)系統(tǒng)的開源社區(qū),我們依賴于 GitHub。
我建議你始終將名為 origin 的遠(yuǎn)程指向你的內(nèi)部的版本控制系統(tǒng)。這樣做可以防止在純粹憑記憶進(jìn)行 git push 時(shí)向外部服務(wù)泄露信息。
此外,我建議使用固定的命名方案來(lái)命名遠(yuǎn)程。我總是將指向自己的 GitLab 實(shí)例的遠(yuǎn)程命名為 origin,將指向開源項(xiàng)目的遠(yuǎn)程命名為 upstream,將指向我在 Github 上的復(fù)刻的遠(yuǎn)程命名為 github。
對(duì)于 foreman-documentation,該存儲(chǔ)庫(kù)具有相對(duì)較平的歷史記錄。當(dāng)處理更復(fù)雜結(jié)構(gòu)時(shí),我傾向于以非??梢暬姆绞剿伎?Git 存儲(chǔ)庫(kù),其中節(jié)點(diǎn)(提交)指向線上的節(jié)點(diǎn)(分支),這些分支可以交織在一起。圖形化工具如 gitk 或 Git Cola 可以幫助可視化你的 Git 歷史記錄。一旦你完全掌握了 Git 的工作原理,如果你更喜歡命令行,可以使用別名。
在進(jìn)行具有大量預(yù)期合并沖突的大型變基之前,我建議創(chuàng)建一個(gè)“備份”分支,以便你可以快速查看差異。請(qǐng)注意,要永久刪除提交是相當(dāng)困難的,因此在進(jìn)行重大更改之前,請(qǐng)?jiān)诒镜?Git 存儲(chǔ)庫(kù)中進(jìn)行測(cè)試。
Git 對(duì)技術(shù)文檔編寫者的幫助
Git 對(duì)技術(shù)文檔編寫者來(lái)說(shuō)是一個(gè)巨大的幫助。不僅可以使用 Git 對(duì)文檔進(jìn)行版本控制,還可以與他人積極地進(jìn)行協(xié)作。