如何優雅地pull request

本文章主要用於闡述pr流程,以及可能遇到的狀況和解決方案,幫助你們更好地協做開發。html

若是須要了解git基礎知識,請查看如下連接:git

[git協做經常使用命令](juejin.im/post/5b5596…)
github

Pull Request請求一般由使用共享存儲庫協做的團隊和組織使用。 shell

Github上的許多開源項目使用pull request請求來管理來自貢獻者的更改,由於它們提供了一種方式來通知項目維護者其餘貢獻者所作的更改,而且在合併到主分支以前,能對代碼進行review和對此進行討論。npm

  • 主要有兩種進行pull request的工做流程;bash

    • 對一個forked倉庫進行pull request;微信

    • 對一個倉庫裏的分支進行pull request;工具

本文主要對第一種方式進行講解。post

1. Fork倉庫

  1. 將須要參與的項目倉庫fork到本身的github中;測試

2. git clone這個fork的項目

  1. 將本身的github中,找到fork下來的項目,git clone 到本地。

3. 添加上游倉庫

  1. 接着上一步,在該項目中,執行如下操做,將上游倉庫鏈接到本地倉庫,即咱們fork的地址:

git remote add <name> <url>複製代碼
  1. 其餘輔助功能:

git remote -v  //查看全部上游倉庫名字和git地址:複製代碼

4. 保持與上游倉庫的同步

  1. 更新 "指定" remote 底下的分支:

    git fetch <name> <branch>複製代碼
  2. 上面這個指令,一次只能更新一個remote,若是咱們有多個remote時,可使用:

    git remote update
    //或者
    git fetch --all複製代碼

  3. 當咱們使用pull命令拉取上游分支的最新代碼時,若是本地分支落後於上游分支,會產生一個新的merge commit 多餘信息,所以建議使用:

git pull --rebase <remote> <branch>
//等同於如下兩條命令
git fetch <remote> <branch>
git rebase <remote>/<branch>複製代碼

5. 提出issue

issue對你的項目,提供了一種很好的方式去追蹤,增強,修復bug。它有點像是郵件,可是它能夠被一塊兒討論。

對於項目維護者

  1. 建議項目維護者維護項目的issue模板,貢獻者們按着這個模板提issue;

  2. 有兩種方式建立issue模板:

    • 經過github建立:help.github.com/articles/cr…/

    • 第二種手動建立一個issue模板:help.github.com/articles/ma…/

      示例:

      (1)在項目中,新增一個bug模板和一個feature模板文件:

      其中bug_request模板的內容以下:

      (2)此後,貢獻則在github中打開issue可看到對應模板選項:

      選擇feature request,即可根據要求填寫:

    • 必需要在默認分支中建立issue模板。

對於貢獻者

  1. 在new一個pull request以前,最好的作法是先提出一個issue,供你們討論;

  2. 請在issue中參照issue規範,提供足夠多的信息來幫助別人理解;

  3. 請爲本身的issue添加對應的標籤,以即可以方便對issues進行分類和過濾:

    • Assigns是受委託人——負責推動issue的人;

    • 一個issues能夠有多個Label;

    • Milstone對應於項目,功能或時間段的issue組:好比版本號,具體截止時間,重構新功能等。

  4. 能夠對提交的issue進行訂閱,得知issue的推動狀況:

6. 生成一個新分支

  1. 建議貢獻者建立一個本身的新分支,在該分支上進行操做,最後經過pull request方式合併到主分支上。

git checkout -b feature_x //不加-b則是切換到某一分支上,加上-b就是建立且切換複製代碼
  1. 最後push的時候,要使用:

    git push --set-upstream origin <分支名>複製代碼

    將新分支提交到遠程倉庫中。

    若是上游倉庫也須要創建這個分支,這可使用:

    git push --set-upstream <remote> <分支名>複製代碼

7. 提交commit信息

在對項目做出更改後,咱們須要生成commit來記錄本身的更改。如下是Angular對commit格式的規範:

(1) 格式

提交信息包括三個部分:HeaderBodyFooter

<Header>
​
<Body>
​
<Footer>複製代碼

其中,Header 是必需的,Body 和 Footer 能夠省略。

1> Header

Header部分只有一行,包括倆個字段:type(必需)和subject(必需)。

<type>: <subject>複製代碼

type

