◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り44日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り44日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/Claude Code
⟐ Claude Code/2026-06-03中級

Claude Code で git push が「成功」したのに反映されない — commit が無音で失敗する罠

git push がエラーを出さず Everything up-to-date と表示されるのに、変更がリモートに反映されない。clone 直後の identity 未設定で commit が無音失敗する原因と、SHA 照合で確実に検証する方法を解説します。

troubleshooting61error15fix11git18claude-code132push3automation55

私が4つの技術ブログを毎日自動更新している仕組みで、いちばん怖かったのは「赤いエラー」ではなく「緑のログ」でした。スケジュール実行のログには git push 成功と出ているのに、記事がサイトに一向に増えない。手元では確かに push が走っているのに、リモートには何も届いていない——この無音の失敗を突き止めるまで、原因を勘違いして数日を溶かしました。

git push は、実は「何もしていなくても成功する」コマンドです。Claude Code やサンドボックス環境で自動化を組んでいると、この性質が思わぬ落とし穴になります。エラーが出ないからこそ気づきにくい、commit の無音失敗について整理します。

症状 — エラーは一切出ないのに変更が消える

典型的なログはこうなります。

$ git add content/
$ git commit -m "Add: new article (JA+EN)"
$ git push origin main
Everything up-to-date

git push が Everything up-to-date を返し、終了コードも 0。スクリプトは何事もなく次の処理へ進みます。ところが GitHub を見ると、新しいコミットは存在しません。CI も走らず、デプロイも起きない。エラーハンドリングを if [ $? -ne 0 ] で書いていても、push 自体は成功扱いなので決して引っかかりません。

問題は push ではなく、その手前の commit が無音で失敗していることにあります。

なぜ起きるのか — commit が静かにスキップされる2パターン

パターン1: clone 直後で git identity が未設定

これがいちばん多い原因です。CI コンテナやサンドボックスで git clone した直後は、user.name と user.email が設定されていません。この状態で git commit を実行すると、環境によっては以下のように コミットを作らずに終了 します。

Author identity unknown

*** Please tell me who you are.

厄介なのは、出力をパイプで握りつぶしていたり、commit の終了コードを確認していないと、この警告が見えないまま次の git push に進んでしまう点です。commit が作られていないのでローカルの HEAD はリモートと同じまま。だから push は当然 Everything up-to-date を返します。

私のスケジュールタスクでは、git clone --depth 1 の直後に毎回 identity を設定する処理を入れていなかった時期があり、これに長く気づけませんでした。

パターン2: ステージした変更が実質ゼロ

git add したつもりでも、対象パスがずれていて何もステージされていない、あるいは生成物が .gitignore で除外されていると、git commit は次のように何もせず終わります。

On branch main
nothing to commit, working tree clean

このときも commit は作られず、終了コードは 1(または環境により 0)。続く push はやはり Everything up-to-date です。自動生成したファイルが意図したディレクトリに書き込めていなかったケースが、これに当てはまります。

パターン3: コミット先と push 先のブランチがずれている

意外に見落としがちなのが、commit は成功しているのに push 先のブランチが別物 というケースです。--depth 1 の浅いクローンで特定コミットを取得すると detached HEAD になることがあり、その状態で commit すると名前のないブランチに積まれます。あるいはリポジトリの既定ブランチが master なのに git push origin main と書いていれば、main には何も載っていないので当然 Everything up-to-date が返ります。

# 自分がどのブランチに commit したかを確認する
git rev-parse --abbrev-ref HEAD   # "HEAD" と出たら detached
git branch --show-current          # 空なら detached HEAD

clone のオプションに --branch main を明示し、push の直前に現在ブランチを確認しておくと、この取り違えは防げます。

再現してみる

挙動を手元で確かめると、対策の勘所が掴めます。identity を消した状態で commit を試すと、push が空振りする流れを再現できます。

# 検証用の使い捨てクローン
git clone --depth 1 https://github.com/you/your-repo.git /tmp/verify
cd /tmp/verify
 
# identity をあえて未設定にする
git config --unset user.name 2>/dev/null
git config --unset user.email 2>/dev/null
 
echo "test" >> README.md
git add README.md
git commit -m "test commit"   # ← ここで identity unknown により失敗する
echo "commit exit code: $?"    # 128 などゼロ以外が返る
 
git push origin main           # ← それでも Everything up-to-date

commit exit code がゼロ以外であること、にもかかわらず push が成功扱いになることが確認できます。

確実な対処 — 「設定」と「検証」を分けて入れる

