◀ 16.

Git pushの使い方|送信先・タグ・force-with-leaseの条件

▶

Git pushは送り先のrefを更新し、必要なcommit等を送る操作です。remote名だけでなくpush URL・送信元と送り先branchを確認し、通常送信、タグ、削除、履歴の書換えを分けます。

Git pushで送り先と更新する参照を確認しforce-with-leaseの条件とdry-runの限界を区別する図

この記事の要点
  • 基本: git push origin main でローカルのコミットをリモートに送る
  • -uは送信成功/最新状態のbranchに追跡先を設定。省略pushの送信先はpush URLや各設定も確認
  • --all 全ブランチ / --tags タグ / --delete リモートブランチ削除
  • --force-with-leaseも強制更新。期待値を省略すると自動fetch等の影響を受け、無条件に安全ではない
  • 接続先のHTTPS/SSH認証と送信権限を確認。remote名とpush URL、送り先branchを明示する

基本: git push

ローカルブランチのコミットをリモートリポジトリに送るコマンド。チーム共有の起点になる操作です。

次は選択肢で一括実行しません。pushは未commitの作業ファイルではなくcommit/refを送ります。mainは例の名前で、現在branchの確認、detached HEAD、ローカルと先の同名branch/tagの曖昧さ、remoteのpush URL/設定にも注意します。

# リモート origin の main ブランチへ
git push origin main

# 現在のブランチを同名でリモートへ
git push origin HEAD

# 短縮形(追跡設定済なら)
git push

初回 push と追跡設定(-u)

-uは成功した/最新状態のbranchへupstreamを設定する指定です。省略pushはbranchのpushRemote、remote.pushDefault、remote側のpush設定、push.default等にも依存するので、upstreamがあるだけで全環境の送り先を保証しません。pullの取込元とpush先が異なる構成もあります。

次のcheckout -bは新branchを作る操作です。既存の名前/作業状態を確認し、追跡設定だけを付けたいときに作成からやり直しません。-uやbranch --set-upstream-toの前に実在するbranch/refと送信/取込の向きを確認します。

# 新ブランチ作成
git checkout -b feature/login

# 初回 push(-u で追跡設定)
git push -u origin feature/login

# 以降は省略可
git push
git pull

# 追跡設定だけ後付け
git branch --set-upstream-to=origin/feature/login

# 現在の追跡先確認
git branch -vv

主なオプション

オプション動作
-u / --set-upstream追跡先設定(初回 push 用)
--all全ローカルブランチを push
--tagsrefs/tags以下の全タグを対象にする。branchの全送信とは別
--follow-tags通常の送信に加え、送信参照から到達可能なcommit-ishを指す未送信の注釈付きタグ
--delete branchnameリモートブランチ削除
--force / -f強制 push(危険)
--force-with-lease期待したref値と比較する条件付き強制更新。内容/協業の安全保証ではない
-n / --dry-run接続して更新予定を確認。参照は更新しないが、実更新の成功は保証しない
-v / --verbose詳細表示

タグの push

次の同じv1.0.0の2行はlightweight/annotatedの別の作り方で、続けて作成すると名前が重複します。--follow-tagsはbranch等の通常送信に加える指定で、未送信の到達可能な注釈付きタグが対象です。lightweight tagや到達不能の注釈付きタグを全て送る指定ではありません。削除例は確認ではなく変更なので一括実行しません。

# タグ作成
git tag v1.0.0
git tag -a v1.0.0 -m "Release 1.0.0"      # 注釈付き(推奨)

# タグだけ push(デフォルトの push にタグは含まれない)
git push origin v1.0.0
git push origin --tags                     # 全タグ
git push --follow-tags                     # 注釈付きタグのみ

# リモートタグ削除
git push origin --delete v1.0.0
git push origin :refs/tags/v1.0.0          # 旧書き方

リモートブランチの削除

