github repository への push でエラーが発生した時の対処

さて、前回は git clone で発生した問題点について書いたわけですけど、今回は git push です。

ローカルでの編集、commit を完了したので、リモートの repository へ push しようと試みたところ、

error: The requested URL returned error: 403 while accessing https://github.com/******/******.git

などとエラーが発生してしまいました。これについて調べてみたところ、Untitled blog: [github] pushおさらいには、ローカルの repository の .git/config を書き変えなさいとあります。.git/config を開くと

url=https://github.com/******/******.git

という箇所があるので、これを

url=git@github.com:**********/**********.git

と書き換えました。

これで上記エラーは解消されましたが、今度は

Permission denied (publickey).

と言われてしまいます。これもUntitled blog: [github] pushおさらいによれば、SSH での github への接続には公開鍵/秘密鍵のペアを用意し、公開鍵を自分の github アカウントに登録しておく必要があるとのこと。言われてみりゃ当たり前のことですね。

これについては ssh-keygen などで適切に鍵のペアを作成し、公開鍵は、自分の github アカウントのプロフィールの SSH Keys に登録します。秘密鍵はローカルの ~/.ssh/id_rsa に置いておくのが一番楽ちんですが、鍵を複数使っている場合に ~/.ssh/id_rsa を上書きしたくない場合がありますよね。そんな時は ~/.ssh/config に以下のような記述を追加します。新しい秘密鍵は ~/.ssh/id_rsa2 に置くとします。

Host github.com
  User git
  Port 22
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa2
  TCPKeepAlive yes
  IdentitiesOnly yes

これで github.com へのアクセスには、~/.ssh/id_rsa2 をデフォルトで使うようになります。

ところで上記2件は、そもそも https で clone したから発生した問題なんですよね。最初から SSH 経由で clone しておけば、鍵は設定されているはずだし、.git/config の url も SSH になるはずです。試しに同じ repository を

$ git clone git@github.com:**********/**********.git

したところ、.git/config は

url = git@github.com:**********/**********.git

となっていました。github へのアクセスは、SSH を使いましょうということで。

更にもう一つ。リモートの develop branch に push しようとして、

$ git push origin develop
Enter passphrase for key '/home/**********/.ssh/id_rsa':
To git@github.com:**********/**********.git
 ! [rejected]        develop -> develop (non-fast-forward)
error: failed to push some refs to 'git@github.com:**********/**********.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

こんなエラーが表示され、

$git pull --rebase

しても解消しない場合、リモートの develop branch とローカルの develop branch がきちんと繋がっていないようでした。ローカルの .git/config に

[branch "develop"]

セクションが見つからなかったりして、どうにもおかしいです。history を辿ったところ、最初に clone した後に

$git checkout -b develop

として、ローカルに develop branch を新たに作成していたようです。そりゃ git pull --rebace しても「git pull して merge しろ」と怒られるわけです。リモートの develop branch とは別物ですからね...。一旦ローカルの develop branch を削除して checkout し直すとかやれば良かったんでしょうけど、もう面倒くさかったので、既存のローカル repository とは別に新たに clone を作成し、改めて checkout し直してしまいました。

$ git clone git@github.com:**********/**********.git hoge
$ cd hoge
$ git checkout develop

そして改めて元の branch の変更を新しい branch に適用し commit、無事 push することができました。