LoginSignup
1433

More than 3 years have passed since last update.

GitHubでFork/cloneしたリポジトリを本家リポジトリに追従する

Last updated at Posted at 2013-04-11
  • 2019/12/11
    • 分かりやすいサイトへのリンクを追加しました
    • hub コマンドの hub fork について追加しました
  • 2013/04/11
    • 興味深い手法があれば随時追加していきます

ネットを検索すると、色々な手法が出てきますが、自分としては「WEB+DB PRESS plus 開発ツール徹底攻略」p.71 に載っていた以下の手法がシンプルで良く理解できました。

本家リモート upstream を追加する方法

本家リポジトリの例として、実際にGitHubに存在する練習用リポジトリ git@github.com:DQNEO/Renshu.git を使います

あなた (youraccount) が既にForkしているRenshuリポジトリをcloneします。

$ git clone git@github.com:youraccount/Renshu.git
Cloning into 'Renshu'...
remote: Counting objects: 109, done.
remote: Compressing objects: 100% (70/70), done.
remote: Total 109 (delta 15), reused 109 (delta 15)
Receiving objects: 100% (109/109), 12.34 KiB, done.
Resolving deltas: 100% (15/15), done.    
$ cd Renshu

ブランチは以下のような状態になっているはずです (他にもあるかもしれません)。

$ git branch -a 
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

リモートリポジトリとして、オリジナルのリポジトリを upstream という名前で設定します。

$ git remote add upstream git://github.com/DQNEO/Renshu.git

以後、このリポジトリは upstream という名前で本家リポジトリを参照します。

ブランチを確認すると、以下のように remotes/upstream/master が加わったことが分かります。出てこない場合には git fetch upstream を試した後に再度 git branch -a で確認してみてください。

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/upstream/master

本家リポジトリの変更を取り出すためには fetchmerge の手順を取ります。

まずfetch

$ git fetch upstream
remote: Counting objects: 1, done.
remote: Total 1 (delta 0), reused 1 (delta 0)
Unpacking objects: 100% (1/1), done.
From git://github.com/DQNEO/Renshu
 * [new branch]      develop    -> upstream/develop
 * [new branch]      master     -> upstream/master

カレントブランチを master にして、upstream/master を merge。

$ git checkout master
Already on 'master'
Your branch is up to date with 'origin/master'.

$ git merge upstream/master
Updating fe579f8..a1e70ae
Fast-forward

変更が無い場合には "Already up-to-date." と表示されて終わりです。今回は差分があったので、コミットIDがfe579f8からa1e70aeまでの差分がmergeされました。

詳細は当該書籍を参照ください。

hub コマンドの hub fork

GitHub 独自の操作を行うことができる hub コマンド があります。Qiita にも hub コマンドについて紹介した記事が多くありますので hub タグのページなどから探してみましょう。

hub コマンドは git のサブコマンドを指定された場合は git と同じ動作をする(git に処理を依頼する)ので、git の alias として hub を指定することで、あたかも git コマンドが GitHub 独自操作を行うサブコマンドを搭載したかのようになります。しかし、この記事では hub コマンド独自の操作は hub コマンドを明示的に書くことにします。また、hub コマンドで GitHub へのログインを求められた場合には、画面に表示された指示通りにログイン処理を行って下さい。

興味あるリポジトリを clone します。普段通り git clone してもいいですが、せっかく hub コマンドがあるので、拡張された hub clone サブコマンドで簡単に GitHub リポジトリを指定して clone してみましょう。

$ hub clone plack/Plack
Cloning into 'Plack'...
remote: Enumerating objects: 15, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 14715 (delta 6), reused 7 (delta 0), pack-reused 14700
Receiving objects: 100% (14715/14715), 5.17 MiB | 566.00 KiB/s, done.
Resolving deltas: 100% (8210/8210), done.

作成されたワーキングディレクトリに入ります。合わせて git remote -v で、origin が登録されていることを確認してみます。

$ cd Plack/

$ git remote -v
origin  git://github.com/plack/Plack.git (fetch)
origin  git://github.com/plack/Plack.git (push)

このディレクトリ内で、hub fork を打つことで GitHub 上で fork が行われます。

$ hub fork
Updating xtetsuji
From git://github.com/plack/Plack
 * [new branch]      builder-interface            -> xtetsuji/builder-interface
 * [new branch]      code-badges                  -> xtetsuji/code-badges
 * [new branch]      conditionalget-fix           -> xtetsuji/conditionalget-fix
(----------- 中略 -----------)
 * [new branch]      travis-devel                 -> xtetsuji/travis-devel
 * [new branch]      un-http-body                 -> xtetsuji/un-http-body
 * [new branch]      wide-strings-check           -> xtetsuji/wide-strings-check
new remote: xtetsuji

fork を行うだけでなく、このリポジトリに自分のユーザ名(以下の例では xtetsuji)の新たなリモートが登録されます。

$ git remote -v
origin  git://github.com/plack/Plack.git (fetch)
origin  git://github.com/plack/Plack.git (push)
xtetsuji        git@github.com:xtetsuji/Plack.git (fetch)
xtetsuji        git@github.com:xtetsuji/Plack.git (push)

今回はリモート origin が第三者のリポジトリとなったので、いつも通り git fetch と master がカレントブランチの状態と git pull をすれば良いことになります。

前出の upstream を追加する方法との違いをまとめてみましょう。

upstream 手動追加 hub fork
必要なコマンド git git と hub
clone するもの GitHub Web上で自分のアカウントに fork しておいたもの 興味ある第三者のリポジトリ
fork GitHub ウェブ画面などで事前に行っておく hub fork で行う
リモート origin fork した自分のリポジトリ 第三者のリポジトリ (readonly)
リモート upstream 手動で追加した第三者のリポジトリ (readonly) -
リモート youraccount - hub fork が追加する
ブランチの push 先 origin youraccount
第三者のリポジトリに追従する merge の方向 upstream/master → master 普段の fetch と pull で OK

分かりやすいサイト

「自分は今までの説明を読んで分かるけれど、初学者や後輩にどう教えれば…」という場合、このことを書いた分かりやすいサイトは他にもあるので探してみると良いでしょう。

特にマンガで解説した以下のサイトは初学者でも分かりやすそうです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1433