XcodeをGitHub連携する
最近Udemyでこちらの講座を受講し始めました。
アウトプット用に自分でも何か作らないとなぁと思い、ひとまずXcodeとGitHubの連携を行いました。
動作環境
macOS Monterey 12.4
Git 2.32.1
Xcode 13.4.1
1. ローカルリポジトリ作成
①新規プロジェクトを作成
「Create a new Xcode project」をクリック
どのようなアプリケーションを作成するのかを選びます。
今回は特に何もいじらずに「Next」
「Product Name」を入力して「Next」
今回は「GitSample」としました。
次にプロジェクトの保管場所を聞かれるので、好きな場所を指定して「Create」を選択してください。 この時「Create Git repository on my Mac」にチェックを入れるとXcodeが自動でローカルリポジトリを作成してくれます。
②XcodeにGitの設定をする
初期状態だとローカルリポジトリの作成に失敗してしまうので、「Fix...」を選んでGitの設定をしましょう。
Author NameとAuthor EmailにそれぞれGitHubのユーザー名、GitHubに登録したメールアドレスを入力します。 他はお好みで設定してください。
こちらの設定は「Xcode > Preferences > Source Control > Git」から行うこともできます。
③ローカルリポジトリ作成
ここまで行うとローカルリポジトリの作成ができるようになるので、作成していきましょう。 「Source Control」から「New Git Repositories...」を選択します。
「Create」を選択するとローカルリポジトリが作成されます。
④ローカルリポジトリが作成されているか確認
「Show the Source Control navigator」を選択して、「Repositories」のところに画像のように表示されていればローカルリポジトリが作成できています。
2. .gitignoreを追加
①.gitignoreファイルを追加
まず「Show the Project navigator」をクリックします。そして画像のようにプロジェクトネームを右クリックし、「New File...」を選択してください。
下の方からEmptyを選んで「Next」
「Save As」のところに「.gitignore」と入力して「Create」
画像のような警告が表示されると思うので、「Use "."」を選択しましょう。
これで.gitignoreファイルが作成されるので、開いて中身を編集しましょう。 私はこちらに記載されているものを使わせていただきました。
.gitignoreを編集できたら一度コミットしておきましょう。 「Source Control > Commit...」を選択してください。
下の画像のような画面が表示されるので、コミットメッセージを入力してコミットしてください。
②既にコミットされてしまっているファイルをgitignoreの対象に含める
おそらくローカルリポジトリを作成した段階でこんな感じでInitial Commitが作成されていると思います。
そのため.gitignoreに設定を追加しただけではignoreされないので、ターミナルから下記コマンドを実行しましょう。
git rm -r --cached .
で一時的に全てのファイルをgitの対象から外すことができます。
その後にgit add .
とすることで、.gitignoreで指定したファイルのみを除外することができます。
この状態で下記コマンドを実行することで、先ほど.gitignoreを追加した際のコミットに変更を追加できます。
これで.gitignoreの追加は完了です。
3. リモートリポジトリ作成
①GitHubアカウントと連携
リモートリポジトリを作成するにはGitHubのアカウントと連携する必要があります。
その際にアカウント名とトークンを要求されるので、まずはGitHubのトークンを取得しましょう。
右上から「Settings」を選択
下の方の「Developer Settings」をクリック
「Personal access tokens」から「Generate new token」をクリック
「Note」にはわかりやすい名前などを入力し、「Expiration」は「No expiration」を選択します。
「Select scopes」は「repo」にチェックを入れてください。「repo」を選択しないとリモートリポジトリへのpushなどができなくなります。
「Generate token」をクリックするとトークンが表示されるのでテキストエディターなどにコピーしておきましょう。
次にXcodeの方でアカウントを追加していきます。 「Xcode > Preferences > Accounts」からアカウントを追加しましょう。「+」をクリックしてください。
「GitHub」を選択して「Continue」をクリックします。
GitHubのアカウント名と先ほど取得したトークンを入力して「Sign in」をクリックします。
うまくサインインができればGitHubアカウントとの連携は完了です。
②リモートリポジトリを作成
まずはローカルリポジトリが作成されているか確認した時と同じように「Show the Source Control navigator」をクリックして「Repositories」を選択してください。
その中のプロジェクトネームを右クリックして、「New "[Project Name]" Remote」を選択します。
「Create」をクリックするとリモートリポジトリが作成されます。
画像のように「origin」と表示されていればリモートリポジトリ作成成功です。
うまくいけばこれでリモートリポジトリへのpushまで行われるかと思います。
【Java】例外が発生しないメソッド = 万能とは限らない
Javaでオブジェクトを文字列に変換する方法ってたくさんありますよね。toString()
とかString.valueOf()
とか。中でもObjects.toString()
は例外も発生しないし、null
だった場合の値を自分で決められるし最強じゃんと思っていたのですが、何でもかんでもObjects.toString()
を使えばいいと言うわけではないことに気がつきました。
オブジェクト → 文字列変換メソッドの違いについておさらい
それぞれのメソッドの主な違いはnull
だった場合の動作です。
- 例外が発生する
toString()
Object obj = null; obj.toString(); // NullPointerExceptionが発生
- 例外が発生しない
String.valueOf
Object obj = null; String.valueOf(obj); // "null"と言う文字列が返る
- 例外が発生しないかつ
null
の時の値を自分で決められるObjects.toString()
Object obj = null; Objects.toString(obj); // "null"と言う文字列が返る Objects.toString(obj, "存在しません"); // 第二引数に指定した"存在しません"が返る
Objects.toString()
使っとけばOKなの?
一見便利そうなObjects.toString()
。実際Javaを使い慣れていない私は、とりあえず文字列に変換するときはObjects.toString()
を使っておけば安心なんだなと感じました。
ですが!
だからと言って何でもかんでもObjects.toString()
を使えばいいと言うわけではありません。
そもそもnull
を許容できない場合がある
DB保存するときにその値にNOT NULL制約が指定されている場合とか、APIにリクエスト送信するのに必須値になっている場合はnull
を許容できないですよね。そう言う場合って、外部からリクエストを受ける際に何らかの方法でnullチェックを行うと思います。
Spring Bootだったら@NotNull
アノテーションを付けたり。
その状態でいざ文字列に変換しようと言う時にnull
が入っている場合、考えられる状況は変換する前の処理で実装ミスがあるか予期せぬ不具合ぐらいしかないと思います。この場合ぬるぽが発生してくれた方がありがたくないでしょうか?
null
を許容できない場合はtoString()
で問題ない
null
を許容できない場合はそもそもそこでnull
になっていること自体がおかしいので、Objects.toString()
を使う必要はありません。むしろ、null
をスルーしてしまう上に、変な値を入れてしまうことになるので使わない方がいいです。ぬるぽが発生すれば実装ミスにいち早く気づけますし、catchしてログを出力することもできます。
なので、こう言う場合はぬるぽを恐れずにどんどんtoString()
を使っていきましょう。
まとめ
今までぬるぽを発生させるような実装をしてはいけない、と言う言葉を鵜呑みにして、とりあえずぬるぽが発生しないメソッドを選びがちでしたが、本質に気付くことができたような気がします。何事も馬鹿の一つ覚えにならないように気をつけていきたいですね。
MySQLを8.0にアップデートするのに紆余曲折あった
先日MySQLを5.6から8.0にアップデートしたら、2つほど苦労がありました。
1つめは、MySQLがアップデートされない! ← ただの凡ミス
2つめは、Sequel Proがクラッシュするようになった!
です。
1つめはまぁ置いといて、Sequel Pro使いにとって2つめは結構困りますよねぇ・・・。
でも、なんとかSequel ProでDB見れる方法があったので、そのお話です。
まずはMySQLをアップデート
前提として、MySQLはHomebrewを使ってインストールしてあります。
HomebrewでインストールしたMySQLのアップデートは以下の手順でできるようです。
ただ私の場合ここでbrew updateし忘れてしまったので、うまくいきませんでした。
通常なら、この後はテーブルのアップグレードを行って終了のようです。
これでパスワードの入力を求められたら入力して、Upgrade process completed successfully.と表示されたらOKなようです。
私の場合はbrew updateし忘れたことに気づかずに、MySQLを再インストールしてしまいました・・・。
Sequel Proがクラッシュするようになった!
MySQLを8.0にバージョンアップしてしまうと、Sequel Proが使えなくなります。
というか、Sequel ProがMySQL8.0に対応していないようです。
ですが、調べてみると、Sequel Pro NightlyというSequel Proのテスト版を入れるとMySQL8.0にも対応しているとのこと。
なので、Sequel Proを一度アンインストールして、Sequel Pro Nightlyをインストールしてみました。
公式サイトからダウンロードする場合はこちら↓
https://sequelpro.com/test-builds
Homebrewでインストールする場合はこちら↓
これで無事にSequel ProでDBを見れるようになりました。
ちなみにSequel Pro Nightlyはあくまでテスト版なので、どうしてもSequel Proがいい!という方以外は別のツールに乗り換えてしまった方が今後楽かもしれませんね・・・。
git rebase -i でコミットをまとめる
実務でgit rebase -i を使う必要がありそうだったので、予習のために使ってみました。
シチュエーション
- リモートにpush済み
- コードレビューをしてもらった後に修正コミットがたくさんできている
この状況でコミットをまとめていきます。
ただ、リモートにpush済みのコミットをgit rebase -iでまとめるのは本来NGです。しかし、自分が作業をしているブランチが「絶対に自分しかいじらない」のであればコミットをまとめても大丈夫な場合があります。例えば私の職場では、コードレビュー後にコミットを1つにまとめるという文化がありますが、コミットをまとめないで欲しいというところもあるようです。コミットをまとめたいと思った時は、チームに確認してからにしましょう。
それでは、実際にやっていきたいと思います。
コミットlogを確認
まずはコミットlogを確認します。
「リスト2を修正」と「リスト1を修正」が修正コミットです。この2つの修正コミットと「リスト1、リスト2を作成」を1つにまとめます。
git rebase -i でまとめたいコミットを指定
git rebase -i でまとめたいコミットを指定します。その際二つの指定方法があるので紹介します。
git rebase -i HEAD~<数字>
数字の部分にはまとめたいコミットの数を指定します。今回であれば3つのコミットをまとめたいので、3を指定します。
git rebase -i <コミットのハッシュ値>
こちらはコミットのハッシュ値を指定します。しかし、この指定方法には少し癖があります。HEADを使って指定する場合は「まとめたいコミットの数」とわかりやすいですが、コミットのハッシュ値を指定する場合は「まとめたいコミットの一つ前のハッシュ値」を指定します。例えば今回の場合だと、「リスト1を修正」〜「リスト1、リスト2を作成」までをまとめたいので、その前のコミットである「titleを記載」のハッシュ値を指定します。
git rebase -i を実行してコミットをまとめる
git rebase -i を実行します。
すると、以下のようにエディタが起動します。
インサートモードに切り替えて、修正コミットの「pick」を「s」に変更・保存します。エディタにも書いてありますが、この「s」はsquashのsです。
するとコミットメッセージを編集するためのエディタが開きます。
コミットメッセージは「リスト1、リスト2を作成」だけあればいいので、他の2つは削除します。
この変更を保存するとrebaseが完了です。以下のように表示されれば問題なくrebaseできています。
git log --oneline でlogを見てみると、コミットが1つにまとまっているのがわかると思います。
最後に、リモートにpushをします。ここで要注意なのが、rebaseをしたことでコミットのハッシュ値が変わっているので、pushができなくなっています。この場合、git push に-f オプションを付けて、強制的にpushすることができます。
これでGitHubを確認すると、コミットが1つにまとまっていると思います。
補足
git push -fなのですが、リモートの内容を破壊的に書き換えてしまうため、実はあまり多用することはおすすめできません。冒頭で、リモートのコミットをまとめるのが本来NGと書いたのは、実はこのgit push -f をする必要があるからでした。なので、git push -f を実行する時は、「絶対に自分以外いじらないブランチ」で作業をしているという確証のもと、実行するようにしてください。
リモートにpushする前に git pull --rebase を使ってみた
10月中旬頃から業務で本格的にプログラミングをし始めたのですが、gitが怖すぎるのでお試しでgit pull --rebaseを使ってみました。ただ使ってみただけだとすぐ忘れるので、せっかくなので書き残しておこうと思います。
やりたいこと
今回実現したいことは、git pull --rebaseを使って
リモートにpushする前に今作業しているブランチを最新の状態にする
です。
masterからブランチを切ってしばらく作業している内に、masterがどんどん更新されていって自分のブランチが古くなってきたなー、なんて時はありませんか?
そんな時にgit pull --rebaseを使うと便利です。
例えば、masterからhogeブランチを切って作業していたとしましょう。そのhogeブランチをリモートにpushする前にgit pull --rebaseを使います。そうすると、hogeブランチを最新のmasterに合わせてそこにhogeブランチのcommitを付け足すことができます。
つまり、最新のmasterからhogeブランチを切ったことにできます。
今回はこれを実際にやって行きたいと思います。
前提
- try-gitというディレクトリの中にsample.htmlがあります
- 同じmasterからbranchAとbranchBが作られています
- 先にbranchAの変更をmasterにマージします
この段階でbranchBの状態を、branchAがマージされた後のmasterに合わせていきます。
sample.htmlを編集
branchAとbranchBでsample.htmlを編集していきます。
まだ何もマージされていない状態のmasterブランチでは以下のようになっています。
master
この状態からまずはbranchAを以下のように編集します。
branchA
この変更をmasterにpushし、マージします。
次に、ブランチをbranchBに切り替え、sample.htmlを編集します。
branchB
branchBではまだpushはせず、commitだけしておきます。
git pull --rebaseでbranchAを最新のmasterに合わせる
今、masterではbranchAがマージされたのでsample.htmlは以下のようになっています。
master
リスト2が追加されていますね。branchBでもこの変更を反映したいです。
そこで活躍するのが、git pull --rebaseです。
まずはブランチをmasterに切り替え、ローカルのmasterを最新の状態にします。
これでローカルのmasterにもリスト2が追加されました。
次にbranchBに移動します。ここでgit pull --rebaseを実行します。
コンフリクトが起きていなければ問題なく成功するはずです。
エディタでsample.htmlを確認すると、以下のようになっているかと思います。
branchBにもリスト2が追加されました。
branchBをリモートにpushすると、branchAをマージ後のmasterからbranchBを切ったことになっているのがGitHub上でわかると思います。
せっかくなのでコンフリクトさせてみる
今回コンフリクトさせた状態でgit pull --rebaseを試してみたので、そちらについてもまとめておこうと思います。
コンフリクトした状態でgit pull --rebaseを実行すると以下のようになると思います。
これはgit pull --rebaseが失敗しています。
エラーメッセージをよく見てみると、
Resolve all conflicts manually, mark them as resolved with "git add/rm <conflicted_files>", then run "git rebase --continue".
となっています。
これを簡単に訳すと
コンフリクトを解消してgit add、もしくはgit rmを実行してgit rebase --continueを実行してね
ということです。
なので、言われた通りにやってみましょう。
Visual Studio Codeを使っている場合、この段階でエディタを開くとコンフリクト解消画面になっていると思うので、コンフリクトを解消してgit addします。
そして、git rebase --continueを実行しましょう。
となっていればgit pull --rebaseの完了です。
ただ、コミットを複数している状態だと何度かコンフリクトを修正しなければいけないことがあるようです。これは、git pull --renbaseの仕様によるものなのですが、ここでは説明を割愛させていただきます。
こちらにかなり詳しく書いてあるので、ぜひ一度読んでみることをお勧めします!
https://www.clear-code.com/blog/2016/9/2.html
コンフリクトした場合の対処方法だけではなく、「--rebase」なしのgit pullとの違いなどもまとめられています。
suとsudoが使えなくなってOSを再インストール
とあるコマンドを実行したらsudoとsuが使えなくなり、詰んでしまったので二度とこのような悲劇を繰り返さないための覚え書きです。
sudo chown -R コマンド
私を絶望の淵に叩き落としたのがこちらのコマンドです。
上記のようにすることでディレクトリやファイルの所有者を変更することができます。これに-Rというオプションをつけると指定したディレクトリ以下のファイルやディレクトリの所有者を全て変更することができます。一括で変更できるので便利だなーと思っていたのですが、これを実行してはいけないディレクトリがあります。私はそれを知らずにやらかしてしまい、sudoとsuが機能しなくなってしまいました。
usrディレクトリにchownコマンドはNG
このディレクトリに対して上記のコマンドを実行するとどうなるか。
私のように詰みます。
つまり、suとsudoが使えなくなります。
では、なぜそうなってしまうのでしょうか?私はそこをちっともわかっていませんでした。
usrディレクトリ
usrディレクトリはルートディレクトリの直下にあります。そしてこのusrディレクトリ以下にはbinというディレクトリがあります。このbinディレクトリに移動してlsコマンドを実行すると、以下のように色々と出てきます。
赤く囲まれた部分に注目してください。suとsudoがあります。実はこれの所有者を変更してしまうと、suやsudoを使ってもルートユーザーに成り代わることができなくなります。ここで何もわからない私はまた所有者をrootに戻せばいいのでは?と思ってしまいましたが、当然そんなことはできません。そもそもそれができるのはルートユーザーだけだからです。これでルートユーザーしか操作できないコマンドなどを全く使うことができなくなってしまいました。
OSを再インストール
もう残された手段はこれしかないので実行しました。
そうしたら無事に解決できました。OSを再インストールしてもデータが残ると言うことを知らなかったため、今まで作ったものをGitHubに上げたりしてからやりましたが、結局全てもと通り。全部しっかり残ってました。ただ消えてしまう可能性もゼロではないみたいなので、バックアップを取ってから再インストールした方が安全ではあるみたいです。今回の場合は外付けのハードにバックアップ取らないといけませんが・・・。
まとめ
sudo chownコマンドを使うときは慎重に!
一時はどうなることかと思いましたが、無事に復活して一安心です。私の場合、これを直そうとしてターミナルが使えなくなるところまで行ってしまったので、私のMacBook終わったんじゃないかと思ってかなり落ち込みました。でも、TECH::EXPERTのメンターさんのお力添えのおかげでまた勉強できるようになりました。こんな失敗やらかす人、私以外にいないかもしれませんがご一読いただいた皆様はどうかお気をつけてください。
unicornでRailsのサーバーが2回目以降立ち上がらない!!
ブログ始めたはいいけど、全然記事書いてなかったのでたまにはと思い書いてみます。
私は今TECH::EXPERTというプログラミングスクールに通っていて、カリキュラムの中でunicornを使ってRailsのサーバーの立ち上げをしたのですが、1回目は上手くいったのに2回目はすぐにコマンドが終了してしまう・・・というエラーに悩まされたので、それについて書いていきます。
unicornでRailsのサーバーが立ち上がらない・・・
原因は色々あるみたいですが、私の場合はこちらの記事に書いてある通りでした。
https://qiita.com/Coconew5/items/2f4ba976e58da9c1ec22
ただ、ここにたどり着くまでに苦労したことがあったのでそれを記事として残しておこうと思います。
lessコマンドでlog/unicorn.stderr.logの中身を確認する
カリキュラム通りにunicornの設定をするとlog/unicorn.stderr.logにエラーを記録する設定になっているそうなので、以下のコマンドを実行しました。
そうすると以下のように色々と表示されます。
しかし、これの見方が私にはよくわかりませんでした。唯一分かっていたのが4行目のEで始まる部分。この行がエラーを表しています。これはまだ最初の数行なのですが、わかる部分がそこしかないので他の部分は特に見ずにここに書いてある「Can't connect to local MySQL server through socket」をひたすら調べました。
こちらのエラーはmySQLに関するエラーなのですが、既にカリキュラムの方で解決していたはずのものなので「何でまた・・・」と思いながら色々と試しました。
しかし、何をやってもサーバーが立ち上がることはありませんでした。
catコマンドで確認する
「これはもうメンターさんを頼るしか・・・」と諦めかけた時、カリキュラムの中に「lessコマンドかcatコマンドでunicorn.stderr.logを確認する」と書いてあるのを見つけ、catコマンドを試してみようと思い以下のコマンドを実行しました。
そうしたらlessで表示した時には見つけられなかった[Argument error]となっている行を発見しました。残念ながらその時のエラー文を残していないのですが、「〇〇〇〇・・・ 長々と書かれている何かのパス 〇〇〇〇[Argument error]」となっていました。そこで「〇〇〇〇[Argument error]」を丸々コピペして検索してみたところ、上記の記事を見つけ見事解決・・・といきたいところなのですが、ここでも少し引っかかってしまいました。
ps aux | grep unicornコマンド
上記記事を参考にps aux | grep unicornコマンドでunicornのプロセスを確認してみました。そうしたら以下のように表示されました。
「xxxxx」の部分には数字が書いてあります。
そして、記事によるとこの中のどれかのxxxxxのプロセスが残ってしまっているということでした。しかしどれが残ってしまっているプロセスなのかよくわからずまたしばらく悩んでしまい、他の原因を探り始めてまた解決への道から遠ざかってしまいました。
当然解決策は見つからず、途方に暮れながら何となく[Argument error]の部分を眺めていると、偶然解決への糸口を見つけることができました。
答えは[Argument error]の先頭部分にあった
[Argument error]の部分を先頭からよくみてみると、どこかでみたような数字が書いてあり、それが「既に実行済みですよ」のようなニュアンスの英語が書いてありました。もしかしてと思ってps aux | grep unicornの結果をみてみると、同じ数字を見つけ、「これだ!」と思って以下のコマンドを実行しました。
xxxxの部分には先ほど見つけた数字が入ります。
そうしたら無事にサーバーを立ち上げることができました!
まとめ
結局のところ、[Argument error]の冒頭部分の〇〇〇〇のところに全て書いてあったということですね。
エラー文はしっかり読まないといけないなーと思いました。