株式会社ネットワールドのエンジニアがお届けする技術情報ブログです。
各製品のエキスパートたちが旬なトピックをご紹介します。

GitとCI/CDに関する知識ゼロのSEが、クローンとフォークの違いを少しだけ理解する話

皆様こんにちは。SEの小池と申します。

突然ですが、皆さまはGitにおけるクローンとフォークの違いをご存じですか?

今回のブログは、Gitのクローンとフォークの違いについて です。

既にクローンとフォークの違いを説明する技術ブログなどはたくさんありますが、それでも良くわからない・・・という方の手助けになれば幸いです。

本記事の対象の方

  • Gitにおいて、クローンとフォークの違いを調べていらっしゃる方。

今回のブログのゴール

このブログのゴールはこちらです。


今回のゴール
  • Gitにおけるクローンとフォークの違いを、少しだけ理解する。

事前ご連絡事項

  • 本記事は筆者の独断と偏見に基づき、クローンとフォークの概要を説明しています。この記事は各機能の詳細な説明ではなく、あくまでも筆者独自の表現による概要の説明に過ぎないことをご了承ください。
  • 本記事に掲載されている情報は正確性・安全性を保証するものではありません。本記事の情報を利用することによって発生した損失や損害については、一切の責任を負いかねます。
  • 本記事は2023/06/27時点の情報です。それ以降に本書で言及している各種プロダクトで発生した仕様の変更については反映しておりません。

【前段①】なぜ git fork コマンドは存在しないのか?

このブログをご参照いただいている方ならもうご存じかと存じますが、gitコマンドにはgit cloneはありますが、git forkはありません。

では、なぜgit forkコマンドは存在しないのでしょうか?

これは、フォークの処理内容はリモートリポジトリ機能を提供するプラットフォーム(例 : GitHub, GitLab, Bitbucket 等)に依存しているためです。

プラットフォーム毎にフォークの作成方法が異なるため、gitコマンドにgit forkは存在しません。

参考 : Forking Workflow | Atlassian Git Tutorial

【前段②】なぜフォーク先はフォーク元と同じプラットフォームに限定されるのか?

GitHub, GitLab, Bitbucketをお使いの皆様は、フォーク先にはフォーク元と同じプラットフォームしか選択できないということをご存じでしょうか。

これは前章で述べた通り、フォークの処理内容がプラットフォームに依存するため、このような仕様になっているのだと推測されます。

もしよろしければ、実際に皆さまが日常的にお使いのリモートリポジトリでフォークをお試しください。
フォーク先を指定する際、フォーク先は同じプラットフォームに限定されていませんか?

GitHubの場合・・・フォーク先はGitHubしか選択できません。

GitLabの場合・・・フォーク先はGitLabしか選択できません。

Bitbucketの場合・・・フォーク先はBitbucketしか選択できません。

上記のように、GitHub, GitLab, Bitbucket の場合はフォーク先にはフォーク元と同じプラットフォームしか選択できません。

一方、クローンの場合はクローン元のプラットフォームに依存することなく、クローン先を指定できます
クローン元がGitHubでクローン先がGitLabでも構いませんし、クローン元がBitbucketでクローン先がローカルリポジトリでも構いません。また、クローン元とクローン先が同じプラットフォームでも構いません。

【前段③】わざわざフォークしなくてもクローンでOKなケース

ここまでの情報だと、「別にフォークじゃなくてクローンでよいのでは・・・?」となるかと存じます。

確かに、一般公開されている任意のリモートリポジトリをローカルにコピーしたいだけならば、フォークを使わずに、直接ローカルリポジトリにクローンしたほうが早いように思います。

また、フォーク元と同じプラットフォームにある、自分の個人用リポジトリにコピーしたいだけならば、クローンでもフォークでも目的は達成できます。

この様に、一般公開されているリポジトリをコピーしたいだけならば、クローンで事足ります。

【本題】クローンではできず、フォークでできることとは?

前段が長くてすみませんでした。ここから本題です。
クローンでは実現できず、フォークを使うと実現できることとは何でしょうか?

それは、一般公開されているリポジトリに対して、誰でも改善を提案し、プルリクエスト(GitLabではマージリクエスト)を作成できることです。

要は、コピー元のリポジトリに書き込み権限がない状況で貢献をしたい場合は、クローンよりフォークのほうが便利です。

