0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHubでpushできないとき最初に確認すること|rejected・origin・branch・conflictを順番に整理する

0
Posted at

GitHubへ、

git push

したらエラーになった。

このとき、エラー文をそのまま検索して、

このコマンドを試す
↓
別のエラー
↓
また別のコマンドを試す

となることがあります。

Gitのpushエラーは原因が複数ありますが、最初にやることは意外と共通しています。

いきなり直そうとせず、現在の状態を確認する。

この記事では、pushできないときの確認順を、

状態確認
↓
原因候補を絞る
↓
必要な対処だけ行う

という流れで整理します。


まず最初に見る6つ

私はまず、次を確認します。

git status
git branch --show-current
git remote -v
git log --oneline --decorate -n 5
git fetch
git status

目的はそれぞれ違います。

確認 見たいこと
git status 未commit変更やGitの現在状態
git branch --show-current 今どのbranchにいるか
git remote -v どのGitHub Repositoryへ接続しているか
git log 直近のcommit
git fetch GitHub側の最新情報
エラー本文 状態と照合して原因を絞る

git status はworking tree、index、未追跡ファイルなど現在の状態を確認する基本コマンドです。Git


1. そもそもpushするcommitがない

最初によくあるのがこれです。

ファイルを修正したつもりでも、

  • 保存していない
  • git addしていない
  • commitしていない

ということがあります。

まず、

git status

を確認します。

例えば、

Changes not staged for commit:

なら、変更はありますがまだstageされていません。

必要なら、

git add .
git commit -m "変更内容"
git push

と進みます。

一方、

nothing to commit, working tree clean

で、pushすると、

Everything up-to-date

なら、Gitから見れば送る新しいcommitがない可能性が高いです。

ポイント

pushできない

と思っていても、実際には、

pushする変更自体がない

ケースがあります。

だから最初にgit statusを見ます。


2. 違うbranchにいる

次に確認したいのがbranchです。

git branch --show-current

例えば、

feature/login

で作業していたつもりなのに、

main

にいるかもしれません。

逆もあります。

branchを間違えた状態で、

git push

すると、意図したbranchとは別のものをpushしようとしてしまいます。

push前には、

git status
git branch --show-current

の2つを見るとかなり分かりやすいです。


3. upstreamが設定されていない

新しく作ったfeature branchを初めてpushすると、

upstreamがまだ設定されていない場合があります。

例えば、

fatal: The current branch feature/example has no upstream branch.

のようなメッセージです。

その場合は、

git push -u origin feature/example

とします。

-uは、そのローカルbranchと対応するremote branchを追跡関係にするための指定です。

一度設定されれば、次回からは通常、

git push

だけで済みます。


4. remote origin already exists

既存プロジェクトへGitHub Repositoryを接続するとき、

git remote add origin https://github.com/USER/REPO.git

を実行したら、

fatal: remote origin already exists.

と出ることがあります。

これは、

originという名前のremoteがすでに登録されている

という意味です。

GitHub公式でも、このエラーは既に同名remoteが存在する場合に発生すると説明されています。GitHub Docs

まず確認します。

git remote -v

例えば、

origin  https://github.com/OLD/REPO.git (fetch)
origin  https://github.com/OLD/REPO.git (push)

と出ます。

URLが正しい

そのままで問題ありません。

URLが間違っている

既存remoteを削除する前に、

git remote set-url origin https://github.com/USER/NEW-REPO.git

で変更できます。

GitHub公式もremote URL変更にはgit remote set-urlを案内しています。GitHub Docs

つまり、

origin already exists
↓
すぐ削除

ではなく、

origin already exists
↓
git remote -v
↓
今どこを指しているか確認

が先です。


5. rejected / non-fast-forward

代表的なpushエラーです。

例えば、

! [rejected] main -> main (non-fast-forward)

のような表示です。

これは多くの場合、

GitHub側に、自分のローカルがまだ持っていないcommitがある

状態です。

GitHubは履歴を失う可能性があるpushを拒否します。GitHub Docs

まずfetchする

git fetch origin

これでGitHub側の最新情報を取得します。

fetchはremote-tracking branchを更新しますが、自分の現在branchへ自動でmergeはしません。GitHub Docs

その後、状況を確認します。

git status
git log --oneline --decorate -n 10

必要なら、

git pull

でremote側の変更を取り込みます。

GitHub公式でも、non-fast-forward時にはfetchしてmergeするか、pullでまとめて取得・統合する方法が案内されています。GitHub Docs


