post Image
github でホストされている go アプリを fork して PR する時には、まず go get から始めよう

TL;DR

fork したリポジトリは clone せず、本家を go get すべし

経緯

Docker のコンテナ管理ツールを夢想してみたものの、なかなか険しい道のりなので、crane を拡張していく方向に切り替えました。で、最初にはまったポイントをメモ。いろいろなところで言及されているので今更感ありますが、ご了承ください。

お勧めの手順

普通は fork したものを clone して、本家へのリモート参照を upstream として追加しますが、Go の場合には逆になります。本家を get して、fork へのリモート参照を追加するのです。

  1. 本家のリポジトリを github で fork
  2. 環境変数 GOPATH を適切に設定(迷ったら HOME で良いでしょう)
  3. 本家のリポジトリを go get github.com/<userid>/<repo> で複製する
  4. 複製したディレクトリに cd $GOPATH/src/github.com/<userid>/<repo> で移動する
  5. fork したリポジトリへのリモート参照を git remote add fork https://github.com/<my-id>/<repo> で追加する
  6. トピックブランチ切って作業を行う

ブランチ切ってからの作業はいつもの手順とほぼ同じです。push 先が origin ではなく、fork であるとか、デフォルトの master ブランチが本家を指している、といったところに気をつければ、特に難しいところはありません。

なぜ fork したリポジトリを clone してはいけないのか?

Go には元からパッケージ管理機能が備わっており、GOPATH 環境変数を起点としてパッケージの存在確認を行います。パッケージのパスはローカルでも github のようなリモートでも良く、なければ GOPATH 以下に自動的にインストールしてくれます。

そして大抵の main.go には、本家のリポジトリを参照する import があります。

main.go
package main

import (
        "github.com/michaelsauter/crane/crane"
)

func main() {
        crane.RealMain()
}

当然ながら fork したリポジトリは github.com/<userid> 部分が自分のものに置き換わりますから、ビルドでコケます。なので、まずは本家を go get するのがお作法になるわけです。

振り返り

最初は、fork したリポジトリに合わせて import を修正しようか…… なんて考えもチラリと浮かんだのですが、そんな乱暴な PR など通るはずもないしなぁと思い、お作法に辿り着きました。

Go のパッケージ管理は良くできているようで、案外、そうでもない気がしています。固有のリポジトリと強固な依存関係をソースコードに持ち込んでしまうのは、果たして良かったのか。リポジトリの物理的な場所は外出しにして、マッピングできるようになっているとか、DI 的なものでも良いのですが、そういった仕組みが用意してあれば今回のケースにもうまく対処できたように思います。

まあでも、git が柔軟だからどうとでもなるのですけどね。

教訓

Go に入っては Go に従え

参考


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。