次の「推奨」は削除自体を勧める意味ではありません。remote削除とlocal branch削除は別の変更です。同名tagもある場合はrefを区別し、利用中のPR/CI/保護・共有者と退避/復旧を確認してから判断します。

# 推奨
git push origin --delete feature/login

# 旧書き方(同じ意味)
git push origin :feature/login

# ローカルも消す
git branch -d feature/login

force-with-lease: 条件付きの強制push

force-with-leaseは期待したリモートref値と現在値を照合する仕組みです。期待値を省略した場合は通常remote-tracking参照等に依存し、IDE等のbackground fetchがそれを更新すると、手元のbranchへ取り込んでいない変更でも強制更新予定が通る場合があります。期待した完全なOIDを明示しても、上書きする内容や対象branchの選択・権限が正しいことまでは保証しません。

次の旧コメントの「安全」は無条件の保証ではありません。どの例も共有履歴を変更し得ます。期待値省略のleaseはfetch更新の影響を受けます。force-if-includesも対応版/指定条件があり、leaseなし、またはref:expectを明示したleaseとの併用では追加チェックがno-opとなる条件があります。名前だけで安全な代替として実行しません。

# ❌ 危険: 他人の commit を含めて全部上書き
git push --force origin main

# ✅ 安全: ローカルが知っているリモート状態と一致しなければ拒否
git push --force-with-lease origin feature/login

# Git 2.30+ では更に安全な --force-if-includes も併用可
git push --force-with-lease --force-if-includes origin feature/login

共有ブランチ(main / develop)には絶対に --force しないのが鉄則です。

リモートの設定確認

次のremote追加/URL変更/削除を一覧確認の続きに一括実行しません。remote -vの出力にも秘密値/内部URLがあり得るため公開前に点検し、get-url --push --allでも送り先を確認します。

# リモート一覧
git remote -v
# origin     git@github.com:user/repo.git (fetch)
# origin     git@github.com:user/repo.git (push)

# リモート追加
git remote add upstream git@github.com:original/repo.git

# URL 変更(HTTPS ↔ SSH 切替)
git remote set-url origin git@github.com:user/repo.git

# リモート削除
git remote remove upstream

複数リモート(fork 運用)

OSS の fork 運用では、自分の fork が origin、本家が upstream という慣習です。

次はfork運用の一例で、upstream/originはローカルの名前です。既存設定/自分のbranchと作業状態を確認します。fetchは追跡参照等を変え、checkout/mergeも作業を変えるので、単なるpush前チェックとして自動実行しません。

# 本家を upstream として追加
git remote add upstream https://github.com/original/repo.git

# 本家の最新を取り込み
git fetch upstream
git checkout main
git merge upstream/main

# 自分の fork に push
git push origin main

認証: HTTPS と SSH

方式長所注意
HTTPS + PATファイアウォール越えやすい接続先の方式・権限・期限/組織条件を確認。GitHubもPAT手入力だけが唯一の方法ではない
SSH 鍵公開鍵認証。接続時の認証は行われ、パスフレーズ/agent・通信速度も環境依存鍵管理(ssh-add / config)が必要
HTTPS + GitHub CLIgh auth login で簡単gh コマンドの導入が必要

次の鍵生成はpushごとに必要な手順ではなく、既存鍵を上書きしません。公開鍵のみ登録し秘密鍵は保護します。ホスト鍵指紋を照合し接続先検証を停止しません。GitHubのssh -Tは認証成功でも終了1となり、repoへの書込権限は別です。

# SSH 鍵生成
ssh-keygen -t ed25519 -C "you@example.com"

# 公開鍵を GitHub の Settings → SSH and GPG keys に登録
cat ~/.ssh/id_ed25519.pub

# 接続テスト
ssh -T git@github.com
# → Hi user! You've successfully authenticated...

# HTTPS → SSH に切替
git remote set-url origin git@github.com:user/repo.git

push を rebase で前処理(履歴をきれいに)

