Pull Requestのおくりかた

BitVisorに修正を加えたらぜひpull requestを送りましょう。ここでは簡単な例を紹介します。

# Forkする

Bitbucketにログインし、BitVisorプロジェクトのページを開くと、ActionsのところにForkというのがありますのでそこを選びます。

bitvisor / bitvisor — Bitbucket
https://bitbucket.org/bitvisor/bitvisor

![bb-fork.png](https://qiita-image-store.s3.amazonaws.com/0/103733/5a1c23bb-6e17-d7ff-ce89-1b7ca3c1703f.png)

そして、名前を決め、privateなどの選択肢をお好みに応じて選択して [Fork repository] を選ぶと自分のアカウントにforkされます。

![bb-fork2.png](https://qiita-image-store.s3.amazonaws.com/0/103733/be71de55-a034-d18e-d6a0-bd7a551082d6.png)

## すでにfork済みの場合

すでにforkしてあった場合、それを最新版に更新 (同期) することができます。Fork済みのOverviewを見ると、Sync nowというリンクが表示されていますので、それを選びます。

![bb-sync2.png](https://qiita-image-store.s3.amazonaws.com/0/103733/8ed46a14-e556-921c-2791-6bb8bf29b0ac.png)

# Cloneする

Forkできたら、それを手元にhg cloneコマンドで持ってきます。アドレスはOverviewのページで確認します。プロトコルはSSHかHTTPSが選べます。お好きな方をお使いください。

![bb-clone.png](https://qiita-image-store.s3.amazonaws.com/0/103733/35c32be6-dfe8-ecd7-b6cb-d142c1c8bb0f.png)

# 修正を加えてcommitする

いろいろ修正を加えてcommitしましょう。Mercurialの通常の使い方で行えばOKですが、各リビジョンごとにコンパイル・実行が問題なく行えるようにすることと、全く関係のない修正が混じらないようにしましょう。例えば、以下の例ではSYSCFG関連の修正とINVPCID関連の修正が混ざっています。

```diff:悪い例
diff --git a/core/cache.c b/core/cache.c
--- a/core/cache.c
+++ b/core/cache.c
@@ -993,6 +993,9 @@ read_syscfg (void *arg)
 
        ret = arg;
        asm_rdmsr64 (MSR_AMD_SYSCFG, ret);
+       /* The SYSCFG is readable but not writable in QEMU/KVM VM.
+          Check whether it is writable to detect such environment. */
+       asm_wrmsr64 (MSR_AMD_SYSCFG, *ret);
 }
 
 static void
diff --git a/core/constants.h b/core/constants.h
--- a/core/constants.h
+++ b/core/constants.h
@@ -46,6 +46,7 @@
 #define CPUID_1_EDX_PAT_BIT            0x10000
 #define CPUID_4_EAX_NUMOFTHREADS_MASK  0x03FFC000
 #define CPUID_4_EAX_NUMOFCORES_MASK    0xFC000000
+#define CPUID_7_EBX_INVPCID_BIT                0x400
 #define CPUID_EXT_0                    0x80000000
 #define CPUID_EXT_1                    0x80000001
 #define CPUID_EXT_1_ECX_SVM_BIT                0x4
diff --git a/core/cpuid_pass.c b/core/cpuid_pass.c
--- a/core/cpuid_pass.c
+++ b/core/cpuid_pass.c
@@ -51,6 +51,8 @@ do_cpuid_pass (u32 ia, u32 ic, u32 *oa, 
        } else if (tmpa >= 4 && ia == 4) {
                /* *oa &= ~CPUID_4_EAX_NUMOFTHREADS_MASK; */
                /* *oa &= ~CPUID_4_EAX_NUMOFCORES_MASK; */
+       } else if (tmpa >= 7 && ia == 7 && ic == 0) {
+               *ob &= ~CPUID_7_EBX_INVPCID_BIT;
        } else if (tmpa >= 0xD && ia == 0xD && ic == 0) {
                /* Processor Extended State Enumeration Leaf */
                /* see xsetbv_pass.c */
```

この場合は別々の2つのリビジョンにします。hg recordやhg qrecordなどのコマンドを使います。私はmqが大好きなのでqrecordを使い、きれいな単位に整えてから、qpop/qpushとqrefreshでコミットメッセージを入れていき、いい感じになったところでqfinishしています。以下に操作例を示します。

```shell-session:
$ hg qrecord fix-pcid
diff --git a/core/cache.c b/core/cache.c
1 個の差分、 3 行の変更
'core/cache.c' の変更点を調べますか？ [Ynesfdaq?] n
diff --git a/core/constants.h b/core/constants.h
1 個の差分、 1 行の変更
'core/constants.h' の変更点を調べますか？ [Ynesfdaq?] a
$ hg qnew syscfg-workaround
$ hg qpop
syscfg-workaround の適用解除
適用中の最上位パッチは fix-pcid です
$ hg qref -m 'cpuid_pass: conceal INVPCID instruction
> 
> INVPCID is used by recent Linux if available.  Previously PCID was
> properly concealed but INVPCID was not.  Therefore the recent Linux
> crashed when it used INVPCID.'
$ hg qpush
syscfg-workaround を適用中
適用中の最上位パッチは syscfg-workaround です
$ hg qref -m 'cache: check whether SYSCFG MSR is writable'
$ hg log -vp | less
$ hg qfin -a
```

# Pushする

いい感じにcommitできたら、hg pushコマンドでBitbucketにpushします。push先はforkした自分のプロジェクトです。PushしたらBitbucketのページでもよく確認しましょう。

```shell-session:
$ hg push
https://bitbucket.org/hdk_2/bitvisor への反映中
変更点を探索中
https://bitbucket.org/hdk_2/bitvisor は HTTP 認証が必要です
認証領域(realm): Bitbucket.org HTTP
ユーザ: hdk_2
パスワード: 
連携先: adding changesets
連携先: adding manifests
連携先: adding file changes
連携先: added 2 changesets with 3 changes to 3 files
```

間違いを見つけたら直しましょう。自分のforkですから、他の人がcloneしていないなら、stripなり何なりして修正しまくって良いのです。とにかく綺麗にしましょう。

たぶん、過去のミスを放っておいてマルチヘッドにしてもpull requestに支障はなかったのではないかと思います。

# Pull Requestを出す

ForkしたプロジェクトのページからPull requestsを選びます。

![bb-pr.png](https://qiita-image-store.s3.amazonaws.com/0/103733/07de02a4-1c6b-c8ec-88d5-a108527f949a.png)

[Create a pull request] を選ぶと、自分のプロジェクトからfork元のプロジェクトへのpull requestの情報を入力する画面が出てきますので、もろもろ入力して [Create pull request] を選びます。

![bb-pr2.png](https://qiita-image-store.s3.amazonaws.com/0/103733/848674d8-17de-8292-f2f1-4c3d22e1f87e.png)

これでpull requestの作成は完了です。後はレビューが行われて取り込まれたり、もうちょっと直してねとなったりするのではないかと思います。

# Mergeされる

Mergeされると表示がMERGEDになります。

![bb-merge.png](https://qiita-image-store.s3.amazonaws.com/0/103733/dcba1a43-39c3-f00f-911b-3742d5f8ecb1.png)

# 補足

Mercurialにはブランチという機能がありますが、BitVisorではdefaultブランチしか使用していません。Mercurialのブランチ名は、commit時にリビジョンに残り、ブランチを閉鎖してもその名前はlogから消えることがありません。Pull requestを行う場合defaultブランチを使用してください。

ご存知とは思いますが、Gitをご愛用の方向けに補足しておくと、GitのブランチにあたるものはMercurialではブックマークになります。Gitではブランチが指すcommitから親commitをたどることで歴史をさかのぼっていきますが、Mercurialではリポジトリにpullされたすべてのリビジョンを親子関係に関わらずたどることができますので、作業対象のリビジョンに名前をつける必要がありません。子のいないリビジョンはヘッドと呼ばれます。複数の人による異なる変更をpullしたり、子のいるリビジョンにcommitしたりするとヘッドが複数となり、マルチヘッドという状態になります。

コーディングスタイルについては以下の記事を参照してみてください。

BitVisorのコーディングスタイル
http://qiita.com/hdk_2/items/3c74c2f166c83db17c87