リモートに存在するはずのブランチにpushができない
結論
ローカルでブランチを作成して最初にリモートにpushした時に、ブランチの追跡設定を行っていなかったことが原因でした。
gitのメッセージにある通りgit push --set-upstream origin feature/xxx
して、ローカルとリモートを紐づけてから push したら成功しました。
何がおきた
開発ブランチをローカルで作成、コードを修正後一度リモートにpush。
その後ローカルで別のコードを修正し、再度pushしようとしたら失敗しました。
fatal: The current branch feature/xxx has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin feature/xxx
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.
「カレントブランチ(= ローカルブランチ)には上流ブランチ(= リモートブランチ)がありません」と言われます。
しかし、リモートブランチにブランチは存在します。なぜこのようなことが起こるのでしょうか。
原因
gitのメッセージにあるように、追跡設定を行っていなかったのか確認しました。
シェルの履歴を出してみます。
$ history | grep git
534 git switch -c feature/xxx
535 git branch
536 git add .
537 git status
538 git commit -m "最初のコミット"
539 git branch
540 git push origin HEAD
...途中省略...
578 git branch
579 history | grep git
540番目が最初のpushですが、git push origin HEAD
を打っていたことが判明、これが原因でした。
ローカルブランチがリモートブランチを追跡していない場合、git push
コマンドだけを実行すると失敗します。今回のように、ローカルでブランチを作成し、リモートに上げる場合が失敗するパターンの例です。
しかし、git push origin HEAD
は失敗せずにpushできてしまいます。そのため、追跡設定も行われると勘違いしていました。
ということで、gitのメッセージにある通り、--set-upstream
オプションをつけて追跡設定を追加しました。
$ git push --set-upstream origin feature/xxx
Enumerating objects: 86, done.
Counting objects: 100% (86/86), done.
Delta compression using up to 12 threads
Compressing objects: 100% (45/45), done.
Writing objects: 100% (46/46), 7.32 KiB | 7.32 MiB/s, done.
Total 46 (delta 40), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (40/40), completed with 38 local objects.
To github.com:{リポジトリ名}
f8887be0c..89259972d feature/xxx -> feature/xxx
branch 'feature/xxx' set up to track 'origin/feature/xxx'.
ちなみに、--set-upstream
のショートオプションは -u
です。
おわりに
普段は --set-upstream
オプションを使ってpushするのですが、最近ちゃんとGitコマンドを理解しようと中途半端に学んだ結果、間違ったコマンドを使ってしまいました。
また、いつもオプションを覚えられないのでgit push
を実行して一度失敗させ、gitのメッセージに出てきたコマンドをコピペして使うという怠惰な運用をしていました(ショートオプションの存在を知りませんでした)。
普段からサボらずちゃんとメッセージを読んでいたら、早い理解とこのようなトラブルは起きなかったかもしれません。
おまけ
ローカルで新規作成したブランチをリモートにpushする際によく使う追跡設定(--set-upstream)
ですが、逆に追跡を解除するオプションもあります(こちらはショートオプションはない)。
git branch --unset-upstream feature/xxx
いつ使うのだろうと思ったのですが、「リモートからクローンしてきてちょっとローカルでソースを見たい」という時、誤ってpushしないように使ったりするようです。なるほど。
Discussion