[GitHub] hub pull-requestの宛先がフォーク元のリポジトリにならない場合の対処法
GitHubの公式コマンドラインツールであるhubの存在を知り、最近使い始めている。いろいろな作業がコマンドからできてとても便利なのだが、フォーク元のリポジトリにプルリクエストを送るところで詰まってしまった。フォーク元のリポジトリを parent/repo
、フォークして作られたリポジトリを child/repo
としたとき、parentのmasterブランチ(parent:master
)にプルリクエストを送りたかったのだが、 hub pull-request
としたときのプルリクエストの宛先が child:master
になってしまった。
hub forkをしておくことが必要
この原因は、hub fork
をしていなかったことにある。今回の場合、GitHubの画面上でリポジトリをフォークし、作成されたchild/repo
をgit clone
して使っていたところで、hubについて知り使い始めた。しかしドキュメントの使用例では、フォークの段階からhub fork
を使うことが前提になっている。フォーク元のリポジトリを parent/repo
、フォークして作られたリポジトリを child/repo
としたとき、以下のような流れで使う。
$ hub clone parent/repo //まずフォーク元をclone $ cd repo $ git checkout -b feature $ git commit -m "done with feature" //何か変更を加えてコミット $ hub fork --remote-name=origin //ここでフォーク $ git push origin feature $ hub pull-request
このとき、 hub fork --remote-name=origin
は、リモートリポジトリを以下のように変更する。 --remote-name=origin
の指定があることで、origin
がchild/repo
を指すようになり、parent/repo
はupstream
という名前になる。
$ git remote -v origin git@github.com:child/repo.git (fetch) origin git@github.com:child/repo.git (push) upstream https://github.com/parent/repo (fetch) upstream https://github.com/parent/repo (push)
そして、hubはプルリクエストを送る際の宛先となるリモートリポジトリの指定がない場合、upstream -> github -> origin
という優先順位でリモートリポジトリを探し、見つかった場合はそこを宛先とする。((https://hub.github.com/hub.1.html のCONVENTION
の項目を参照。))このため、 事前にhub fork
した状態で hub pull-request
とすれば、宛先はupstream
という名前で登録されているparent/repo
のmasterブランチとなる。
既にフォークしたリポジトリでhubを使うには
今回は既にフォークしたリポジトリをgit clone
してきたため、リモートリポジトリは以下のようになっていた。origin
という名前のものしかないため、プルリクエストの宛先がchild/repo
のmasterブランチになるのも当然である。
$ git remote -v origin git@github.com:child/repo.git (fetch) origin git@github.com:child/repo.git (push)
これを回避するには、プルリクエストを送る際に以下のようなオプションをつける。-b
が宛先のブランチ、-h
が変更を加えたブランチを表す。remoteにparent/repo
が登録されていなくても、hubコマンドがGitHubを探索してくれる。
$ hub pull-request -b parent:master -h child:feature
しかし、これから何度もプルリクエストを送るのであれば、hub fork
と同様に、フォーク元のリポジトリをupstream
という名前でリモートリポジトリに登録してしまうのが良いだろう。これでオプションの指定なしでhub pull-request
が使えるようになる。
$ git remote add upstream https://github.com/parent/repo.git $ git remote -v origin https://github.com/child/repo.git (fetch) origin https://github.com/child/repo.git (push) upstream https://github.com/parent/repo.git (fetch) upstream https://github.com/parent/repo.git (push)