次のrebaseをpushの必須前処理にしません。rebase対象は現在checkout中のbranchで、コメントだけではfeature/login上にいると保証できません。continueは停止中のrebaseを解決して続ける操作です。未共有のcommitの積み直し等では通常pushできる場合もあり、「rebase後はforce必須」は誤りです。共有履歴とチームの方針を確認します。

# main を最新化
git fetch origin
git rebase origin/main   # feature の上から main 最新コミットの上に積み直す

# コンフリクト解決後
git rebase --continue

# force-with-lease で push(rebase 後は履歴が書き換わるので force 必須)
git push --force-with-lease origin feature/login

よくあるエラー

エラー原因対処
rejected (non-fast-forward)リモートに新しい commit がある対象URL/branchと両履歴を調べ、チーム方針に従って統合方法を決める。無条件のrebase/forceを行わない
rejected (fetch first)同上まず正しい送り先からfetchし差分を確認。履歴の統合は別の判断
permission denied (publickey)ユーザー/選択鍵/登録/SSH設定等の認証条件接続先と実際のクライアント/鍵を確認。既存鍵の上書きや無条件のagent追加で対処しない
remote: HTTP 403認可・組織ポリシー・認証条件・URL等接続先と応答の理由を確認。403だけで期限切れと断定してtokenを再発行しない
protected branch hook declinedブランチ保護で直接 push 禁止保護方針と必要なreview/status等を確認し所定のPR経路へ。保護を無効にして回避しない

FAQ

Q: 全ブランチを一括 push したい
A: --allは全ローカルbranch、--tagsは全タグです。旧git push --all --tags originは併用できません。必要な参照を選び、branch送信とタグ送信を別々に確認します。一括対象にする前に公開してよい履歴か点検し、--follow-tagsも全注釈付きタグを無条件に送る指定ではありません。

Q: push 前に hook で lint や test を走らせたい
A: ローカルのpre-push hook等は検査を補助しますが、配布/有効化が必要で回避も可能です。設定されたcore.hooksPathやプロジェクトのツールを確認し、必須条件はサーバー側の保護/CI等も含めて設計します。未知のhookを取得してそのまま実行しません。

Q: 巨大ファイルを誤って push してしまった
A: 容量や秘密値の問題を分け、まず対象ref/コピー・利用先への影響を確認します。共有済み履歴のfilter/force pushは一律の対処にせず、合意・退避/復旧・全ref/署名・再混入や他者のcloneも含めて判断します。秘密値なら失効/ローテーションを先に扱い、巨大な通常ファイルならLFS等も別途検討します。

送信前に対象を明示してdry-runする

次は対象の作業repo内で使うBash例です。引数1はremote名、引数2は送り先branchで、省略例はorigin/mainです。現在のHEADをそのbranchへ送る予定を確認するため、今のbranchが正しいかを先に見ます。接続は行いますが参照は更新せず、取得する出力も秘密値/内部情報を含まないか点検します。

set -eu

# Run inside the intended working repository; this contacts the destination.
remote=${1:-origin}
branch=${2:-main}
git check-ref-format "refs/heads/$branch"
git branch --show-current
git remote get-url --all -- "$remote"
git remote get-url --push --all -- "$remote"
git log -1 --oneline
git push --dry-run -- "$remote" "HEAD:refs/heads/$branch"

dry-run成功は後の実送信時の保護/hook・認証/同時更新やアプリのdeploy成功を保証しません。強制更新を加えて拒否を解消するための例でもありません。refs/headsを明示することで同名tagとの送り先の曖昧さを避けています。

新規ローカルrepoでbranchとタグを送る練習

Bash/Git 2.28以降で新しい空フォルダから実行します。既存の2つの練習先があれば停止します。最初のpushはbranchと到達可能なannotated tagを送り、lightweight tagは次の明示した操作で送ります。global設定や実サービス、既存branchの改名/削除は行いません。

set -eu

