Git
PR

【Git】fork先リポジトリの最新化及び関連のないリポジトリの反映方法

Git Fork先リポジトリの最新化
コル
記事内に商品プロモーションを含む場合があります

[greeting]

システム開発をしているといくつかのチームに分かれて開発することがあります。
フレームワークチーム、基盤構築チーム、各業務別の開発チームなどですね。
僕もこのたびフレームワーク開発チームの現場に入り

  1. マイクロサービス開発用の基礎部分を開発したリポジトリ
  2. マイクロサービスの一機能(DBアクセスや分散トランザクションなど)を提供するリポジトリ
  3. 業務使用に合わせたサンプルリポジトリ

を作成することになりまして、1→2→3の順に親子関係を持ったfork作業が多々発生したため
「fork先リポジトリの最新化作業」を備忘録としてメモしておきます。

また環境の異なるAzure DevOpsのGitにリポジトリ移動が必要になったケースに立ち会いましたので、fork関係にないリポジトリのupstreamで反映する方法も載せておきます。

スポンサーリンク

全体構成

まず作業の前に作業の全体の簡略図を貼っておきます。
fork元、fork先がそれぞれリモートにあり、作業者のローカルに現在開発中のfork先リポジトリがあるだけです。

Gitのfork簡略図

今回は例としてAzure DevOpsでforkしてやっていきます。
Azure DevOpsでのfork方法に関して知りたいかたはAzureドキュメントの「フォーク」をご覧ください。

今回はそれぞれ下記のように
Fork元:AppBase
Fork先:AppRedis
としました。リポジトリの関連性に注力したので名称適当です、お気になさらず^^;

Forkのリポジトリ説明図

この状態でまずはFork元を変更します。

fork元の変更をコミット リモートへプッシュ

今回はわかりやすく下記のような新規クラス(Exceptionハンドリングクラス)を作成して変更しました。

fork元変更分

これをプッシュしてfork元を更新します。

fork元更新確認

fork元の変更を取り込む

fork元の変更を取り込んでいきます。全体図の①、②は前提として終わっているため
③から実行していきます。

Gitのfork簡略図

 

fork元のURLを追加(③git remote add upstream URL)

upstreamとしてfork元のURLを追加します。
まずはfork先リポジトリを開き、ブランチ情報を確認します。

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

今は自分のリモートとローカルのブランチしか見えません。ここでupstreamとしてURLの向き先を変更します。

git remote add upstream [fork元のURL]
例)git remote add upstream https://dev.azure.com/{OrganizationNama}/{ProjectName}/_git/{ReposName}

これでfork元のリポジトリが見えるようになりました。

fork元のブランチをフェッチ(④git fetch upstream)

この状態でブランチ情報を確認するとまだ見えません。そのためまずはフェッチします。

$ git fetch upstream
remote: Azure Repos
remote: Found 10 objects to send. (14 ms)
Unpacking objects: 100% (10/10), 1.01 KiB | 114.00 KiB/s, done.
From https://dev.azure.com/{OrganizationNama}/{ProjectName}/_git/AppBase
* [new branch] main -> upstream/main

ログに記載がありますが新規でブランチが作られたため、ブランチ情報を確認するとupstreamとして確認することができます。

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

upstreamをプルして変更を取込(⑤git pull upstream ブランチ名)

ブランチが見えるようになったため、upstreamから変更分を取り込みます。これ以降はGit使用者には直感的にわかる操作です。

$ git pull upstream main
From https://dev.azure.com/{OrganizationNama}/{ProjectName}/_git/AppBase
* branch main -> FETCH_HEAD
Updating c8ed5a2..f849815
Fast-forward
src/main/java/jp/techtekulife/appbase/exception/BaseControllerAdvice.java | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 src/main/java/jp/techtekulife/appbase/exception/BaseControllerAdvice.java

これでローカルのリポジトリにfork元の変更が取り込むことができました^^
あとはいつも通り変更分をプッシュすれば終了です。

関連のないリポジトリを取り込む方法