type用於說明 commit 的類別,可使用以下類別:

  • feat:新功能(feature)

  • fix:修補bug

  • doc:文檔(documentation)

  • style: 格式(不影響代碼運行的變更)

  • refactor:重構(即不是新增功能,也不是修改bug的代碼變更)

  • test:增長測試

  • chore:構建過程或輔助工具的變更

subject

subject是 commit 目的的簡短描述。

  • 以動詞開頭,使用第一人稱如今時,好比改變,而不是改變了。

  • 結尾不加句號(。)

2> Body

Body 部分是對本次 commit 的詳細描述,能夠分紅多行。下面是一個範例。

More detailed explanatory text, if necessary.  Wrap it to 
about 72 characters or so. 
​
Further paragraphs come after blank lines.
​
- Bullet points are okay, too
- Use a hanging indent複製代碼

注意:應該說明代碼變更的動機,以及與之前行爲的對比。

3> Footer

​ Footer 部分應該包含:(1)Breaking Changes; (2)關閉issue;

Breaking Changes

​ 若是當前代碼與上一個版本不兼容,則 Footer 部分以BREAKING CHANGE開頭,後面是對變更的描述、以及變更理由和遷移方法。這種使用較少,瞭解便可。

Issue部分:

  • 經過commit關聯issue:

    若是當前提交信息關聯了某個issue,那麼能夠在 Footer 部分關聯這個 issue:

    issue #2複製代碼

  • 經過commit關閉issue,當提交到默認分支時,提交信息裏可使用 fix/fixes/fixed , close/closes/closed 或者 resolve/resolves/resolved等關鍵詞,後面再跟上Issue號,這樣就會關閉這個Issue:

Closes #1複製代碼

​ 注意,若是不是提交到默認分支,那麼並不能關閉這個issue,可是在這個issue下面會顯示相關的信息表示曾經想要關閉這個issue,當這個分支合併到默認分支時,就能夠關閉這個issue了。

​ 以下圖所示,爲向默認分支提交關閉issue的commit:

​ 而在別的分支想要關閉時:

4> 例子

下面是一個完整的例子:

feat: 添加了分享功能
​
給每篇博文添加了分享功能
​
- 添加分享到微博功能
- 添加分享到微信功能
- 添加分享到朋友圈功能
​
Issue #1, #2
Closes #1複製代碼

上面的提交信息應該可以解釋本身的意思了。

8. 整合commit信息,保持commit信息的乾淨度

(1) 經過git rebase -i清洗commit記錄

咱們能夠經過rebase -i完成如下目的:

  • 編輯之前的commit信息;

  • 將多個commit信息整合到一個;

  • 刪除commit信息。

注意這些commit都是還未被push的信息;

使用rebase -i進入交互模式

rebase 有6個選項能夠選擇:

  • pick : pick意味着採用該commit;

  • reword:reword選項能夠修改commit信息;

  • edit:能夠修改commit的提交信息,不一樣於reword,這個選項能夠暫停rebase過程,使得你能夠添加更多的commit信息,這容許您將大型提交拆分爲較小的提交,或者刪除提交中所作的錯誤更改;

  • squash:此命令容許您將兩個或多個提交組合到一個提交中。提交被壓縮到它上面的提交中。 Git讓您有機會編寫描述這兩個更改的新提交消息。

  • fixup:這與squash相似,但要合併的提交會丟棄其消息。提交只是簡單地合併到它上面的提交中,而且先前的提交消息用於描述這兩個更改。

  • exec:這容許您針對提交運行任意shell命令。

例子講解

如下是一個squash的示例:

如圖,有三個commit記錄:

執行git rebase -i

進入編輯界面,若是咱們是想要合併兩個commit記錄則能夠進行以下編輯:

commit記錄已經變爲:

(2) 撤銷rebase 操做

  1. 執行git reflog找到commit ID;

    • reflog能夠查看從本地倉庫建立之日起,本地所進行的與項目更改有關的操做,好比說commit,clone,rebase等操做。git log是查看當前版本庫及其以前的全部commit。

    • git reflog默認實際上是git reflog show Head;可使用git reflog show --all來查看全部分支的狀況;

  2. 執行git reset --hard <commit ID>;

(3) 回退到某一commit狀態