--forceを最初の解決策にしない

ここは重要です。

non-fast-forwardを見ると、

git push --force

で押し切れる場合があります。

しかし、既存のremote履歴を書き換える可能性があります。

初心者向けの通常解決手順としては、

rejected
↓
fetch
↓
状況確認
↓
pull / merge等を検討

を基本にした方が安全です。

原因不明のままforce pushしない。

これだけは覚えておいた方がよいです。


6. conflictが起きた

git pullやmergeを行ったとき、同じ箇所が別々に変更されているとconflictが発生することがあります。

例えばファイル内に、

<<<<<<< HEAD
ローカル側の内容
=======
remote側の内容
>>>>>>> origin/main

のような表示が入ります。

この場合は、

  1. どちらの変更を残すか確認
  2. conflict markerを消す
  3. 正しい内容に修正
  4. git add
  5. commit

という流れです。

git status

を見ると、どのファイルがconflictしているか確認できます。

今回はconflictそのものの詳細には踏み込みません。

大事なのは、

conflictが出たら、別のコマンドを適当に打つのではなく、まず衝突しているファイルを見る

ことです。


7. detached HEADになっている

少し分かりにくい状態です。

例えば過去のcommitを直接checkoutしたあとなどに、

HEAD detached at ...

となることがあります。

これは、

通常のbranch上ではなく、特定commitを直接見ている状態

です。

まず、

git status

を確認します。

git branch --show-currentが何も返さないこともあります。

この状態で変更を続ける前に、

本当にこの状態で作業したいのか

を確認します。

通常のfeature branch作業へ戻るなら、

git switch main

や、

git switch feature/example

など、目的のbranchへ戻ります。

detached HEADの内部構造は今回は深掘りしません。


8. 認証エラー

push先やbranchが正しくても、GitHubへの認証に失敗してpushできない場合があります。

remote URLを確認します。

git remote -v

GitHubでは主に、

HTTPS
SSH

のremote URLを使います。GitHub Docs

HTTPSの場合は、パスワード認証そのものではなく、Personal Access Tokenやcredential helperなどを使用します。

SSHの場合はSSH鍵を使います。GitHub Docs

今回は認証設定自体は主題ではありません。

ただ、

branchもremoteも履歴も問題なさそうなのにpushできない

場合は、

認証も原因候補

として切り分けます。


9. GitHub側にsecretが含まれてpushを拒否されるケース

現在のGitHubでは、Push Protectionによりsecretが検出されたcommitのpushがブロックされる場合もあります。

GitHub公式では、対応対象のsecretが検出された場合、pushを止め、secretの削除または案内された手続きを行うよう説明しています。GitHub Docs

つまり、

pushできない
=
Gitの履歴だけが原因

とは限りません。

エラー本文は必ず読みます。


やらない方がいい対処

pushできないと焦ると、環境を大きく壊す操作を試したくなります。

初心者向けには、次を通常対処にしない方がよいです。

原因不明のまま --force

remote履歴を書き換える可能性があります。

.gitフォルダを削除

Git履歴や設定そのものを失います。

「よく分からないから初期化し直す」は最後の手段にします。

とりあえずcloneし直す

cloneし直すと一時的に直ったように見えても、

何が原因だったか分からないまま

になります。

originを確認せず削除

まず、

git remote -v

で確認します。

未commit変更があるままpullを繰り返す

先に、

git status

でローカル状態を確認します。


pushできないときの確認チェックリスト

最初にこれだけ見ると、かなり原因を絞れます。

git status
git branch --show-current
git remote -v
git log --oneline --decorate -n 5
git fetch
git status

そのうえで、

変更がない
→ commit状況を見る

branchが違う
→ 正しいbranchへ

upstreamなし
→ git push -u origin branch

originエラー
→ git remote -v

non-fast-forward
→ fetch → 状況確認 → pull等

conflict
→ 衝突箇所を解消

detached HEAD
→ branch状態確認

認証エラー
→ HTTPS / SSH設定確認

と進めます。


まとめ

GitHubでpushできないとき、

大事なのはエラー別の解決コマンドを大量に覚えることではありません。

まず、

status
↓
branch
↓
remote
↓
log
↓
fetch
↓
エラー本文

の順で現状を整理する。

その後に、

必要な対処だけ選ぶ。

この順番にすると、

何となくコマンドを試して、さらに分からなくなる

状態をかなり避けやすくなります。

Gitでは、

「直す前に状態を見る」

のが一番重要なのかもしれません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?