先ほどはfork関係にあるリポジトリを取り込む方法をご紹介しました。
しかし現場によっては2つの開発環境が存在し親子関係にないけれど、漏れがないようにコミット分を取り込みたい場合はあると思います(ユーザー企業A社の開発環境に、ベンダー企業B社の環境から移行する場合など)。実際僕はこのケースに立ち会ってしまいました^^;

そこで対応した方法を残しておきます。取込先をAnotherBase、取り込み元をAppBaseとします。

関連のないRepos取込

 

関連のないリポジトリの変更はエラーとなる

fork関係にある場合と同じようにフェッチ(④git fetch upstream)まではそのまま動作します。
しかしプルを行うと「fatal: refusing to merge unrelated histories」となります。

$ git pull upstream main
From https://dev.azure.com/{OrganizationNama}/{ProjectName}/_git/AppBase
* branch main -> FETCH_HEAD
fatal: refusing to merge unrelated histories

ここがfork関係にないために発生するエラーです。

回避策(refusing to merge unrelated histories)

対応策はpullを実行する際に「–allow-unrelated-histories」のオプションを付けることです。下記のように動作します。

$ git pull upstream main --allow-unrelated-histories
From https://dev.azure.com/{OrganizationNama}/{ProjectName}/_git/AppBase
* branch main -> FETCH_HEAD
Merge made by the 'recursive' strategy.
.gitignore | 37 ++++
build.gradle | 33 +++
gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59536 bytes
gradle/wrapper/gradle-wrapper.properties | 5 +
gradlew | 234 ++++++++++++++++++++++
gradlew.bat | 89 ++++++++
settings.gradle | 1 +
.../jp/techtekulife/appbase/AppbaseApplication.java | 13 ++
.../jp/techtekulife/appbase/ServletInitializer.java | 13 ++
.../application/controller/BaseController.java | 26 +++
.../appbase/application/model/ResponseData.java | 13 ++
.../appbase/exception/BaseControllerAdvice.java | 22 ++
src/main/resources/application.properties | 1 +
.../techtekulife/appbase/AppbaseApplicationTests.java | 13 ++
14 files changed, 500 insertions(+)
create mode 100644 .gitignore
create mode 100644 build.gradle
create mode 100644 gradle/wrapper/gradle-wrapper.jar
create mode 100644 gradle/wrapper/gradle-wrapper.properties
create mode 100755 gradlew
create mode 100644 gradlew.bat
create mode 100644 settings.gradle
create mode 100644 src/main/java/jp/techtekulife/appbase/AppbaseApplication.java
create mode 100644 src/main/java/jp/techtekulife/appbase/ServletInitializer.java
create mode 100644 src/main/java/jp/techtekulife/appbase/application/controller/BaseController.java
create mode 100644 src/main/java/jp/techtekulife/appbase/application/model/ResponseData.java
create mode 100644 src/main/java/jp/techtekulife/appbase/exception/BaseControllerAdvice.java
create mode 100644 src/main/resources/application.properties
create mode 100644 src/test/java/jp/techtekulife/appbase/AppbaseApplicationTests.java

これで関連のないリポジトリを取り込むことができました^^

まとめ

今回はfork関連の最新化は終了です。

  • fork先リポジトリの最新化
  • 関連のないリポジトリの反映方法

について解説しました。現場によって開発環境は異なりますが、開発者である限り手動で移行するなどは必ず避けたいところです。forkが発生するプロジェクトの場合、基本的に別チームもしくは別会社の修正分の取込作業にて実施する必要性が出てくると思いますが、マージ漏れがないように気をつけて行っていきましょう。

少しでもお役に立てれば嬉しいです。ご一読ありがとうございました。

スポンサーリンク
運営者
コル
コル
技術探検家 / 子育て忍者
ウェディングプランナーからエンジニアへ異業種転職し、家族と田舎のとある村でリモートワークメインで生活中。今はフリーランスエンジニアとしてJava/Python/Go/Reactなどが経験多め。子育てとコーディングを巧みに両立する「忍者スタイル」でスローライフと気になる技術を日々探求中!たまに妻から「ボヤッキーみたい」と笑われながらも、技術やガジェット関連をテーマにブログを更新しています。
記事URLをコピーしました