😂

Flutterのpubspeck.yamlにGithubのブランチを指定した場合はVerifiedコミットが取得される

に公開
2025/07/14

何があったのか

纏めると以下です。

試したこと

Flutterでパッケージを使用する際はpackage.yamlに記述しますが、そこにGitHubのURLとブランチを指定することができます。例えば以下のようにreferenced_libraryというパッケージを参照しているとします。

pubspeck.yaml
dependencies:
  flutter:
    sdk: flutter
  referenced_library:
    git:
      url: git@github.com:XXXXXX/referenced_library.git # URL
      ref: main # ブランチ名

referenced_library側は、単純に文字列を返すだけの関数があるとします。

referenced_library.dart
class Calculator {
  String getMessage() => 'これは古いです。';
}

メインのアプリ側は、このreferenced_libraryのgetMessage()を呼び出した結果を画面に表示しています。

パッケージ側を更新

パッケージ側を更新し、getMessage()が返す文言が変わりました。

class Calculator {
-  String getMessage() => 'これは古いです。';
+  String getMessage() => '変更しました。';
}

この状態で、メインのアプリ側でflutter pub getを実行してパッケージを更新しても、表示される文言は変わりませんでした。

キャッシュを削除してみた

古いキャッシュが残ったままになっているかもしれないと思い、flutter pub cache cleanを実行してキャッシュを削除しました。

❯ flutter pub cache clean
This will remove everything inside /Users/xxx/.pub-cache.
You will have to run `flutter pub get` again in each project.
Are you sure? (y/N)? y
Removing pub cache directory /Users/xxx/.pub-cache.
Deletion failed, path = '/Users/xxx/.pub-cache' (OS Error: Directory not empty, errno = 66)
Failed to update packages.

# エラーが出る場合は、再度実行する
❯ flutter pub cache clean
This will remove everything inside /Users/xxx/.pub-cache.
You will have to run `flutter pub get` again in each project.
Are you sure? (y/N)? y
Removing pub cache directory /Users/xxx/.pub-cache.

再度flutter pub get を実行する

キャッシュが削除されたので、再度flutter pub getでパッケージを取得するも、変わらず古い文言のままでした。

flutter pub get 

なぜなのか

原因は、冒頭に書いた話ですが、最新のVerifiedコミットが取得されるからです。最新のVerifiedコミット以降に作られたコミットは無視されています。

Verifiedとは?

署名付きのコミットのことで、詳細は以下をご参照いただきたいのですが、要するにそのコミットって本当にその人がやったのか?というのを検証できるようにする仕組みのことです。
https://docs.github.com/ja/authentication/managing-commit-signature-verification/about-commit-signature-verification

各コミットには誰がコミットしたかが表示されていますが、そもそもこれはローカルのgitconfigで設定できるので、他人の名前やメールアドレスを指定できてしまうからということのようです。


コミット履歴

  • 最新の一つ前のコミット(eb05175)は、getMessage()は'これは古いです。' ← Verified
  • 最新のコミット(094581e)は、getMessage()は'変更しました。'

なので、最新ではなく一つ前のコミットが取得されていたため、画面には'これは古いです。'が表示されたままでした。

なんでVerifiedが付いたり付かなかったりするの?

コミットする際、明示的に指定しなければ署名は付きません。
https://docs.github.com/ja/authentication/managing-commit-signature-verification/signing-commits

ですが、GitHubのWebインターフェース上で操作した場合は自動的にGitHubが署名するようです。

今回の場合は、

  • 最新の一つ前のコミット(eb05175)は、ブランチ切ってコード変更して、PR作ってmainにマージした。→ GitHubのWeb画面上で操作した
  • 最新のコミットは、mainブランチから直接pushした。→ GitHubのWeb画面上で操作していない

という違いがあったため、このような事態に陥りました。


Web画面から操作した場合自動で署名される

解決

mainから再度ブランチを切って、PR作成→マージをすれば、最新コミットがVerifiedになりました。その状態でflutter pub getをすれば、ちゃんと変更後の文言が表示されました。

要するに、mainに直接pushせず、ちゃんとブランチ切ろうということですね。。そうしていれば通常問題になることはないはずです。

さらに探求

解決に至るまで、実はもう少し色々調査してまして、分かったことを記載します。

cacheの中身

まずキャッシュの保存場所は、~/.pub-cacheなのですが、その中の~/.pub-cache/git配下に、対象のリポジトリが丸々cloneされており、中のソースコードを開くと確かに変更前の状態でした。

で、よくよく見るとディレクトリ名にコミットID(ハッシュ値)そのものが付いていました。これで気がつきました。

pubspeck.lock

もう一個ハマったことがあって、それがpubspeck.lockです。このファイルは各パッケージの具体的なバージョンなどが記載されているファイルで、flutter pub getした際にpubspeck.lockに記載のバージョンがダウンロードされます。これがあるお陰で人に依って取得されるバージョンが異なるということを防ぐことができます。

で、私は上記で解決した際、結局GitHub上のブランチの操作が原因だったので、パッケージ自体を変更するつもりが無かったのでローカルの変更内容を全て破棄して元に戻してしまったんです。

そうすると、最新のコミットをVerifiedにしたにも関わらず、また古いコミットが取得されてしまいました。

pubspeck.lockにはバージョンだけでなく、以下のようにGitHubの場合はコミットID(ハッシュ値)が記載されていました。

pubspeck.lock
  referenced_library:
    dependency: "direct main"
    description:
      path: "."
      ref: main
      resolved-ref: eb051756c94b51d7fdfdf9389fa2b0216bfc46f6 # コミットID
      url: "git@github.com:XXX/referenced_library.git"
    source: git
    version: "0.0.1"

ローカルの編集内容を破棄して元に戻してしまったことで、コミットID(resolved-refの値)も古いコミットのIDに戻ってしまった、ということです。

flutter pub upgradeを実行するか、このファイル自体を削除してしまうと、(更新があれば)全パッケージが更新されてしまうので、更新したいパッケージの行だけを削除することで、そのパッケージだけを更新することができます。

pubspeck.yaml にコミットIDを指定することもできる

ちなみに、以下のようにpubspeck.yamlにブランチ名ではなくコミットIDを指定することもできます。

pubspeck.yaml
dependencies:
  flutter:
    sdk: flutter
  referenced_library:
    git:
      url: git@github.com:XXXXXX/referenced_library.git # URL
      ref: 094581e234a76a2e317df294ed0ce20042eb606d # コミットID

こうすると、Verifiedかどうかに関わらず、指定したコミットが取得されます。
当然、そのコミットに固定されることになりますが。

Discussion