20201019のGitに関する記事は10件です。

CI/CDをkatacodaで体験(初心者向け) - Part7(Finding Bugs)

CI/CD入門

このぺーじでは、katacodaと呼ばれる「ブラウザから無料で勉強用のインスタンスを起動できるWebサービス」を利用してCI/CDを実践します
内容は上記リンクに沿うので、不明点があればそちらへどうぞ

Gitのバージョン管理について - Scenario 7 - Finding Bugs

ここでは、CI/CDとして欠かせないGitによるバージョン管理について学習します
このシナリオで学習することをさっと確認する場合は概要を確認
理解に間違い等がございましたら、ぜひご指摘ください

概要

  • git diff <hashA> <hashB>で特定のバージョンを比較
  • git log <option>で様々なログの表示が可能
    • option = --oneline:一行で各commitコメントを確認
    • option = -p:↑に加えて「誰が」、「いつ」、「どのような」変更を加えたか確認
    • option = --grep="(hoge)":特定のcommitコメントが入ったバージョンのみ表示
  • git bisectで誤りのあるcommitを二分探索
    1. git bisect startで探索開始
    2. git bisect bad/good <hash>で正誤を定義
    3. badおよびgood内のランダムなバージョンで正誤を確認
    4. 正誤に対して、git bisect bad/goodで評価
    5. 3,4を繰り返して誤りのあるcommitを発見
    6. git bisect resetで探索終了
  • git blameでファイルの特定のセクション(各行)で誰が最後に作業したか確認

Git Diff Two Commits

git diffは最も簡単なコミットの差分を出力する方法
同じファイルに対してバージョンごとの差分を見る場合は以下のような使い方をする