# Bash / Git 2.28+: use a new empty practice directory.
for name in push-remote.git push-work; do
    if [ -e "$name" ] || [ -L "$name" ]; then
        printf '%s\n' 'Practice path already exists; stop without changing it.' >&2
        exit 1
    fi
done
git init --bare --initial-branch=main push-remote.git
git init --initial-branch=main push-work
git -C push-work config --local user.name "Example Author"
git -C push-work config --local user.email "author@example.invalid"
printf '# Push practice\n' > push-work/README.md
git -C push-work add -- README.md
git -C push-work commit -m "Create practice README"
git -C push-work tag practice-light
git -C push-work tag -a practice-annotated -m "Practice annotated tag"
git -C push-work remote add origin ../push-remote.git
git -C push-work push -u origin main --follow-tags

# Explicitly send just the selected lightweight tag.
git -C push-work push origin refs/tags/practice-light
git -C push-work rev-parse --abbrev-ref '@{upstream}'
git --git-dir=push-remote.git for-each-ref --format='%(refname)'

leaseが比較するものと確認できないもの

期待値の一致はcommit内容の確認ではありません。リモートがAからCへ進んだ場合、古いAを期待するleaseは拒否できますが、自動fetch等でremote-tracking参照がCへ更新されると、期待値を省略したleaseがCを前提に強制更新予定を通す場合があります。完全なOIDを固定しても、意図的に上書きすることの合意/保護/復旧は別の要件です。

今回はこの条件を独立した利用者の新規repoで再現し、通常push/古い期待値の拒否と、fetch後の省略leaseのdry-run結果を比較しました。危険な予定が表示されることと、本番へ実行してよいことを混同しないでください。

接続先はremoteの設定/確認、作成はリモートrepo作成、作者は名前とメール設定へ。Git親ページの子ページから選択してください。

公式資料と検証範囲

2026年10月にpushのrefspec/タグ/lease/if-includes、送信先の設定、rebase、remote、GitHub認証連携、SSH確認と照合しました。元pre9個と章を保持し、安全と断定した見出しは条件付きへ訂正。新規のローカルrepoで追加例/タグ/leaseの条件を実行検査しましたが、実GitHubの認証/組織保護・各サービスhook/CIや共有履歴の運用移行を検証したものではありません。

子ページ

子ページはありません

同階層のページ
  1. 用語一覧
  2. エラー一覧
  3. git本体のインストール(Linux)
  4. Linuxサーバーへのgit導入とクライアントのセットアップ
  5. リモートリポジトリをローカルリポジトリとしてクローンする方法
  6. リモートとローカルのリポジトリを同期(pull)する方法
  7. 設定の確認
  8. gitユーザー名とemailの設定
  9. リモートリポジトリの作成
  10. ローカルリポジトリの作成
  11. 新規ファイル/ディレクトリをインデックスに登録
  12. インデックスの登録状態を確認
  13. ローカルリポジトリの変更をコミット
  14. コミット履歴の確認
  15. クライアントからリモートリポジトリの接続設定、確認、削除
  16. リポジトリへのプッシュ
  17. リモートリポジトリからクライアントへのSSHクローン
  18. リモートとローカルの差分表示
  19. バージョンの確認
  20. プロキシの設定
  21. ローカルをリモートリポジトリの状態に戻す
  22. ブランチの作成, 一覧表示, 切り替え
  23. ブランチのマージと削除
  24. リベース
  25. .gitignoreの書き方
  26. .gitignoreの設定が反映されない場合
  27. 特定のファイルをgitの管理から外す方法
  28. 参照(ORIG_HEAD, HEAD, FETCH_HEAD)
  29. git rm [-r --cached] の取り消し
  30. 一部のディレクトリ/ファイルのみをリポジトリから復元する方法
  31. ローカルとリモートリポジトリの有無を同期
  32. pushの取消し方法
  33. マージツールの起動方法
  34. Gitで「MERGING」の状態

最近更新/作成されたページ