具体的にはフォークを用いて以下の処理をすることで、一般公開されているリポジトリに対して改善や修正の提案が可能となります!

  1. 一般公開されているプロジェクトのリモートリポジトリを、個人用のリモートリポジトリにフォークする。
  2. 個人用のリモートリポジトリに変更をコミットする (下図②) 。
    もしくは、個人用のリモートリポジトリからローカルにクローンし、ローカルで変更をコミットし、個人用リモートリポジトリにプッシュする (下図②'のルート) 。
  3. 一般公開されているプロジェクトのリモートリポジトリに対し、個人用のリモートリポジトリに反映した変更のプルリクエスト (GitLabならマージリクエスト) を作成する。
  4. 一般公開されているプロジェクトのリモートリポジトリの管理者は、3.で作成されたプルリクエスト (またはマージリクエスト) の内容をチェックし、問題が無ければマージする。

2023/06/27時点の GitHub, GitLab, Bitbucket では、少なくとも上記と同じ方法をクローンで実施することはできません
(なんやかんやすれば最終的に上記の 4. に至ることは不可能ではないかもしれませんが、上記と全く同じ方法では実施できません。)

なぜなら通常、一般公開されているリポジトリに対して、そのリポジトリ (プラットフォームによってはグループ, プロジェクト や 組織) に所属していない不特定多数のユーザーは、プッシュする権限がないからです。

参考 : What is the Difference between Git Clone and Git Fork?

【検証】GitHub, GitLab, Bitbucket でフォークとクローンの違いを確認

Git素人の筆者が実際に以下の検証を実施致しました。

検証目的

GitHub, GitLab (SaaS版) , Bitbucket (クラウド版) において、一般公開されているリポジトリを以下の2つのパターンで自分用のリモートリポジトリにコピーし、コピー元のリポジトリに提案 (プルリクエスト や マージリクエスト) が可能なのかを確認する。
  • クローンでコピーする。
  • フォークでコピーする。

【前提】
  • 全ての操作はGUIから実施する。
  • 操作者はコピー元のリポジトリのメンバーではない。
  • 【検証準備】
    1. 一般公開されている任意のリポジトリ "repo-A" を、同プラットフォーム上の自分用リモートリポジトリに "repo-A-fork" としてフォークする。
    2. 一般公開されている任意のリポジトリ "repo-A" を、同プラットフォーム上の自分用リモートリポジトリに "repo-A-clone" としてクローンする。
    3. 自分用リモートリポジトリの "repo-A-fork" と "repo-A-clone" に、同じ変更を加えてコミットする。

    【検証項目】
    1. 自分用リモートリポジトリの "repo-A-fork" をソースとし、一般公開されている任意のリポジトリ "repo-A" に対してプルリクエスト (GitLabの場合はマージリクエスト) を作成できるか。
    2. 自分用リモートリポジトリの "repo-A-clone" をソースとし、一般公開されている任意のリポジトリ "repo-A" に対してプルリクエスト (GitLabの場合はマージリクエスト) を作成できるか。

    結果は以下の通りでした。
    (筆者は本当にGit素人であり、GUIから操作可能な全てを確認したわけではございません。実際の仕様はこの通りではない可能性がございますので、一意見としてご参照いただければと存じます。また、この検証では図の簡略化や文字数の関係上、ブランチに関する説明は割愛しております。)

    表1. 各プラットフォームにおける検証結果
    プラットフォーム ソース → マージ先
    repo-A-fork → repo-Arepo-A-clone → repo-A
    GitHub
    ○ (OK)
    × (NG)
    GitLab (Saas版)
    ○ (OK)
    × (NG)
    Bitbucket (クラウド版)
    ○ (OK)
    × (NG)

    想定通り、クローンでリポジトリをコピーした場合はコピー元のリポジトリに対してプルリクエスト (または マージリクエスト) を作成できず、フォークでリポジトリをコピーした場合はコピー元のリポジトリに対してプルリクエスト (または マージリクエスト) を作成できました。

    【おまけ】ユースケースで考えるフォーク+クローン or クローンのみの使い分け

    前章までの内容を踏まえて、開発経験ゼロの筆者が "任意のリモートリポジトリをローカルにコピーする際に フォーク+クローン と クローンのみ のどちらでコピーするか" について、そのケースを少し考えました。

    • フォーク+クローンでコピーするケース
      • 一般公開されているリポジトリに対して、自分なりの改善を提案して貢献したいとき。
      • 社内ルールでフォーク+クローンを用いてローカルにコピーすることが義務付けられている場合。
    • クローンでコピーするケース
      • 非公開の社内プロジェクトのメンバーであり、そのリポジトリに対して書き込みなどの十分な権限を持っているとき。
      • 一般公開されているリポジトリを、異なるプラットフォームにコピーしたいとき
      • コピーしたいリモートリポジトリにフォークの制限がかかっているとき。

    具体的なユースケースを考えると、クローンで事足りるならクローンで済ませるケースが多いように思います。

    フォークを使った方がよいケースは、コピー元プロジェクト (OSS 等) への貢献が目的の場合 など、限定的かもしれません。

    また、ここでは言及しませんでしたがどっちでもいいケースもあり、一概にこうだったらクローン!こうだったらフォーク+クローン!というような明確な指標を作るのは困難だと存じます。

    最後に

    この度はGitもCI/CDもよくわかっていないど素人SEによるGitLab検証ブログをお読みいただき、誠にありがとうございます。
    このブログの目標は以下のとおりでしたが、皆さまはいかがでしたでしょうか。


    今回のゴール
    • Gitにおけるクローンとフォークの違いを、少しだけ理解する。

    フォークを使用しなければならないケースは限定的で、開発プロジェクトの方針や環境によっては一度も使ったことが無い方もいらっしゃるかと存じます。
    筆者はフォーク≒クローンくらいの認識で、GitLabのドキュメントでフォークという単語が出てくるたびに、「フォーク…クローンとなんか同じようなものだった気がする。具体的な違いはよくわからないけれど…まあいいや…。」と、勉強を後回しにしておりました。とても恥ずかしい。

    実はGitLab 16.0でフォークに関する新機能 (主にGUI) が追加されたのですが、その機能を紹介する前段として、本記事を記載致しました次第です。 というか、クローンとフォークの違いをようやく自習し、それをまとめただけです。。

    この記事がGitのクローンとフォークの違いでお困りの方の一助となれば幸いにございます。


    GitLabに関するお問い合わせは、以下のフォームからお願い致します。
    GitLab製品 お問い合わせ

    今までのGitLabの検証ブログはこちらです。
    GitLab カテゴリーの記事一覧 - ネットワールド らぼ

    GitLab操作デモ動画 (基本編) を作ってみました。(音声の録音は自宅でiPhoneのボイスメモ使うという超低クオリティですが…。)
    つたない内容ではありますが、ご興味がおありでしたら是非ご視聴いただければと存じます。

    www.youtube.com