HOWTO · Git
Git プッシュの Everything Up-To-Date 問題を解決する
この記事では、Git のリポジトリに変更を加えた後、すべてが最新の問題を修正する方法について説明します。
このページの内容
git push を実行して Everything up-to-date と表示された場合、プッシュ元から送信先ブランチへ送る新しいコミットがないことを Git が示しています。このメッセージだけでは、作業ツリー内のファイルがコミット済みかどうかは分かりません。また、ローカルの変更がすべてアップロードされたという意味でもありません。まず作業ツリーを確認してコミットがあることを確かめ、それからプッシュに使われるブランチとリモートを確認してください。
「Everything up-to-date」が意味すること
Git がプッシュするのはコミットであり、作業ツリーから編集内容を直接送るわけではありません。ファイルを変更、ステージ、または新規作成しても、コミットに含まれていない場合があります。送信先にないコミットがソースブランチに存在しなければ、Git には転送するものがなく、Everything up-to-date と表示されることがあります。コミットがすでにリモートに届いている場合も、同じ応答が正常です。
まず git status --short を実行して、未ステージ、ステージ済み、未追跡のファイルを確認します。次に git branch --show-current と git log -1 --oneline で、現在のブランチと直近のコミットを調べます。これらを確認すれば、ファイルの変更とプッシュできるコミットを区別できます。
コミットが作成されたことを確認する
含めるファイルを git add <file> でステージします(git add . を使う場合は、先に作業ツリー全体を確認してください)。git commit -m "Describe the change" でコミットを作成し、続けて git status と git log -1 --oneline を確認します。コミットが作成されていなければ、git push で転送する新しいコミットはありません。
-m オプションはコミットメッセージを指定します。このオプションを省略すると、通常 Git は設定済みのエディターを開きます。コマンドが必ず失敗するわけではありません。エディターを利用できない場合や、メッセージを保存しなかった場合は、コミットが作成されないことがあります。git commit -am "..." は、すでに追跡されているファイルの変更と削除をステージしますが、新しい未追跡ファイルはステージしません。新規ファイルは、コミットする前に明示的に追加してください。
ブランチとアップストリームを確認する
git status -sb で現在のブランチとアップストリームを確認し、git remote -v で設定済みのリモートを確認します。送信先を明示しないプッシュでは、ブランチのアップストリームと設定されたプッシュ動作が使われます。Git が常に main または master を選ぶわけではありません。そのため、あるブランチでコミットしても、別のソースや送信先がプッシュに使われる場合があります。
コミットを特定のリモートブランチに送る場合は、対応関係を明示します。git push origin HEAD:main は、現在のブランチの先端を origin の main に送ります。main は目的の送信先ブランチ名に置き換えてください。新しいブランチの場合は、git push --set-upstream origin my-feature を実行すると、そのブランチがプッシュされ、アップストリームも記録されます。以降は送信先が設定された状態で git push を実行できます。プッシュする前にブランチ名を確認してください。
意図したコミットをプッシュする
この自己完結型の例では、一時的なローカルリポジトリと bare リモートを作成し、コミットを1つ作ってプッシュします。ホスティングサービスに接続せずに、コミットをリモートへ送る流れを示します。
次の例を実行します。
このセクションのコードと表示されるラベルや出力は英語のままです。
set -eu
tmp_dir=$(mktemp -d)
trap 'rm -rf "$tmp_dir"' EXIT
git init -q --bare "$tmp_dir/remote.git"
git init -q -b main "$tmp_dir/work"
cd "$tmp_dir/work"
git config user.name Example
git config user.email example@example.com
printf 'A small change\n' > note.txt
git add note.txt
git commit -q -m "Add note"
git remote add origin "$tmp_dir/remote.git"
git push -q -u origin main
local_commit=$(git rev-parse HEAD)
remote_commit=$(git --git-dir="$tmp_dir/remote.git" rev-parse refs/heads/main)
if [ "$local_commit" = "$remote_commit" ]; then
printf 'Commit sent to origin/main.\n'
fi
Commit sent to origin/main.
自分のリポジトリでは、まずブランチとコミットを確認してから、git push origin <branch> または設定済みのアップストリームを使います。送信先ブランチにそのコミットがない場合、プッシュが成功するとリモートブランチが進みます。すでにコミットがある場合は、最新状態であることを示す応答が返ります。手元にない変更がリモートにあるため Git に拒否された場合は、その拒否メッセージを読み、履歴を慎重に調整してください。これは最新状態を示す応答とは別の状況です。
HEAD が切り離されている場合
git status を実行して、detached HEAD の通知があるか確認します。この状態では HEAD がローカルブランチではなく、コミットを直接指しています。この状態でもコミットは存在しますが、通常プッシュするブランチに自動で含まれるわけではありません。この状態だけで Everything up-to-date のすべての応答を説明できるわけではないため、まずソースの参照先と送信先を確認してください。
切り離された状態でのコミットを残したい場合は、たとえば git switch -c my-work を使って、そのコミットを起点とするブランチを作成または切り替え、そのブランチを明示してプッシュします。すでにあるブランチにそのコミットを含めたい場合は、コミット履歴を調べ、意図した方法で取り込んでください。むやみにブランチをリセットしないでください。リセットすると、ブランチが指すコミットが変わり、--hard は作業ツリーの変更を破棄することがあります。
危険な操作や無関係な対処を避ける
Git が Everything up-to-date と表示したという理由だけで、強制プッシュ、リベース、プル、リモート URL の変更、リポジトリの削除、再クローンを行わないでください。これらは別の状況に対する操作であり、履歴を変えたり作業を失ったりする可能性があります。設定された送信先が意図したリポジトリではない場合は、リモート URL を確認する価値がありますが、URL を直しても不足しているコミットが作られるわけではありません。権限の問題では、通常この応答ではなく拒否メッセージが表示されます。
次の順で確認してください。git status を調べ、直近のコミットを確認し、現在のブランチとアップストリームを確かめてから、必要に応じて意図したブランチを明示してプッシュします。作業ツリーに残したい変更がある場合は、先にステージしてコミットしてください。コミットがすでに送信先ブランチにあるなら、追加のプッシュは不要です。