Git リポジトリ間のマージについて

Git
この記事は約6分で読めます。
記事内に広告が含まれています。

本記事ではリポジトリマージの手順について載せていきます。

こんなマージです!

また、「GitHub.com」でForkを利用した場合のリポジトリ間マージについても触れていきます。

以下、目次です。

リポジトリ間のマージ

前提条件とパターン

リポジトリの前提条件は次の通りです。

  • リポジトリA(オリジナル)
  • リポジトリB(複製)

今回は、次のパターンを想定しています。

  • B ← A(BにAの内容をマージする)
  • A ← B(AにBの内容をマージする)

※リポジトリBは次のいずれかの手順で作成可能です。

  1. リポジトリAをFork(GitHub利用)
  2. リポジトリAをClone後に新規リポジトリBとして登録

コマンドで試します

リポジトリ間マージ:B ← A

  • リポジトリBはクローンしておきます。
  • リポジトリAは何かしら変更しておきます。

→ リポジトリAの変更を取り込んでいきましょう。

# リポジトリBに移動
cd repoB

# 取込元にAを追加して確認
git remote add upstream https://github.com/xxxx/RepoA.git
git remote -v

# 取込実施&マージ
git fetch upstream
git merge upstream/main

# リポジトリB(リモート)に反映
git push

※マージの際にコンフリクトがある場合は通常のブランチ間マージのように対応が必要です。

リポジトリ間マージ:A ← B

方向を逆にするだけで同じように実施出来ます。

  • リポジトリAはクローンしておきます。
  • リポジトリBは何かしら変更しておきます。
# リポジトリAに移動
cd repoA

# 取込元にBを追加して確認
git remote add downstream https://github.com/xxxx/RepoB.git
git remote -v

# 取込実施&マージ
git fetch downstream
git merge downstream/main

# リポジトリA(リモート)に反映
git push

GitHub.com上の場合

続いて、GitHub.com上だけでリポジトリ間のマージについて調べます。

リポジトリの前提条件は次の通りです。

  • リポジトリA
  • リポジトリB(リポジトリAをFork)

GitHubの場合:B ← A

次の画像はForkしたリポジトリです。

それぞれのリポジトリで変更した状態ですが、Forkしたリポジトリでは「ahead」「behind」「Sync fork」といった項目があります。

  • ahead:fork先(下流)の変更量
  • behind:fork元(上流)の変更量
  • Sync fork:上流→下流に同期

Sync forkで上流の変更を取り込む場合、次のような画面になります。

↑の場合は、Fork先で特に変更もないので単純に取込が出来ます。

続いての場合、Fork先で変更があって自動的にマージ出来ない場合は「Sync fork」において「Discard」という選択しか取れません。

この選択の場合、fork先の変更を破棄(内部的にはgit reset –hard)が行われ、上流の取り込みが行われます。

廃棄したくない・・・。

pull requestの選択肢が残されているよ。

xx commits aheadだったり、xx commits behindをクリックすると、リポジトリ間のpull requestになって、反映作業を進めることが出来ます。

ところでDiscardを選択した場合、Fork先での変更は簡単に破棄出来てしまいます(Write以上の権限)。現状の仕様なのか不具合なのかわかりませんが、ブランチ保護ルールで強制push(push -f)を禁止していても、破棄出来てしまいます。うっかり操作して破棄ってなったら、リモート側なので復旧が大変そうです。

GitHubの場合:A ← B

上流に対する変更は「pull request」を経由した反映となります(あくまでGitHub.com上の操作だけに限定した場合です)。

xx commits aheadだったり、xx commits behindをクリックすると、リポジトリ間のpull requestになります。この先は通常のブランチ間のpull request操作と同等です。

GitHubの場合のまとめ

GitHub.com上だけの操作において、リポジトリ間マージの選択肢は次の通りです。

パターン手順
B ← A
(自動マージ可)
Sync fork or
pull request
B ← A
(自動マージ不可)
pull request
A ← Bpull request

(参考) GitHubで新規リポジトリ作成(複製登録)

手元にローカルリポジトリがある状態で「git push」をしようとした場合、上手くいきません。例えば、git clone → remote url変更 → push という操作です。

remote: Repository not found.
fatal: repository 'https://github.com/xxxx/xxxx.git/' not found

GitHubのForkを使わないでリモートリポジトリを複製したいのよ。

権限(アクセストークン)を持っていてもこのようなエラーになります。sshならば解決出来るという記事を見たことがありますが、私はhttpsで実施したいのです。

解決方法は次の通りです。

  1. GitHubでリポジトリ登録
    → コンテンツ何も無しの未履歴で登録します。
  2. ローカルリポジトリの「remote set-url」を変更
    → git remote set-url –push origin <repository url>
  3. git push

最初にGitHubで枠を作らないとだめなようです。

(参考) ForkとCloneの違い

念のため、Cloneとの違いを書きます。

ForkClone
操作・リポジトリを自分のアカウントやOrganizationにコピー。・既存のリポジトリをローカルマシンにコピー。
目的・コントリビューションのための開発。・自分自身の開発や変更。
メリット・オリジナルのリポジトリを変更せずに独自の変更を加えられる。
・自分自身のアカウントで管理できる。
・リポジトリ全体をダウンロードして開発や変更ができる。
デメリット・オリジナルのリポジトリが更新された場合、手動で変更を取り込む必要がある。
・自分自身のリポジトリのメンテナンスが必要。
・オリジナルのリポジトリへの変更を行えない(PullRequest&Pushすれば可)。
・ローカルマシンのストレージを占有する可能性がある。

少々、雑な部分はありますが、主な違いはこの通りでしょうか。

なお、元々のリポジトリをベースにするが、切り離して新しく開発したいのであれば、Forkではなく、Clone → 新規リポジトリ登録という流れが自然です(必要に応じて登録前に履歴を圧縮することもある)。

まとめ

本記事ではリポジトリ間のマージについてご紹介しました。

  • コマンドを使う場合、remoteのurlを追加することでマージが可能です。
  • GitHubでForkを使う場合、Sync forkやリポジトリ間のpull request発行によってマージが可能です。

最後までご覧いただきありがとうございました。

コメント

Top
タイトルとURLをコピーしました