當想撤回某一commit記錄時,能夠採用回退的方式,可是注意這種方式也將使你的後續更改丟失。

  1. 執行git log命令,查看commit記錄:

    如上圖,能夠看到commit的哈希值;

    若是增長--pretty=oneline參數,則能夠只顯示版本號和提交時的備註信息。

  2. 執行git reset --hard commit_id

    例如咱們須要回退到新增MVC模式的上一個版本,則執行:

    git reset a5f2a27f02d32b666e01c24ed2218598db57a183 //此爲默認方式,不帶任何參數的git reset它回退到某個版本,只保留源碼,回退commit和index信息複製代碼

    若是是--hard參數,則完全回退到某個版本,本地工做區也會變爲上一個版本的內容:

    git reset --hard a5f2a27f02d32b666e01c24ed2218598db57a183複製代碼

    若是是--soft參數,會保留工做區和暫存區的記錄,在下次能夠直接commit:

    git reset --soft a5f2a27f02d32b666e01c24ed2218598db57a183複製代碼

    這種狀況下在push時,要執行:

    git push --force 複製代碼

9. Push到遠程倉庫

  1. 在push以前,應該再pull一次上游倉庫,將本地commit與遠程commit對比,若是遠程倉庫已經有個新的更新,而且與本地倉庫產生衝突,那麼就須要先解決衝突,接着在git add && git commit;

10. new 一個 pull request

  1. 在本身的項目中new 一個 pull request,選定哪個分支要合併到哪個分支:

  1. 選擇審閱者,委託人,標籤等信息;

11. 審閱者進行審閱

  1. 若是新增代碼不須要運行,審閱者審閱後可進行是否merge的評定;

  2. 代碼審閱者能夠將該pull request的來源倉庫設爲上游倉庫,拉取被審閱的代碼,再運行,以運行結果斷定是否merge;

  3. 有三個merge行爲,可根據具體狀況選擇:

其餘狀況

  1. 丟棄本地全部修改(已經commit);

    git reset Head^   //可加參數--hard或者--soft 複製代碼

  2. 取消已經暫存的文件,即,撤銷先前"git add"的操做

    git reset Head 複製代碼

    (未被追蹤的文件不會獲得更改,也就是沒有執行git add的文件)

  3. 將本地狀態回退到和遠程的同樣:

    git fetch origin/master
    git reset origin/master //可加參數--hard或者--soft複製代碼

  4. 查看某次commit記錄具體內容:

    git show <commit ID> 
    //也能夠用
    git show Head^^複製代碼

  5. cherry-pick

    cherry-pick 就是挑選一個咱們須要的 commit 進行操做。它能夠用於將在其餘分支上的 commit 修改,移植到當前的分支,可是移植的只是一個副本,會生成一個新的commit記錄。

    1.切換到 develop 分支。
    2.經過 git log,找到 C 的 SHA1 值。
    3.經過 git cherry-pick <C的SHA1> ,將 C 的修改內容合併到當前內容分支 develop 中。
    4.若無衝突,過程就已經完成了。若是有衝突,按正常衝突解決流程便可。複製代碼

    關於cherry-pick的其餘操做能夠查看後面給出的參考連接。

  6. 使用changlog打印commit信息(前提是按照angular規範書寫commit信息)

    npm install -g conventional-changelog-cli //安裝全局包;
    conventional-changelog -p angular -i CHANGELOG.md -s -r 0 //第一次使用時,執行此命令,會生成一個CHANGELOG.md文件
    conventional-changelog -p angular -i CHANGELOG.md -s  //以上生成的更改日誌基於自上一個semver(語義化版本)標記以來的提交。複製代碼

    通常在發包(release)的時候打印changlog信息,changelog其實是release的一個步驟之一。

  1. 更多操做指令請查看另外一篇git經常使用命令文檔。

參考連接

pr:www.thinkful.com/learn/githu…

commit&changelog規範:www.ruanyifeng.com/blog/2016/0…

angular規範:docs.google.com/document/d/…#

github issue API:developer.github.com/v3/issues/#…

git reflog:www.atlassian.com/git/tutoria…

git rebase : help.github.com/articles/ab…/

www.cnblogs.com/dracohan/p/…

issue模板:github.com/devOpenDoce…

commit中的issue:help.github.com/articles/cl…/

changelog:www.npmjs.com/package/con…

約定式提交:conventionalcommits.org/lang/zh-Han…

Cherry-pick:blog.csdn.net/qq_32452623…

相關文章
相關標籤/搜索