$ git diff HEAD~2 HEAD
ESC[1mdiff --git a/list.html b/list.htmlESC[m
ESC[1mindex 96e99d0..9f53aec 100644ESC[m
ESC[1m--- a/list.htmlESC[m
ESC[1m+++ b/list.htmlESC[m
ESC[36m@@ -2,4 +2,6 @@ESC[m
 <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>ESC[m
 <li>Aliquam tincidunt mauris eu risus.</li>ESC[m
 <li>Vestibulum auctor dapibus neque.</li>ESC[m
ESC[32m+ESC[mESC[32m<li>Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in,   //変更箇所
ESC[32m+ESC[mESC[32m<li>Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu   //変更箇所
 </ul>ESC[m

HEAD~2は、現在作業をしているbranch(HEAD)から二つ前のバージョンを示している
つまりここでは、現在作業をしているbranchとそのbranchが二つ前にcommitした際の結果を比較
git diffの結果を理解するため、git blame <hash> fileというコマンドで各バージョンごとの変遷を確認

$ git blame HEAD list.html
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 1) <ul>
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 2) <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 3) <li>Aliquam tincidunt mauris eu risus.</li>
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 4) <li>Vestibulum auctor dapibus neque.</li>
eddb7535 (Katacoda Scenario 2020-10-19 11:01:16 +0000 5) <li>Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, p
93701df5 (Katacoda Scenario 2020-10-19 11:01:16 +0000 6) <li>Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu v
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 7) </ul>
$ git blame HEAD~1 list.html
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 1) <ul>
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 2) <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 3) <li>Aliquam tincidunt mauris eu risus.</li>
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 4) <li>Vestibulum auctor dapibus neque.</li>
eddb7535 (Katacoda Scenario 2020-10-19 11:01:16 +0000 5) <li>Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, p
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 6) </ul>
$ git blame HEAD~2 list.html
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 1) <ul>
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 2) <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 3) <li>Aliquam tincidunt mauris eu risus.</li>
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 4) <li>Vestibulum auctor dapibus neque.</li>
^b22862a (Katacoda Scenario 2020-10-19 11:01:16 +0000 5) </ul>
$ git blame HEAD~3 list.html
fatal: bad revision 'HEAD~3'

上記の結果からlist.html現在も合わせて3つのバージョンを持っていることが判明
第一世代では、<ul>~</ul>までの5行がhash値"b22862a"というバージョンで管理されている
第二世代では、<li>Morbi~の5行目がhash値"eddb7535"というバージョンで管理されている
第三世代では、<li>Praesentの6行目がhash値"93701df5"というバージョンで管理されている

Git Log

ここでは、git logを用いて該当レポジトリ内での変遷を様々な粒度で確認
git log --onelineはコミットメッセージとhash値を簡潔に確認

$ git log --oneline
ESC[33m93701dfESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Final Item
ESC[33meddb753ESC[m New Item
ESC[33mb22862aESC[m Initial commit of the list

git log -pは上記の内容に加え、「誰が」、「いつ」、「どのような」変更を加えたかlessコマンドで表示
オプションとして-n 2を付けることで、現在のhash値から何世代前まで表示するか指定可能(この場合、HEAD,HEAD~1)

$ git log -p
ESC[33mcommit 93701df5e4a964c2bf483e0d171528684699d0f4ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33
Author: Katacoda Scenario <scenario@katacoda.com>
Date:   Mon Oct 19 11:01:16 2020 +0000

    Final Item

ESC[1mdiff --git a/list.html b/list.htmlESC[m
ESC[1mindex def310d..9f53aec 100644ESC[m
ESC[1m--- a/list.htmlESC[m
ESC[1m+++ b/list.htmlESC[m
ESC[36m@@ -3,4 +3,5 @@ESC[m
 <li>Aliquam tincidunt mauris eu risus.</li>ESC[m
 <li>Vestibulum auctor dapibus neque.</li>ESC[m
 <li>Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a.</li>ESC[m
ESC[32m+ESC[mESC[32m<li>Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros e
 </ul>ESC[m

ESC[33mcommit eddb7535cb88cd4000673585e2981be06cfe2375ESC[m
Author: Katacoda Scenario <scenario@katacoda.com>
Date:   Mon Oct 19 11:01:16 2020 +0000

    New Item

git log --grep="Initial"はコミットの文字列で表示するコミットを制限することができる

$ git log --grep="Initial"   //"Initial"とコメントされているcommitを表示
ESC[33mcommit b22862af361944b5ff365b094011c875c798f4efESC[m
Author: Katacoda Scenario <scenario@katacoda.com>
Date:   Mon Oct 19 11:01:16 2020 +0000

    Initial commit of the list

Git Bisect

git bisectは誤った変更等、間違いを含んだcommitを特定することが可能
今回のシナリオでは、list.html内のhtmlタグが未入力となってcommitされたバージョンを特定する

0.初めにgit logで状態を確認

$ git  log --oneline
ESC[33mbbb550fESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Adding Pel
ESC[33mefb15afESC[m Adding Quisque
ESC[33m9c5469bESC[m Adding Vestibulum
ESC[33m063f446ESC[m Final Item
ESC[33m4167e39ESC[m New Item
ESC[33m2ae3793ESC[m Initial commit of the list

1.git bisect startで探索を開始

2.git bisect bad (HEAD)で間違った結果を定義
間違った変更がいつcommitされたか探索するために、「正しい結果のcommit」、「間違った結果のcommit」を定義する必要がある
ここでは、「間違った結果のcommit」と定義

3.git bisect good HEAD~5
ここでは、「正しい結果のcommit」と定義
hash値は正しいと確証が得られるバージョンであればより新しいバージョンでも問題ない

4.「正しい結果のcommit」と「誤った結果のcommit」の間のランダムなバージョンに対して結果の正誤を確かめる

Bisecting: 2 revisions left to test after this (roughly 1 step)
[063f4464b45cbc3f2bb3c30ca33ef3c579b3318a] Final Item   //ランダムにHEAD~3のバージョンが選択された
$ cat list.html   //htmlタグ記述漏れの確認(目視)
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li>Vestibulum auctor dapibus neque.</li>
<li>Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a.</li>
<li>Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat.</li>
</ul>
$ git bisect good   //結果が正しいことをgitに伝える

HEAD~3時点では、list.htmlに記述漏れは存在しない(=HEAD~4以前の探索は不要

5.4の繰り返し

Bisecting: 0 revisions left to test after this (roughly 1 step)
[efb15afb8108df6760557a183592321cd803d9fc] Adding Quisque   ////ランダムにHEAD~1のバージョンが選択された
$ cat list.html
<ul>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li>Vestibulum auctor dapibus neque.</li>
<li>Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a.</li>
<li>Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat.</li>
Vestibulum auctor dapibus neque   //htmlタグの記述漏れを発見
<li>Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed.</li>
</ul>
$ git bisect bad   //結果が間違っていることをGitに伝える

4と5の探索から誤りの混入したcommitはHEAD~3とHEAD~1の間
すなわち、HEAD~2の"Adding Vestibulum"のcommit時と断定

6.探索終了

$ git bisect reset
Previous HEAD position was 9c5469b Adding Vestibulum
Switched to branch 'master'
$ git branch -va
* ESC[32mmasterESC[m bbb550f Adding Pellentesque

確認のため、以下に各バージョンのlist.htmlを順に表記
一つずつバージョンを遡って確認するより、手間がかからないことを実感できるはず

$ git blame HEAD list.html
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000  1) <ul>
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000  2) <li>Lorem ipsum dolor sit amet, consectet
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000  3) <li>Aliquam tincidunt mauris eu risus.</l
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000  4) <li>Vestibulum auctor dapibus neque.</li>
3dd56b54 (Katacoda Scenario 2020-10-19 13:04:18 +0000  5) <li>Morbi in sem quis dui placerat ornare
59b68ac6 (Katacoda Scenario 2020-10-19 13:04:19 +0000  6) <li>Praesent dapibus, neque id cursus fau
6c0c7e6a (Katacoda Scenario 2020-10-19 13:04:42 +0000  7) Vestibulum auctor dapibus neque
3abf424c (Katacoda Scenario 2020-10-19 13:04:42 +0000  8) <li>Quisque sit amet est et sapien ullamc
45b0dc5d (Katacoda Scenario 2020-10-19 13:04:42 +0000  9) <li>Pellentesque fermentum dolor</li>
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 10) </ul>
$ git blame HEAD~1 list.html
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 1) <ul>
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 2) <li>Lorem ipsum dolor sit amet, consectetu
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 3) <li>Aliquam tincidunt mauris eu risus.</li
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 4) <li>Vestibulum auctor dapibus neque.</li>
3dd56b54 (Katacoda Scenario 2020-10-19 13:04:18 +0000 5) <li>Morbi in sem quis dui placerat ornare.
59b68ac6 (Katacoda Scenario 2020-10-19 13:04:19 +0000 6) <li>Praesent dapibus, neque id cursus fauc
6c0c7e6a (Katacoda Scenario 2020-10-19 13:04:42 +0000 7) Vestibulum auctor dapibus neque
3abf424c (Katacoda Scenario 2020-10-19 13:04:42 +0000 8) <li>Quisque sit amet est et sapien ullamco
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 9) </ul>
$ git blame HEAD~2 list.html
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 1) <ul>
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 2) <li>Lorem ipsum dolor sit amet, consectetu
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 3) <li>Aliquam tincidunt mauris eu risus.</li
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 4) <li>Vestibulum auctor dapibus neque.</li>
3dd56b54 (Katacoda Scenario 2020-10-19 13:04:18 +0000 5) <li>Morbi in sem quis dui placerat ornare.
59b68ac6 (Katacoda Scenario 2020-10-19 13:04:19 +0000 6) <li>Praesent dapibus, neque id cursus fauc
6c0c7e6a (Katacoda Scenario 2020-10-19 13:04:42 +0000 7) Vestibulum auctor dapibus neque
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 8) </ul>
$ git blame HEAD~3 list.html
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 1) <ul>
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 2) <li>Lorem ipsum dolor sit amet, consectetu
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 3) <li>Aliquam tincidunt mauris eu risus.</li
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 4) <li>Vestibulum auctor dapibus neque.</li>
3dd56b54 (Katacoda Scenario 2020-10-19 13:04:18 +0000 5) <li>Morbi in sem quis dui placerat ornare.
59b68ac6 (Katacoda Scenario 2020-10-19 13:04:19 +0000 6) <li>Praesent dapibus, neque id cursus fauc
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 7) </ul>
$ git blame HEAD~4 list.html
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 1) <ul>
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 2) <li>Lorem ipsum dolor sit amet, consectetu
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 3) <li>Aliquam tincidunt mauris eu risus.</li
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 4) <li>Vestibulum auctor dapibus neque.</li>
3dd56b54 (Katacoda Scenario 2020-10-19 13:04:18 +0000 5) <li>Morbi in sem quis dui placerat ornare.
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 6) </ul>
$ git blame HEAD~5 list.html
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 1) <ul>
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 2) <li>Lorem ipsum dolor sit amet, consectetu
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 3) <li>Aliquam tincidunt mauris eu risus.</li
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 4) <li>Vestibulum auctor dapibus neque.</li>
^d9670fb (Katacoda Scenario 2020-10-19 13:04:18 +0000 5) </ul>

Git Blame

git blameはファイルの特定のセクション(各行)で誰が作業したかを知ることができます
また、行数が多いファイルに対しては、確認したい行を指定することが可能です

$ git blame list.html
^2ae3793 (Katacoda Scenario 2020-10-19 13:41:30 +0000  1) <ul>
^2ae3793 (Katacoda Scenario 2020-10-19 13:41:30 +0000  2) <li>Lorem ipsum dolor sit amet, consectet
^2ae3793 (Katacoda Scenario 2020-10-19 13:41:30 +0000  3) <li>Aliquam tincidunt mauris eu risus.</l
^2ae3793 (Katacoda Scenario 2020-10-19 13:41:30 +0000  4) <li>Vestibulum auctor dapibus neque.</li>
4167e39f (Katacoda Scenario 2020-10-19 13:41:30 +0000  5) <li>Morbi in sem quis dui placerat ornare
063f4464 (Katacoda Scenario 2020-10-19 13:41:30 +0000  6) <li>Praesent dapibus, neque id cursus fau
9c5469be (Katacoda Scenario 2020-10-19 13:41:47 +0000  7) Vestibulum auctor dapibus neque
efb15afb (Katacoda Scenario 2020-10-19 13:41:47 +0000  8) <li>Quisque sit amet est et sapien ullamc
bbb550f2 (Katacoda Scenario 2020-10-19 13:41:47 +0000  9) <li>Pellentesque fermentum dolor</li>
^2ae3793 (Katacoda Scenario 2020-10-19 13:41:30 +0000 10) </ul>
$ git blame -L 6,8 list.html   //6行目から8行目を確認
063f4464 (Katacoda Scenario 2020-10-19 13:41:30 +0000 6) <li>Praesent dapibus, neque id cursus fauc
9c5469be (Katacoda Scenario 2020-10-19 13:41:47 +0000 7) Vestibulum auctor dapibus neque
efb15afb (Katacoda Scenario 2020-10-19 13:41:47 +0000 8) <li>Quisque sit amet est et sapien ullamco
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

yps並走備忘録 Task6 既存コードからアプリケーションを作成する(To Do List)

いよいよ本格的にWebアプリケーションを作成します。
今回の開発ではWebアプリの定番CRUD操作も入ってきますし、Laravelのミドルウェアも使います。

また開発でも機能単位での開発になるのでこのタスクからは本格的にgit-flowを使うことが推奨されています。

参考:git-flow図解

git-flowはWeb開発の現場では当たり前に使われているそうなので、この機会に慣れておきたいですね!

注意事項

2020年/20/19日現在Laravel 8のリリースにより最新版のLaravelを導入した場合本記事やリンク先の参考記事の通りの実装だと動かなくなる可能性があるのでLaravelのプロジェクト作成時には以下のコマンドで7.25.0で作成することをおススメします。
cd /var/www/html //まずはアプリを公開するnginxの公開ディレクトリに移動
composer create-project --prefer-dist laravel/laravel myapp2 "7.25.0" //Laravelを7.25.0バージョンで構築します

まずは認証系を作っていきましょう

下記参考記事をなぞりながら認証機能を導入していきます

参考:Laravel 6.x laravel/uiを利用してbootstrap 4を適用する

cd myapp2
composer require laravel/ui "2.*" //フロント側のログインのテンプレートを一発で導入できるLaravel/uiを入れます
npm install 
php artisan ui bootstrap --auth
npm install cross-env
npm install
npm run dev

npm run devでエラーが出た場合は下記コマンドで対応
rm ./package-lock.json
rm -rf ./node_modules/
npm install

補足: npm run devは導入したjsやcss等のライブラリやフレームワークをビルドするコマンド、上記の場合で言うとimportしたbootstrap関連のscss,jsファイルなどをまとめていい感じにpublicに配置してくれます。
なお、ビルドには多少時間かかるので面倒な場合は一先ずbladeとかに書きなぐっておいて、後ほどSassやjsファイルに突っ込んでビルドするのもいいかもしれないです。

参考:
dotenvとcross-envで環境変数を設定して開発環境の処理を切り替える
npm run devに関して:Readouble

ここまでやったら一先ず新しく構築したアプリへ公開ディレクトリを移しておきましょう

sudo vi /etc/nginx/conf.d/default.conf

/var/www/html/yps/public;
      ↓
/var/www/html/myapp2/public;

※3か所くらいあります

WebサーバーとPHP-FPMを再起動
sudo systemctl restart nginx && sudo systemctl restart php-fpm
キャッシュクリア
php artisan cache:clear &&php artisan config:clear && php artisan route:clear &&php artisan view:clear
composer clear-cache && composer dump-autoload --optimize
※上記のコマンドは割と使うので.bashrc等でエイリアスに指定しておくのがおススメ

オーナーとディレクトリ権限変更
sudo chown -R centos:nginx /var/www/
sudo chmod -R 777 storage/ bootstrap/cache/
※このコマンドも新しいファイルやディレクトリ作ったり、ファイルを移動したりすると稀に使うのでエイリアス登録推奨

ここまでやると画面右上にLOGIN REGISTERという認証用のリンクが出ているはずです。



いざ!アプリ構築!
いよいよ、アプリを構築していきます。
とはいえ、いきなりだと何から手を付けていいか分からないと思うので、最初はハンズオンで…

php artisan make:model Task -m //-mオプションでマイグレーションファイルも同時に作成します

参考:Readouble:マイグレーション
(ザックリ言うとDBとやり取りするのを任せるファイル、このファイルを通じてLaravelではSQLのデータ型やカラムの構造などを含めたデータベース操作を行います)

アプリで使うデータベースを作成
mysql -u root -p
create database myapp2db;
exit

作成したDBをLaravelと連携させます
vi .env

//下記を編集
DB_DATABASE=myapp2db                                                                                
DB_USERNAME=root
DB_PASSWORD="パスワード"

設定が終わったら実際に接続します
php artisan migrate
//念のためテーブルがちゃんと作られているか確認
mysql -u root -p -D myapp2db
show tables;

※tasksテーブルが作成されています
+--------------------+
| Tables_in_myapp2db |
+--------------------+
| failed_jobs        |
| migrations         |
| password_resets    |
| tasks              |
| users              |
+--------------------+

あとは下記参考リンクのコードを模写しながらタスク管理アプリを実装します。
なお、本タスクのクリア要件は

  • ユーザー登録後に送信されたメールで認証したユーザーのみログイン可能
  • ログイン後にタスク一覧画面に変遷
  • タスク一覧及び個別画面はログインしていないと見られない
  • ログアウト機能の実装

だそうです。

参考:
サンプルソース(GitHub)
※サンプルソースに一部修正が必要な個所があります↓
クリア要件:画面の変遷

補足

gmailによる認証はセキュリティの関係でハマりやすいのと、別アカウントを取る手間もあるのでおススメは下記ブログで紹介されているmailtrapというWebサービス。メール関係の実装のテストなんかに気軽に使えて便利です。

参考:2020-09-05 yps学習記録その6

簡単にできてしまった方は追加機能開発をしてみるのがおススメです。(結構沼れます)
- タスクのソート機能
- 期限を過ぎたタスクの色変更
- メールでの期限通知
- 検索機能
- ユーザーにタスクを紐づけ
- その他モロモロ

参考:Laravel-Todoアプリに一週間機能追加チャレンジ

私は
- ソート機能(ライブラリ使用)
- 表示色変更
- ユーザーに紐づけ(自分の物しか見られない)
上記に加えて下記参考リンクのカレンダー機能をガッチャンコしてみました(これがかなりの沼だった…)

参考:Laravelの教科書:カレンダーアプリを作ろう

具体的には上記参考リンクの臨時休業の設定に当たる部分を流用して簡易的なシフトの入力(日勤、夜勤、休み)を入力できるようにしました。
もう少し発展させて管理者画面から操作できるようにしてあげればシフト管理アプリとしても使えそうですね…今後の課題として作り込みをゆっくりやっていきたいと思います。

Task6は結構カスタマイズのしがいもあると思うので、是非色々自分好みのカスタマイズを行ってみましょう!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

peco を使ってブランチのチェックアウトを行う (リモートブランチ と ローカルブランチ) 改良版

peco を使ってブランチのチェックアウトを行う (リモートブランチ と ローカルブランチ) 改良版

https://qiita.com/m-tmatma/items/8285a6cace98cfdb5db9 の改良版です。

改善版1

git checkout $(git branch -a | grep -v "/HEAD" | peco | sed -r "s#^\\s+remotes/origin/##")

改善ポイント

https://qiita.com/tommy_aka_jps/items/6ce68f564cb3802ca9b0 の記事で以下で proj/exampleWorks のリモートブランチをチェックアウトできるとあったのでそれを反映して簡略化しました。

git checkout proj/exampleWorks
  • git branch -a でリモートブランチとリモートブランチを両方列挙します。
  • sed で git branch -a を使ったときにリモート名のところを削除します。
  • git checkout proj/exampleWorks でリモートブランチをチェックアウトできることを利用します。

改善版2 (git リポジトリの外で実行した場合に git checkout を実行しない版)

alias co='git rev-parse --is-inside-git-dir > /dev/null 2>&1 \
  && git checkout $(git branch -a | grep -v "/HEAD" | peco | sed -r "s#^\\s+remotes/origin/##" | sed -r "s#^\*\s+##")'

改善ポイント

  • git リポジトリの外で実行した場合に git checkout を実行しない
  • 現在いるブランチを選択してもエラーにならないようにする。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SONYのNNCチャレンジ(音声データを用いてAudioStockに役立つものを作れ)に応募する。

0. 私は誰?

 数学科博士課程の院生です。専門は解析であり計算機代数やまして機械学習の知識はほとんどありませんが研究のために計算機を使うことはあり、Pythonだけはなんとか使うことができます。第一回のNNCチャレンジ(画像分類)にも参加しましたが明確な目的意識がなく、知識不足もあってめぼしい成果物は得られませんでした(提出だけはしました)。
 

1. SONY NNCチャレンジとは

 SONYが運営する機械学習の統合開発環境「Neural Network Console (NNC)」を使った機械学習のコンテストです。
コンテストの運営はSONYと株式会社ledgeさんらしいです。概要は以下のURLにあります。
https://nnc-challenge.com/

2. 今回のテーマ

 今回の公募で扱うのは音声データということで、自分の中でやりたいことがはっきり決まりました。私はいわゆる"音ゲー"が趣味で、普段から聞いているのはほとんどゲーム楽曲です。その中でも特に大好きな作曲家であるt+pazolite("とぱぞらいと"と読みます。)さんは非常に独特な音楽を作ります。その独特な世界観は機械にも判別できるのではないか、というのが今回のテーマです。つまり「機械はt+pazolite曲を判別できるか」ということです。コンテストテーマに即した言い方をすれば、「お気に入りの楽曲を学習してユーザーに新しい曲をレコメンドする機能を作る」でしょうか。すでにAmazon Prime Musicなどではユーザーに楽曲をお勧めする機能は実装されています。"チャレンジ"としては独自性がないかもしれませんが自分の実力とコンテストの期限を鑑みるとあまりテーマ選択に時間をかけられません。何より自分が興味のあるテーマの方がチャレンジにも気合が入ります。今回はこちらのテーマでいきます。

3. 何が必要か

 私の今回のテーマは入力された楽曲がt+pazoliteさん(以下"とぱぞ")によるものかどうか判定する"識別器"を作ることです。つまり何らかの楽曲データを入力したとき、"0"("とぱぞ曲"ではない)または"1"("とぱぞ曲"である)を返すプログラムを(機械が自ら学習して)作ることになります。どんな曲が"0"でどんな曲が”1”かを"0"または"1"のラベル付きの大量の楽曲たちで学習させ、未知の曲に対してこの判定ができるプログラムを作るのです。NNCでは入力は配列なので楽曲データを何らかの形で配列にする必要があります。wav形式の音楽ファイルが配列形式なので楽曲をこの形式に変換します。
(NNC公式ドキュメント、https://support.dl.sony.com/wp-content/uploads/sites/2/2017/11/19120828/starter_guide_sound_classification.pdf)
また、入力データの配列はすべて同じ形の配列であることが必要です。今回はNNC公式から一万曲以上の楽曲データが同じサイズのwav形式で配布されたので(学習用データ提供:Audiostock)こちらに合わせて"とぱぞ曲"を整形します。

4. 楽曲データの整形

 "1"判定のデータとしてとぱぞ曲を整形します。手持ちのとぱぞ曲はm4a形式だったのでwav形式に変換する必要があります。こちらの投稿を参考にPythonでプログラミングしました。
(M4AをWAVに変換する(その逆も)
https://wave.hatenablog.com/entry/2017/01/29/160000)
 楽曲がwav形式に変換できたら、次はサイズを提供された学習用データと同じサイズに揃えます。楽曲の配列サイズは1.ステレオかモノラルか、2.サンプリングレート、3.楽曲の長さ(秒数)
によって決まります(NNC公式ドキュメント参照)。ステレオモノラルに関しては提供データと手持ちデータが両方ともモノラルだったので変える必要はありませんでした。サンプリングレートに関しては公式配布のものが8kHz、手持ちの楽曲が48kHzだったのでダウンサンプリングする必要があります。ただし、単純にサンプリングレートを6分の1にすると間延びした(遅くなった)楽曲データが生成されるので方法は選ぶ必要があります。こちらの記事の方法で簡単に目当てのサンプリングレート変換を達成できました。
(Downsampling wav audio file
https://stackoverflow.com/questions/30619740/downsampling-wav-audio-file)
最後に楽曲の長さを揃えます。提供データはすべて24秒に整形されていたので手持ち楽曲も24秒に"切りそろえ"ます。こちらの記事を参考に出力ファイルの名前を元楽曲の名前に通し番号を振ったものに変え、フォルダ内のすべての楽曲に対して同様の操作を繰り返すプログラムを書きました。
(【Python】WAVファイルを等間隔に分割するプログラム【サウンドプログラミング】
http://tacky0612.hatenablog.com/entry/2017/11/21/164409)

5. アノテーションCSVファイルの作成

 NNCにデータを入力するために、最後にアノテーション作業を行います。アノテーションとは各楽曲に対してそれが"1"であるか"0"であるかのラベルをつけることです。NNCではこの入力を楽曲のパスとその曲に対応する"0"または"1"を書き込んだCSVファイルとしてアップロードすることで行います。楽曲データはCSVに書き込んだパスから自動的にアップロードされます(NNC公式ドキュメント参照)。Pythonで楽曲の入ったフォルダからパスを取得し、CSVに書き出すプログラムを書きました。"とぱぞ曲"と"そうでない曲"を別々のフォルダに配置して、とぱぞ曲のパスに”1”を、そうでない曲に"0"を対応させました。
私はCSVを作った時点で楽曲の順番をシャッフルしましたがNNC上で上がってきたデータをシャッフルする機能があるので特に必要なかったです。

6. 学習

 データが揃ったのでいよいよ学習です。なのですがこの時点で締め切り当日の午後2時になっていました。学習にもそれなりの時間がかかることはわかっていたのでNNCのサンプルプロジェクトから音声データ用のものを借りて、入出力を今回のテーマに合わせたものを使うことにしました。具体的にはwav_keyboard_soundというプロジェクトの入力を(96000, 1)、出力前の処理をAffine -> Sigmoid -> Binarycrossentropyに変えたものを使いました。時間配分がうまくいかなかったのは悔しい限りです。

  1. 結果12sec_completed.jpeg

 12sec_result1.jpeg

 結果はまさに圧倒的で、機械に対しても"とぱぞ曲"が圧倒的な認識率を誇っていることがわかります。写真は楽曲データを12秒に切りそろえたもの5450個を学習に使っています。TESLA V100 4機を用いた学習でこれらの処理に14分でした。CPUでの学習も試みたのですが2時間以上学習にかかり結果を出すことを断念しました。返す返すも時間配分のまずさが悔やまれます。次回があれば与えられた時間をうまく使ってデータの前処理、効率の良い学習等の比較も試せるようにしたいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CI/CDをkatacodaで体験(初心者向け) - Part6(Experiments Using Branches)

CI/CD入門

このぺーじでは、katacodaと呼ばれる「ブラウザから無料で勉強用のインスタンスを起動できるWebサービス」を利用してCI/CDを実践します
内容は上記リンクに沿うので、不明点があればそちらへどうぞ

Gitのバージョン管理について - Scenario6 - Experiments Using Branches

ここでは、CI/CDとして欠かせないGitによるバージョン管理について学習します
このシナリオで学習することをさっと確認する場合は概要を確認
理解に間違い等がございましたら、ぜひご指摘ください

概要

  • branchの作成は、git branch <new branch> <original branch>や、git checkout -b <new branch>
  • branchの一覧表示は、git branch。オプションとして-vaは頻繁に利用
  • branchの統合は、マージ先branchでgit merge <branch>
  • branchの削除はgit branch -d/D

Step 1 - Git Branch

gitを用いた開発では、ローカルレポジトリにmaster branchがデフォルトで作成される
このbranch上で直接開発を行うのではなく、複製した別のbranchを使うことでmaster branchにはローカルレポジトリ上での行うべき作業が行われたキレイな状態を維持することが可能
master branchをもとに別のbranchを複製する方法はgit branch <new_branch> <master branch>で実現可能
branchの移動はgit checkout <to branch>で実行

$ git branch -va
* ESC[32mmasterESC[m abe4241 First Commit on master
$ git branch new_branch master
$ git branch -va
* ESC[32mmaster    ESC[m abe4241 First Commit on master
  new_branchESC[m abe4241 First Commit on master
$ git checkout new_branch
Switched to branch 'new_branch'
$ git branch -va
  master    ESC[m abe4241 First Commit on master
* ESC[32mnew_branchESC[m abe4241 First Commit on master

また、git branch -b <new_branch>で同様にbranchを作成し、branchの移動(git checkout <new_branch>)も一度に行うことができる

$ git checkout -b test_branch
Switched to a new branch 'test_branch'
$ git branch -va
  master     ESC[m abe4241 First Commit on master
  new_branch ESC[m c112293 Commit on branch
* ESC[32mtest_branchESC[m abe4241 First Commit on master

Step2 - List Branches

branchの一覧を確認する際はgit branchで実現
以下のオプションはよく利用される

-a:remote branchも表示。remotes/origin/master等
-v:各branchの最新のコミットメッセージも表示

*は現在いるbranchを示している

$ git branch -va
  master    ESC[m 93f6d42 First Commit on master
* ESC[32mnew_branchESC[m 66ce3bf Commit on branch
$ git branch
  masterESC[m
* ESC[32mnew_branchESC[m
$ git branch -v
  master    ESC[m 93f6d42 First Commit on master
* ESC[32mnew_branchESC[m 66ce3bf Commit on branch

Step 3 - Merge To Master

gitにおいて複製元は複製先の変更を自動的に反映されない
反映させるために、git mergeを用いる

$ ls -a
.  ..  .git  staging.txt
$ git branch -va
* ESC[32mmasterESC[m bade7a5 First Commit on master

~~~branch作成、ファイル追加~~~   //katacodaでは、step3に入った際に自動的にファイルが作成されている

$ ls -a
.  ..  .git  new-file-6.txt  staging.txt
$ git branch -va
  master    ESC[m bade7a5 First Commit on master
* ESC[32mnew_branchESC[m 7a52803 Fix for Bug #58
$ git checkout master
Switched to branch 'master'
$ git merge new_branch
Updating bade7a5..7a52803
Fast-forward
 new-file-6.txt | 1 +
 staging.txt    | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)
 create mode 100644 new-file-6.txt
$ ls -a
.  ..  .git  new-file-6.txt  staging.txt

Step 4 - Push Branches

ローカルレポジトリでの変更が済んだら、リモートレポジトリに変更の反映を行う
ここでは、すでにPart3(katacodaにおけるScenario 3 - Working Remotely)で経験済みなので省略
ちなみに、git pushを初めて実行したことで、git branch -vaの結果にremotes/origin/masterbranchが確認できるようになる

$ git branch -va
* ESC[32mmaster                   ESC[m 7a52803 Fix for Bug #58
  new_branch               ESC[m 7a52803 Fix for Bug #58
  ESC[31mremotes/origin/new_branchESC[m 7a52803 Fix for Bug #58

Step 5 - Clean Up Branches

最後に、必要なくなったbranchの削除方法はgit branch -d <branch>

$ git branch -va
* ESC[32mmaster                   ESC[m 7a52803 Fix for Bug #58
  new_branch               ESC[m 7a52803 Fix for Bug #58
  ESC[31mremotes/origin/new_branchESC[m 7a52803 Fix for Bug #58
$ git branch -d new_branch
Deleted branch new_branch (was 7a52803).
$ git branch -va
* ESC[32mmaster                   ESC[m 7a52803 Fix for Bug #58
  ESC[31mremotes/origin/new_branchESC[m 7a52803 Fix for Bug #58

マージされていないbranchを削除する場合はオプション-Dを利用

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ssh keyの登録方法

https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent

tsuboi@tsuboi hotel-project-spring % ssh-keygen -t rsa -b 4096 -C "igarage@gmail.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/tsuboi/.ssh/id_rsa): <このままEnter>
Enter passphrase (empty for no passphrase): <このままEnter>
Enter same passphrase again: <このままEnter>
Your identification has been saved in /Users/tsuboi/.ssh/sample_igarage.
Your public key has been saved in /Users/tsuboi/.ssh/sample_igarage.pub.
The key fingerprint is:
SHA256:EDfM107HohOoo7eFhArJne1rk3FgaJh0sW6IxKWtkoQ igarage@gmail.com
The key's randomart image is:
+---[RSA 4096]----+
|   o. .oo. . .   |
|o.+..  o+.o + o  |
|E*=o+... . = o   |
|*=+=.++.  o .    |
|++.+oo.oS  .     |
|. o .oo..        |
|     .=o         |
|     =.          |
|    . .          |
+----[SHA256]-----+
tsuboi@tsuboi hotel-project-spring % ls ~/.ssh/
id_rsa.pub id_rsa
tsuboi@tsuboi hotel-project-spring % cat ~/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDLYXb92jzvmZIXwSIzJD0fuPuDf10nYAOGfpMBn8qN7sPoTw17sU46mWMwT/bbkFyfxP4FRsNZbFl7lIATYFk8lY3BRqfnjxlaATqAo4F5U2l28WGJyqStrky9U3jrYum9NTd4uSzoDwTnh2PE+PeT9bEl0KguRCttUot9C8u2zMIShx7bYc+3cbtT8Ix0M7nP0VGCyXBe7RZanFew/JcGiNVL3MEx0ygZ1d/wlBfXJAF+8egod2SWAthARo+pmJ0n/s1TGtHFY7jwLVbnjXdKVSOf9cq0t0qu5v9RuWuznCkKNfk1S7bW9P2qUjXZNkT7KqmAnm04tyDj7Q3g7KCR1oxzpgWw3yj/L+JwOBn8miCEtMSmD8RJ0AqEcOKgF8Bb8kOLqACU0NbQUEhtDz8272tTcp8cg4UXUTlHLyVskTVtkzlEw59ksuxMZvAwxkhdjtRRbqlQKI7SfycrEB83+hYA1Fa/GexAFBzhiKgiIuLSHxyujodKIsTXrWprdVlR0CJFjatPWD4vDyVXm6oFX32O4SgftAhJ1aCjP3APXYeUKQlzu4iky15Mxo8etqEbw9Jct1YLh73cPqLSimOf1J95zE4mASPRpOC1TQwJcQJBxJJR/vtSV2AyDvk6nRSH2C5LRFcxdSkajYEYidd5tKo2csiHGw/wcJllXXK1bQ== igrage@gmail.com
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CI/CDをkatacodaで体験(初心者向け) - Part5(Fixing Merge Conflicts)

CI/CD入門

このぺーじでは、katacodaと呼ばれる「ブラウザから無料で勉強用のインスタンスを起動できるWebサービス」を利用してCI/CDを実践します
内容は上記リンクに沿うので、不明点があればそちらへどうぞ

Gitのバージョン管理について - Scenario5 - Fixing Merge Conflicts

ここでは、CI/CDとして欠かせないGitによるバージョン管理について学習します
このシナリオで学習することをさっと確認する場合は概要を確認
理解に間違い等がございましたら、ぜひご指摘ください

概要

  • branchの分岐 × 分岐元と分岐先の同じファイル、同じ行に対して異なる変更 -> conflict発生
  • git checkout --ours/theirs <file>で分岐先、分岐元どちらを優先するか決定。その後優先した変更をcommitし劣後の変更を加える
  • branch統合の方法はgit mergegit rebaseがあるが、前者を用いた方がいい。詳しくはこちらもしくはこちら

Step 1 - Git Merge

step1では、リモートレジストリ上にあるファイルを数人で編集する際に発生する"conflict"というエラーの対処法について学習する
ローカルレジストリの状況は下記の通り

$ ls -a
.  ..  .git  staging.txt
$ cat .git/config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = /s/remote-project/1
        fetch = +refs/heads/*:refs/remotes/origin/*

リモートレジストリ"origin"が登録されており、同様に別の作業者もこのリモートレジストリを登録している
ローカルレジストリ上のmaster branchとremotes/origin/master branch(リモートレジストリからダウンロードした内容が保存されるbranch)のstaging.txtが一致していないため、conflictが発生

$ cat staging.txt   //master branch
Fixing Error, Let's Hope No-One Else Does
$ git branch
* ESC[32mmasterESC[m
$ git branch -a
* ESC[32mmasterESC[m
  ESC[31mremotes/origin/masterESC[m
$ git checkout remotes/origin/master
Note: checking out 'remotes/origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 4b304c4 Fix for Bug #1234
$ git branch
* ESC[32m(HEAD detached at origin/master)ESC[m
  masterESC[m
$ cat staging.txt   //remotes/origin/master branch
Fixing Previous Error
$ git checkout master
Previous HEAD position was 4b304c4 Fix for Bug #1234
Switched to branch 'master'
$ git branch -a
* ESC[32mmasterESC[m
  ESC[31mremotes/origin/masterESC[m
$ git merge remotes/origin/master
fatal: refusing to merge unrelated histories   //関連性のないヒストリを持つbranch同士のマージはGit2.9からできなくなった※1
$ git merge --allow-unrelated-histories origin/master   //上記エラーの対応
Auto-merging staging.txt
CONFLICT (add/add): Merge conflict in staging.txt
Automatic merge failed; fix conflicts and then commit the result.
$ cat staging.txt
<<<<<<< HEAD
Fixing Error, Let's Hope No-One Else Does
=======
Fixing Previous Error
>>>>>>> origin/master

※1
<<<HEADから====の部分と====から>>>>origin/masterで競合発生

Step 2 - Viewing Conflict

マージ対象のstaging.txtの差分を確認する際の一例としてgit diff (branch_a)(branch_b)を用いる

$ git diff master remotes/origin/master staging.txt
ESC[1mdiff --git a/staging.txt b/staging.txtESC[m
ESC[1mindex 02a3604..9139e85 100644ESC[m
ESC[1m--- a/staging.txtESC[m
ESC[1m+++ b/staging.txtESC[m
ESC[36m@@ -1 +1 @@ESC[m
ESC[31m-Fixing Error, Let's Hope No-One Else DoesESC[m
ESC[32m+ESC[mESC[32mFixing Previous ErrorESC[m

異なるファイルの差分を取る際は、git diff br1:foo/bar.txt br2:hoge/fuga.txtのように記述する

視覚的にコンフリクトを解消する方法としてkdiff3という外部ツールもある

Step 3 - Resolving Conflict

コンフリクトが発生した場合の基本的対策は下記のいずれかです。

  • 自分の変更結果を優先しコミット。その後、相手(コンフリクト先)の変更を組み込む
  • 相手の変更結果を優先しコミット。その後、自分(コンフリクト先)の変更を組み込む

自分もしくは相手を優先する際の方法はgit checkout <option> <file/directry>のオプションに--oursもしくはtheirsを与える

$ git checkout --theirs staging.txt   //レポジトリ先の変更を優先
$ git status
On branch master
Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both added:      staging.txt

$ cat staging.txt
Fixing Previous Error
$ git add staging.txt
$ git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

        modified:   staging.txt

$ git commit -m 'checkout --theirs'
[master 46801f2] checkout --theirs
$ git log --oneline
ESC[33m46801f2ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m checkout --th
ESC[33m3e7785fESC[m Fixing Error
ESC[33mc2080aeESC[mESC[33m (ESC[mESC[1;31morigin/masterESC[mESC[33m)ESC[m Fix for Bug #1234
ESC[33mae9e69bESC[m First Commit
$ cat staging.txt
Fixing Previous Error

最初のgit statusboth add: staging.txtと見慣れない記載がされている
これはこちらに記載されている通り、コンフリクトの発生を知らせてくれる
また、どのようなコンフリクトが発生しているかも大まかに教えてくれる

注意
katacodaでは、step1で$ git merge --allow-unrelated-histories remotes/origin/masterを実行するよう要求されない
この操作を実行せずにstep3を実行しても--ours/--theirsオプションが反映されずgit statusの結果が変わらない
これは、katacodaの環境では自分のbranchとremoteのbranchが関連性を持っていないため、git merge remotes/origin/masterでは、コンフリクトの発生を認知できず、その後の--ours/--theirsオプションが意味をなしていないためと思われる
おそらく、最初にこの演習を作成した時点では、2つのbranchの関連性があったにも関わらず途中で関連性がないbranchを別に用意したのだろう
(ちゃんと演習内容も修正してほしい、、、、初心者殺しやん、こんなの涙)

$ git merge remotes/origin/master
fatal: refusing to merge unrelated histories   //関連性のないヒストリを持つbranch同士のマージはGit2.9からできなくなった※1
$ git merge --allow-unrelated-histories origin/master   //上記エラーの対応
Auto-merging staging.txt
CONFLICT (add/add): Merge conflict in staging.txt
Automatic merge failed; fix conflicts and then commit the result.

Step 4 - Non-Fast Forward

step4では、以下の図のような場面を考える
図1.png

$ ls -a
.  ..  .git  new-file-5a.txt  new-file-5.txt  new-file.txt  staging.txt
$ git log --oneline
ESC[33mc993ea3ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Fix for Bu
ESC[33m1f30797ESC[m Merge remote-tracking branch 'origin/master'
ESC[33m7b6b4d3ESC[m Fixing Error
ESC[33m499f006ESC[mESC[33m (ESC[mESC[1;31morigin/masterESC[mESC[33m)ESC[m Fix for Bug #1234
ESC[33mf9fb9b3ESC[m First Commit
$ git pull --no-edit origin master
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From /s/remote-project/1
 * branch            master     -> FETCH_HEAD
   499f006..b35bfb6  master     -> origin/master
Merge made by the 'recursive' strategy.
 new-file-6.txt  | 1 +
 new-file-6a.txt | 1 +
 2 files changed, 2 insertions(+)
 create mode 100644 new-file-6.txt
 create mode 100644 new-file-6a.txt
$ git log --all --decorate --oneline
ESC[33m3833389ESC[mESC[33m (ESC[mESC[1;36mHEAD -> ESC[mESC[1;32mmasterESC[mESC[33m)ESC[m Merge bran
ESC[33mb35bfb6ESC[mESC[33m (ESC[mESC[1;31morigin/masterESC[mESC[33m)ESC[m Fix for Bug #58a
ESC[33mc993ea3ESC[m Fix for Bug #55
ESC[33m1b74e50ESC[m Fix for Bug #58
ESC[33m1f30797ESC[m Merge remote-tracking branch 'origin/master'
ESC[33m7b6b4d3ESC[m Fixing Error
ESC[33m499f006ESC[m Fix for Bug #1234
ESC[33mf9fb9b3ESC[m First Commit
$ ls -a
.   .git             new-file-5.txt   new-file-6.txt  staging.txt
..  new-file-5a.txt  new-file-6a.txt  new-file.txt

開発者が自分の変更を容易に確認できる方法としてstep5で紹介する

Step 5 - Git Rebase

git rebaseを用いると以下の図のようなログを生成
図2.png

git mergegit rebaseの復習

  • 共通点:最新のbranchの状態は同じ(HEADの位置は異なる可能性あり)
  • 差異:

    • merge:コミットの履歴を出来事の通り記録
    • rebase:コミットの流れを見やすく記録
  • 使い分け
    基本的には、git merge一択
    master branchの変更が活発でgit熟練者が複数人で使う場合はgit rebase
    masterに統合->git mergemaster以外に統合->git rebase

詳しく知りたい方はこちらもしくはこちら

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ブランチ切り替え時に移動先ブランチのstash一覧を表示させる方法

stashしたことを忘れてしまう問題

git stashは非常に便利ですが、他のブランチで作業をしているうちにstashしたことを忘れ、戻ってきた際に再び同じ作業を始めてしまうようなことがたまにあります。

今回はその対策として、
「ブランチを移動するたびに移動先ブランチのstash一覧を表示するGitフック」
を作成したので、その実装方法について解説します。

完成イメージ 

以下のように、移動先ブランチ上でstashしたもののみを表示するイメージです(他のブランチのものは表示しない)。
スクリーンショット 2020-10-18 0.39.04.jpeg
これなら明らかに通常と違うため stash の存在を思い出せるはずです。

また、元々存在する機能(git hooks)しか使わないため、変なプラグインを入れたりする必要もありません。

実現方法

git の標準機能である git hooks を使います。

git hooksとは.git/hooks/下に置かれたスクリプト群のことで、特定のタイミングで自動的に呼び出される仕組みになっているものです。

例えば「commit 前にリントをしたい」という場合には、pre-commitという名前のファイルを.git/hooks/に配置して、リントを行うコードを書けばOKといった感じです。

今回はgit switchgit checkoutの後に呼ばれてほしいのでpost-checkoutという名前で作成します。

実装

処理の流れを大まかにいうと、
1. git branch --show-currentで移動後のブランチ名を取得し、
2. そのブランチ名をgit stash listの中からgrepする
という感じです。

.git/hooks/post-checkout
#!/bin/sh

has_branch_changed=$3 #ブランチ移動したかどうかのフラグ
current_branch=$(git branch --show-current | awk -F/ '{print $NF}')

if [ $has_branch_changed = 1 ] && [ -n "$current_branch" ]; then
  git stash list | grep "$current_branch: "
fi

結果
スクリーンショット 2020-10-18 0.34.45.jpeg
※ 説明のため、ここではまだ文字色の変更等は行っていません。色付きバージョンのコードは次節をご参照ください。

技術的な詳細
  • git checkoutしてもブランチが変わっていないケースもあるため、post-checkoutの三番目の引数$3(ブランチ移動したかどうかのフラグ)を使ってチェックを入れています。ちなみに$1には移動元のcommit hash, $2には移動先のcommit hashが入っています。

  • awk -F/ '{print $NF}'はブランチ名を/で分割して末尾部分を取得するコードです。この処理が必要なのは、ブランチ名が/で区切られている場合git stash listは区切りの末尾の部分しか表示しないためです。例えばaaa/bbb/cccならcccの部分しか表示しないため、単純にgrep <ブランチ名>では取得できません。

  • [ -n "$current_branch" ]でブランチ名が1文字以上かのチェックを行っていますが、これは detached HEAD の場合ブランチ名が出力されず、結果的に全ての stash が表示されてしまうためです。

もっと目立たせる

上記のコードでは文字色の変更等は行っていませんでした。
しかしより視認性を高めるためにはechoを通して文字色を変更したほうが良いかもしれません。

.git/hooks/post-checkout
#!/bin/sh

has_branch_changed=$3 #ブランチ移動したかどうかのフラグ
current_branch=$(git branch --show-current | awk -F/ '{print $NF}')

if [ $has_branch_changed = 1 ] && [ -n "$current_branch" ]; then
  git stash list | grep "$current_branch: " | while read line; do
    echo "?   \033[32m$line\033[m"
  done
fi 

結果
スクリーンショット 2020-10-18 0.39.04.jpeg
前節のコードの出力をwhile readで回して、echoで色と絵文字を付加しているだけです。

echoの文字色の変更法はシェルによって異なります。例えば bash の場合は-eオプションが必要かと思います。より詳しくはこちらの記事をご参照ください。

以上です。改善点等があればコメントやリクエストからご教示いただけると幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git v2.28でデフォルトブランチをmainに変更する

ご存知の方も多いと思いますが、2020年10月1日よりGitHubではプロジェクト作成時点でのデフォルトのブランチ名が master から main に変更されました。
また、7月27日にリリースされた git バージョン 2.28 からはデフォルトブランチの変更オプションが実装されているので、これにより main ブランチに対応できるようになっています。
本記事ではこちらの設定手順についてご説明します。

TL;DR

  • git 2.28 (GitHubの変更時点での最新版) ではデフォルトブランチはmasterのままである
  • デフォルトブランチを変えるには、まずgitを 2.28 に更新する
  • その後 git config --global init.defaultBranch main をCLIで実行するか .gitconfig を変更すれば対応完了

変更の背景

Git関連の複数のコミュニティではGitのデフォルトブランチ名 master について変更すべきではという議論があります。詳しくはここで語りませんが、もともと業界では master/slave といった用語が一般的に使われていて、この言葉のニュアンス(master:主人 slave:奴隷)が差別的だから変えようという流れがあり、GitHubとgitもそれぞれの方法で対応を行った形となります。

対応方法

前述の通りGitHubでは10月1日よりプロジェクトのデフォルトブランチを master から main に変更しており、gitそのものもmasterブランチがデフォルトしてハードコードされてはいるものの、 7月27日のバージョン2.28から init.defaultBranch というオプションを追加することによって対応できるようになりました。

対応方法についてはブランチ名変更について記載しているGitHubの資料でも触れられています。

(中略)
Git 2.28 added a similar setting to control the default branch used when you run git init on the command line. Learn more about the new init.defaultBranch setting in the Git 2.28 blog post.

init. defaultBranch オプションでデフォルトブランチを変更できるということで、以下のコマンドを実行することで対応できます(全く同じコマンドがGit 2.28 のブログポストにも記載されています)

git config --global init.defaultBranch main

またはグローバルの .gitconfig に以下を追記しても対応できます。
個人的に設定を管理されている方はこちらのほうが便利かと思います。

[init]
    defaultBranch = main

まとめ

今回はGitHubがプロジェクトデフォルトのブランチ名の変更したということで、git側での対応方法について記載しました。
ただ現時点ではBitbucketではデフォルトのリポジトリ名は master のままですし、ベンダーによって対応が変わってくるので一概にプロジェクトデフォルトを main に合わせていくのがが正解とは言えず、会社の判断やそれぞれの環境に合わせて適切な設定をしていくのが良いかと思われます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【zsh】絶対やるべき!ターミナルでgitのブランチ名を表示&補完【git-prompt / git-completion】

:star2: この記事でできること

  • ターミナルのプロンプトにgitのブランチ名を常に表示させる(git-prompt)
  • gitコマンドをTab補完できるようにする(git-completion)

スクリーンショット 2020-10-17 22.36.17.png

:star: はじめに

:computer: 確認環境

  • macOS Catalina 10.15.7

:pencil2: git-prompt / git-prompt の用意

mkdir ~/.zsh
cd ~/.zsh

curl -o git-prompt.sh https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh
curl -o git-completion.bash https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash
curl -o _git https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.zsh

:pencil: .zshrc に設定追記

~/.zshrc
# git-promptの読み込み
source ~/.zsh/git-prompt.sh

# git-completionの読み込み
fpath=(~/.zsh $fpath)
zstyle ':completion:*:*:git:*' script ~/.zsh/git-completion.bash
autoload -Uz compinit && compinit

# プロンプトのオプション表示設定
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_PS1_SHOWSTASHSTATE=true
GIT_PS1_SHOWUPSTREAM=auto

# プロンプトの表示設定(好きなようにカスタマイズ可)
setopt PROMPT_SUBST ; PS1='%F{green}%n@%m%f: %F{cyan}%~%f %F{red}$(__git_ps1 "(%s)")%f
\$ '

:rocket: 以上!

  • より良いgitライフを!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む