対処は2段構えにします。発生を防ぐ「設定」と、起きても気づける「検証」です。

1. clone 直後に必ず identity を設定する

自動化スクリプトでは、clone のたびに無条件で identity を設定するのが安全です。一度設定すればそのリポジトリでは保持されますが、再 clone のたびに消えるため、毎回入れておきます。

git clone --depth 1 --branch main "https://${TOKEN}@github.com/you/your-repo.git" "$WORK"
cd "$WORK"
 
# clone 直後は identity が空。無条件で設定する
git config user.email "you@example.com"
git config user.name "your-name"

2. push の成否を「SHA 照合」で判定する

ここがいちばん大切です。git push の終了コードは信用できないので、ローカルの HEAD とリモートの HEAD が一致したか で成功を判定します。これなら commit の無音失敗も、push の取りこぼしも、まとめて検出できます。

# commit は終了コードも見る
git add content/
if ! git commit -m "Add: new article (JA+EN)"; then
  echo "❌ commit に失敗しました(変更なし、または identity 未設定)"
  exit 1
fi
 
# push 後にローカルとリモートの SHA を突き合わせる
git push origin main
 
LOCAL=$(git rev-parse HEAD)
REMOTE=$(git ls-remote origin -h refs/heads/main | cut -f1)
 
if [ "$LOCAL" = "$REMOTE" ]; then
  echo "✅ push 確認: $LOCAL がリモートに反映されました"
else
  echo "❌ 不一致 — local=$LOCAL remote=$REMOTE。push は反映されていません"
  exit 1
fi

git ls-remote はリモートの最新 SHA を直接問い合わせるので、ローカルのキャッシュに惑わされません。この照合を通ってはじめて「push 成功」とみなす——という原則にしてから、私の自動更新では「成功ログなのに記事が増えない」現象が起きなくなりました。

自動化パイプラインでは「終了コードを信じない」を既定にする

この一件で学んだのは、自動化において終了コードは出発点でしかない、ということです。git push のように「何もしなくても成功するコマンド」は珍しくありません。成果物が本当に存在するか(コミットが積まれたか、ファイルが届いたか)を、コマンドの戻り値ではなく 状態そのもの で確認する。これは Git に限らず、API 呼び出しでもファイル生成でも同じ姿勢で臨むべきだと感じています。

無音の失敗が厄介なのは、ログを何度見返しても「正常」としか書かれていない点にあります。エラーであれば文面を手がかりに検索できますが、何も起きていない成功はそもそも調べる糸口がありません。個人開発で自動化を一人で回していると、声を上げてくれる人もいません。私自身、原因をログの読み違いだと思い込んだまま、関係のない場所を何日も探ってしまいました。だからこそ、成果物が本当に積まれたかを毎回機械的に問い合わせる一手間を、パイプラインの既定動作にしてしまうのが結局いちばん早道だと考えています。

Git 操作で別の壁にぶつかったときは、サンドボックス特有の問題をまとめたClaude Code の git index.lock がVM・CIで詰まるときの対処や、git の dubious ownership を safe.directory で解決する方法も合わせて確認してみてください。どうしても git コマンドが安定しない環境では、GitHub REST API で commit と push を行う方法に切り替えるのも現実的な選択肢です。

まずは、自動化スクリプトの git push の直後に、上記の SHA 照合を3行足してみてください。次に「成功ログ」が出たとき、それが本物かどうかを初めて自信を持って言えるようになります。

最後までお読みいただき、ありがとうございました。同じ無音の失敗で時間を溶かす方が一人でも減れば嬉しいです。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⟐ Claude Code2026-05-02
Claude Code の Edit ツールで「old_string is not unique」エラーを止める実践的な書き換え戦略
Claude Code の Edit ツールで「old_string is not unique」が頻発するのは、編集ターゲットの一意性をプロンプト側で保証していないことが根本原因です。再発を防ぐ書き換え戦略を解説します。
⟐ Claude Code2026-05-24
Claude Code で連続する Edit が連鎖的に失敗するときの直し方 — old_string が消える・重複する問題
Claude Code が同じファイルへ Edit を連続で投げると、2件目以降が突然『not found』や『not unique』で落ちることがあります。原因は順序依存とコンテキスト二重化で、Read 再実行と分割パッチで救えます。
⟐ Claude Code2026-05-10
Claude Code の Glob と Grep が0件を返すときの原因切り分け
Claude Code の Glob/Grep ツールがファイルを見つけられないとき、.gitignore除外・隠しファイル・パターン記法の落とし穴を切り分け、適切な代替手段で確実に発見する手順をまとめます。