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

Git/Githubをワンライナーで扱うCLIツールを作った話【Go言語】【cobra】

はじめに

golangとcobraを使ってGit/Githubをワンライナーで扱うCLIツールを作成しました。
前半で導入方法や使い方、後半でcobraでCLIツールを作成する方法(WIP at 2019/12/14)について扱います。

対象読者

  • golangでCLIツール作ってみたい人
  • CLIを使って業務改善したい人
  • エンジニアな人

リポジトリ

こちらからどうぞ↓
https://github.com/HiroyukiYagihashi/toolbox

導入方法

golangの動作環境があれば下記で動くと思います。

$ go get github.com/HiroyukiYagihashi/tooland/gh
$ go install $GOPATH/src/github.com/HiroyukiYagihashi/toolbox/gh

gitコマンドとhubコマンドに依存していますので、こちらもインストールしてください。
(gitは入れてるけどhubは入れてないって方が多いのでは)
MacOSユーザーかつパッケージマネージャに特にこだわりがなければ下記でインストールできると思います。
違う方は調べてみてください。

$ brew install git && brew install hub

使い方

下記コマンドで確認できます。

$ gh --help

Usage:
  gh [flags]

Flags:
  -a, --add strings     add
  -c, --cm string       commit -m
      --config string   config file (default is $HOME/.gh.yaml)
  -b, --cop string      checkout -b and push
  -h, --help            help for gh
  -o, --open            hub browse
  -p, --push            push

下記使用例になります。

$ gh -a app/ -c “Create function” -p -o
// app以下をadd、コミットメッセージ”Create function”でcommit、push、該当リポジトリをブラウザで開く

$ gh -o
// オプション単体でも動作します(挙動は該当リポジトリをブラウザで開く)

$ gh -b feature/1/create_function
// feature/1/create_functionブランチを切ってリモートに反映

cobraでCLIツールを作成する方法(WIP)

需要があったら書こうかなと思ってます。
(個人的にはこの記事に10いいねくらいついたら書くつもりです)

それまでは下記を参考にしてください。
https://github.com/spf13/cobra

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

macOS CatalinaにUpdateしたら, gitの補完が効かなくなったので直した

macOSのアップデートをしてmacOS Catalinaに変更した時に,terminalでのgithubの補完機能が働かなくなってしまったので,修正をしました.というより,一から導入したので,その話をします.

OSのアップデートをすると,ディレクトリの構成などが変わる場合があります.私はgitのterminalでの補完機能を次のディレクトリから呼び出していました.

  • /Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash
  • /Library/Developer/CommandLineTools/usr/share/git-core/git-prompt.sh

OSのアップデートをしたら,上記のファイルがなくなったみたいなので,本記事では,1から補完機能を導入することにしました.

1から導入する

  • 使用した環境
$ sw_vers 
ProductName:    Mac OS X
ProductVersion: 10.15.2
BuildVersion:   19C57

ファイルの準備

  • git-prompt.shのダウンロード
wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh -O ~/.git-prompt.sh
  • git-completion.bashのダウンロード
wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash -O ~/.git-completion.bash

それぞれのファイルは,~/に保存されています.vim ~/.git-prompt.shvim .git-completion.bashで内容を確認することができます.

.bashrcに設定

次に,bashrcの設定を行います.

  • vim ~/.bashrcに次を追加してください
source ~/.git-prompt.sh
source ~/.git-completion.bash

追加したら,.bashrcを保存してください.

  • terminalで次のコマンドを入力してください.
$ source ~/.bashrc

最後に

補完機能があれば,typoが減って効率化できます.

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

はじめての共同開発でGitHubがめっちゃ便利だったって話

はじめに

先月、自分が通っていたCodeBaseというプログラミングスクールの卒業生が参加できる、β版ハッカソンに参加してきました。(β版ハッカソンとはビジネスアイデアはあるけれど技術がない人と技術を学び始めたけれど、まだ実践経験がない人をマッチングしてアプリケーションを開発する場所みたいなものです。)そこで、今まで個人開発でしか使用していなかったGitHubが共同開発で利用するとめちゃくちゃ便利だなと思ったのでここに記しておきます。

GitHubとは

GitHubとはソフトウェア開発においてソースコードをオンライン上で管理できるプラットフォームです。ソースコードをオンラインで管理することにより、エンジニアが協同で開発作業を行なったり、レビューをしてソースコードのブラッシュアップしたりできます。

GitHubが便利だなと思ったポイント

①ブランチを変更することで、アプリを動かせる状態にしつつ開発を行える
 アプリケーション開発時には、アプリケーションが常に正常に動いているマスターブランチの他にも、複数のブランチに分岐させることで複数の開発や変更を同時に進めることができます。分岐させたブランチは後でマージすることでそれぞれで開発した機能を1つのブランチに統合することができるので、共同での開発がすごく楽になります。

②管理する場所を一元化することで、ファイルの重複を防ぐことができる
 自分的にはこれが1番便利だと思ったポイント。パワポとかで例えるとわかりやすいんですけど、パワポの共同作成っていちいちラインにあげたものをダウンロードして、自分の担当のところを編集して、またラインにあげてってしているうちに、同じような名前のパワポが5とか10とか増えていくんです。そうなってしまったらどれが最新かわからないし、どのファイルでどんな変更したかも分からないからいちいちファイルを開くか、変更した人に詳しく聞くかをしないといけなくなります。GitHubではそんなことなくて、プロジェクトが一元管理されているから、変更した部分だけが更新されて、どこを編集したかもわかりやすいのでそういった問題が起こりにくいんです。

今回の開発で使いまくったGitコマンド

 git branch -a
 git fetch
 git checkout branch名 origin branch名
 got pull

共同開発でメンバーが作ったリモートのリポジトリにアクセスするコマンド群です。これらだけで他人の作ったブランチを簡単に自分のローカルブランチに持ってくることができます。

 git add .
 git commit -m ‘コメント’
 git push origin branch名

これらは、自分が開発した部分をオンラインに上げることができるコマンドです。変更した部分をすぐにオンラインに共有できたらとても楽ですよね。ちなみに、コメントの部分には自分が開発・変更したことを書くとメンバーにも分かりやすい、効率性のある開発になると思います。

 git stash
 git stash apply stash@{番号}

これらは、自分が変更を加えている時に、メンバーの変更部分を統合しないといけなくなった時に一度自分の変更した部分を横に置いておくっていうコマンドです。2行目のapplyコマンドを使用することによりこの横に置いていた部分をまた戻して作業を再開することができます。

共同開発でGitHubを使うときに気をつけるべきポイント

GitHubを使って共同開発をする上で(ていうか共同開発する上で)気をつけようって思ったポイントもありました。

①インデントを揃える
②無駄な改行やスペースを入れない
③いらないコードやコメントアウトは消す
④自分が書いたコードがなぜこのようになったのかというプロセスをissueに書き残す

上の3つは個人開発の時によくやってしまっていました。特に③が1番多かった。binding pry や binding irb でシステムの挙動を確認して、また後でやるかもしれないからコメントアウトして置いておくつもりがそのまま忘れてしまうことが多いんですよね。

でも、やっぱり仕事でのシステムやアプリケーション開発って基本的にみんなで一緒に開発していくものだから、誰が見ても見やすい&意味が分かるようなコードの書き方を心がける必要があるなって今回のβ版ハッカソンで強く思いました。

④は何で気をつけるべきかっていうと、自分がなんでこのコードの書き方をしたのかっていうとプロセスを開発メンバーに知っててもらうことで、一緒に開発していくときに生じるズレを少なくしていけるっていうメリットがあります。エンジニアってコミュニケーションのいらない職業って思われがちだけど、システムが動かなくなったり、開発スケジュールの遅延に関わってくることもあるからメンバー同士のコミュニケーションは必須だと思います。

あと、開発の時に詰まったところとその解決策を残しておくことで、後で見返したり、他のメンバーが開発するときの参考になったりするから再現性が高くなるんですよね。

まとめ

というわけで色々書き連ねたんですが、「共同開発でGitHub使おうぜ」って感じでまとめとさてください。ちなみに、自分のつくりたいアプリケーションとかシステムがあったらGitHubで探してみてください。結構いろんな書き方があって参考になると思います。(自分は個人開発の時に色々漁ってました。)

あと、β版ハッカソンめっちゃ楽しかった。まだプログラミングを始めて半年も経たないペーペーの意見にも耳を傾けてくれたし、先輩方の考え方や開発の技術も、参考になってとても刺激になりました。是非ともまた参加したい。

沖縄でエンジニアの勉強始めてみたい方、CodeBaseおすすめなので是非チェックしてみてください。(急な宣伝)

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

Gitでブロックチェーンのようなことをする

ブロックチェーンはGitと何が違うの?ということでブロックチェーンのようにGitで Proof-of-Work する。

暗号通貨の送金などのトランザクションがgit addであり、ブロックチェーンのブロックがgit commitである、として考える。
そうするとブロックチェーンはgitの履歴であり、トランザクションの確定はgit commitを Proof-of-X することで信頼性(?)が担保される。

簡易的な Proof-of-Work を hooks/post-commit に書くことにする。
コミットのハッシュが特定の条件を満たさない場合はコミットのやり直しという感じ。

$ git commit --allow-empty -m foo
c501d4fd3d6522ac34f0977c87d2942b1438fb1c -
f28f9c80a4431fe9f2bd2cc806e1b0880ac58619 -
99513727ca14d70b336a1aaccd11e8c17a65e3c9 -

...

ad6e20750dc378eac2a15f73623fb49a0cf45973 -
00a824e2b63a0260e1bec773780d44b323b87b43 -
  ---  
done 0s.
  ---  
done 7s.
[master 3eaaac4] foo

なんか最後の出力がミスってるけど、とりあえずこれで。

https://github.com/nishimura/gitmining-hook

$ git log --oneline
0058b75 add readme
0054dde add empty readme
00842e6 update command
009b8bc add post-commit file
0008b42 initial commit

コミットハッシュの先頭を00に揃えることができた。

ランダムな文字列をコミットコメントに追加して PoW している。
コミットコメントやAuthor、Committerを自分の公開鍵のハッシュのみの固定文字にして変更不可にすれば、1秒ごとにマイニングするPoSになる、と思う。コミット時刻が変わるとハッシュが変わるので。

ブロックチェーンはトランザクションがブロードキャストされるので、これを更にブロックチェーンに近付けるならgit addをブロードキャストするようにしなければいけない。
あとはコミットを検証してコミットハッシュが00で始まらない場合や間違った計算のコミットはrecievepullも拒否しなければならない。

さて、上記ブロードキャストや検証の仕組みを作っても、今のままでは特に意味は無い。
単に面白いハッシュが作れるという以外の意味を見出すには、コミットに成功したらコインが増えるというような仕組みがないとどうしようもないよね。
普通のGitでいいじゃん、となる。

逆に言うと、自分のローカルのリポジトリが見ず知らずの他人によってブロードキャストされたデータで勝手に更新されるような環境だと、PoXが必要なのかもしれない。
ただし、そのデータの価値がコミットのPoXの価値と関連していなければ、やはり普通のGitでいいよね、となる。

ブロックチェーンをコイン以外の何かに使うことを考えるというのは、この0008b42ハッシュが何かに使えるかと探すようなことかもしれない。

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

Git fow windows設定備忘録 その1

概要

  • Windows10環境で開発をするときのgit for windows導入の仕方。
  • リポジトリの同期の仕方。

目的

自分用の備忘録。このため、下記を前提としています。

  • Windowsのコマンドプロンプトの操作が多少できること。
  • githubのアカウントを持っていること。
  • 既に開発中のリポジトリなどがあること。

インストール

Git for Windowsを入手してインストール。

 ※設定は全部デフォルトのままでOK

設定

git config --global user.name "ユーザー名"
git config --global user.email "メールアドレス"

Windowsの環境変数に LESSCHARSET = utf-8 を設定。

ローカルにリポジトリを同期

やり方が二つ。cloneか手動で同期。

コマンドラインプロンプトを起動

  1. チェックアウトしたいディレクトリをエクスプローラーで開く(ex: c:\test)
  2. アドレスバーにcmdと入れてEnter

cloneの場合

git clone https://github.com/hoge_user/hogehoge.git

で完了。ただし、c:\test> git clone hogeすると、カレントディレクトリの下にリポジトリ名でディレクトリを切るので、c:\test\hogeが出来てしまいます。
※git clone [URL] [hoge]で任意のディレクトリ名にすることは出来ます。

手動で同期させる場合

:warning: 注意
このやり方は中身が入っているディレクトリでも実施できます。
危険なので中身のバックアップを取ってからでお願いします。

ローカルのリポジトリを初期化

git init

リモートリポジトリの指定

git remote add origin https://github.com/hogehoge/hoge.git

※ここで間違えた場合は>git remove originで。

プル & チェックアウト

git pull origin master

この時点ではupstream指定が無いので、git branch --set-upstream-to=origin/master master でupstream(上流)指定しておくか、
push時に-uオプションで。

余談

なんでこんな面倒なことを?

既存の色々入っているアプリのディレクトリに追加の個人設定ファイルだけチェックアウトしたいな、と。

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

detached HEADになった後にめっちゃcommitしてしまった、、

発生した状況と手順

開発中、同じブランチの以前の状態に戻りたくなり
git refloggit checkout <commit id>で過去の状態に戻った

エラーメッセージっぽいものが出ていたけど、無視してそのまま10回くらいcommitを重ねた

GitHubにPushができなくなってしまった

detached HEADとは

現在の地点が、ブランチから切り離されてしまっている状態。
ターミナルのプロンプトに現在のブランチ名を表示させているのですが、気がつくとブランチ名ではなくd8d36db9f649a163b097のようなSHA1が表示されちゃってました。

何がまずいのか

どのブランチにも属していないので、PUSHができません。
あと、うまいことやらないと行った変更が全て消えてしまいます。

うまくいった対処法

新規ブランチを作成し、

$ git branch tmp

元いたブランチに移動し、

$ git checkout create-header

作成したブランチを取り込む

$ git merge tmp

コミット履歴に、マージをした記録が残ってしまいますが、個人的にはオッケーです。
無事解決できてよかった。

うまくいかなかった対処法

現在のブランチのSHA1を取得

$ git rev-parse HEAD
d8d36db9f649a163b097

SHA1からブランチを取得

$ git name-rev d8d36db9f649a163b097
d8d36db9f649a163b097 master

現在masterブランチが指すコミットにいることがわかったので、移動

$ git checkout master

私の場合git name-rev d8d36db9f649a163b097をしてもブランチ名が取得できなかったので、この方法ではうまく行きませんでした。
過去のコミットに戻る、という動作をした場合、この方法は使えないのかもしれません。

逆にdetached HEADになった直後はこの方法で修正できそうです。

今後に向けて

過去のバージョンに戻りたい時には、git checkout <commit ID>ではなくgit reset --hard [commit id]を使う!

参考

gitのHEADがブランチから外れてしまう現象とその直し方
detached HEAD から脱出する方法を git の内部構造から探る

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

うっかり創業者のコードを上書きしない技術

この記事は SmartHR Advent Calendar 2019 14日目の記事です。

はじめに

私は 3人目あるいは 4人目のエンジニアとして、 2016年2月に SmartHR に入社しました。
あれから約4年、今となっては順調に権限移譲の進んでいる SmartHR ですが、当時は正社員が 7人しかおらず、全社員が様々な仕事を行う小さな企業でした。
当然エンジニアである副社長の @kakipo はプロダクトコードを書いていますし、非エンジニアである @miyasho88 も SmartHR にコードを書いては PR を投げていました。

社長による PR
image.png

こういった、創業者がコードに込めた思いというのはとても重要であり、おいそれと上書きしてよいものではありません。
この記事では、入社から 4年弱の期間、私がいかにして創業者のコードを上書きしないで済んだのか、その方法をお伝えします。

うっかり上書きしないために

さて、では実際にどのようにしてコードの上書きを避けるのか説明します。その答えはいたって簡単で、 Git Hook にスクリプトを仕込むことで解決します。
commit する際に修正箇所の最終編集者を確認、創業者として指定したアカウント名が変更に含まれている場合はエラーを出して commit を中止する、という流れになります。
このスクリプトを実行するためには、創業者が commit に利用したアカウント名がわかる必要がありますので、それはなんとかして手に入れてください。

なお、本記事で扱うコードはほぼデフォルトの macOS Catalina 上でのみ動作を確認しておりますので、そのほかの環境では正常に動作しない可能性がありますのでご了承ください。

処理の流れ

スクリプト内で行われる処理の流れとしては以下のようになります。

  1. git hook の pre-commit でスクリプトが実行されます
  2. git diff から変更のあった行を取得します
  3. git blame を使って変更のあった行を誰が書いているのか確認します
  4. 指定したユーザ名が含まれる行を変更している場合にはメッセージを出力して git commit を中止します

コード

プロダクト直下から .git/hook/pre-commit に以下のコードを追記します

BOSS_NAMES=YOUR_BOSS_NAME # カンマ区切りで複数指定可能です
file_names=(`git diff --cached --name-only`)

for file in ${file_names[@]}; do
    git_diffs=(`git --no-pager diff --cached --no-ext-diff -U1000000 ${file} | $(cd $(dirname $0) && pwd)/diff-lines.sh | grep -E "^[^\"].*\:[0-9]+\:\-"`)

    for git_diff in ${git_diffs[@]}; do
        line=(`echo ${git_diff//:/ }`)
        origin=`git blame -L${line[1]},+1 HEAD^ ${file} | awk '{print $2}' | sed -e 's/^(\(.*\)/\1/'`

        if [[ ${BOSS_NAMES} == *${origin}* ]]; then
            echo "You will overwrite ${origin}'s code in *****:${line[1]}"
            is_boss_exist=true
        fi
    done
done

if [ "${is_boss_exist}" ]; then
    echo "Commit aborted."
    exit 1
fi

なお、ここでは簡単のために、 gitで変更ファイルの差分行番号を取得するには? - どこでも見れるメモ帳 で書かれているコードをお借りして行番号を取得しています

そのため、上記のブログで使われている diff-lines.sh.git/hook ディレクトリに保存し、 chmod +x .git/hook として実行権限を付与する必要があります

実際の動作

output.gif

ちゃんと abort されましたね :tada:
どこで誰のコードを消したり上書きしようとしているか一目瞭然です。便利。

最後に

今回はうっかり創業者のコードを上書きしないために Git Hook を使ってコミットを中断させました。
しかし、動画作成のためにいろいろと探してみたのですが、 社長のコードはほぼ残っておらず、結果的として 2015年に作られた 12番目の PullRequest をチェックアウトすることとなりました。 とても残念です
いつの間にか大量に書き換えていた事実に驚愕です。

記憶があれば、来年は おまえは今まで書き換えた創業者のコードをおぼえているのか? をお送りいたします。

明日じゃなくて来年です。みなさま良いお年を!

参考

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

ローカルリポジトリをGithubにpushする方法

ローカルで作業リポジトリをリモートリポジトリにpushする際の手順。
いつも忘れてしまうので、忘備録として書き留めておきます。

// 作業ディレクトリに移動(今回の作業ブランチはstudy-laravelと想定)
$ cd workspace/study-laravel

// gitを初期化
$ git init

// ステージングにあげる
$ git add .

// コミット
$ git commit -m "Initial Commit"

// リモートディレクトリを追加
$ git remote add origin <リモートリポジトリのURL>

// リモートリポジトリにPush
$ git push origin master

以上!!
次からはちゃんと覚えます!!

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

【Docker】error Couldn't find the binary gitが出た時の対処法

error Couldn't find the binary gitが出たDockerfileのソースコード

Nuxt.jsで開発したアプリから、Dockerのイメージを作成した時に「error Couldn't find the binary git」というエラーが起きました。

実際にエラーが起きたDockerfileのソースコードは以下です。

FROM node:10.15.1-alpine as builder
WORKDIR /app
COPY . /app
RUN yarn install --production
RUN yarn build

FROM node:10.15.1-alpine
WORKDIR /app
COPY --from=builder /app /app
CMD ["yarn", "start"]

※Dockerfileの作成方法もまとめているので参考にしてもらえると嬉しいです。

参考:https://qiita.com/arthur_foreign/items/fca369c1d9bde1701e38

Dockerイメージ作成時のエラーログ

エラーログは以下のような感じです。(GCRにイメージをPUSHする想定でした)

$ docker build -t gcr.io/${PROJECT_ID}/app_name:v1 .
Sending build context to Docker daemon  157.9MB
Step 1/9 : FROM node:10.15.1-alpine as builder
 ---> xxxxxxxxxx
Step 2/9 : WORKDIR /app
 ---> Running in xxxxxxxxxx
Removing intermediate container 0eb38e4dfdc1
 ---> xxxxxxxxxx
Step 3/9 : COPY . /app
 ---> xxxxxxxxxx
Step 4/9 : RUN yarn install --production
 ---> Running in xxxxxxxxxx
yarn install v1.13.0
[1/4] Resolving packages...
[2/4] Fetching packages...
error Couldn't find the binary git
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
The command '/bin/sh -c yarn install --production' returned a non-zero code: 1

タイトルや見出しにも書いてる通り、error Couldn't find the binary gitというエラーが発生していますね。

error Couldn't find the binary gitの原因

ちょうど同じエラーがteratailに掲載されていました。

参考:https://teratail.com/questions/179483

teratailのベストアンサーや解決の報告を見るにGitでこけているようですね。

error Couldn't find the binary gitの解決方法

おそらく、teratailはローカルの操作なのでDockerfileにも合わせていきましょう。

Dockerでうまくいかないということは、alpineのパッケージマネージャであるapkにGitを入れる必要があります。

そのため、Dockerfileを以下のようにしましょう。

FROM node:10.15.1-alpine as builder
WORKDIR /app
COPY . /app
RUN apk update && \
    apk add git
RUN yarn install --production
RUN yarn build

FROM node:10.15.1-alpine
WORKDIR /app
COPY --from=builder /app /app
CMD ["yarn", "start"]

すると、Dockerイメージの作成に成功します。

Successfully built xxxxxxxxxxxx
Successfully tagged gcr.io/gke_project_name/app_name:v1
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コミットメッセージをアスキーアートで装飾する

この記事はHamee Advent Calendar 2019の14日目の記事です。

はじめに

コマンドラインインターフェース(CLI)とアスキーアート(AA)は親和性が高く、slcowsayなどその親和性を発揮したジョークコマンドが多数存在している

そこで、git-hookを利用してgit commitしたときにコミットメッセージをAAで装飾するジョークhookを作った

ぶち当たった壁

某掲示板を中心に発達したAAは主にWindowsのフォントで綺麗に表示されるようにできているため、別の環境でみようとした時に綺麗に見えない可能性がある。(というかフォントが変わると綺麗に見えなくなるのは当たり前だったが実際に見るまで酷さを知らなかった)

元々やろうとしてことはアスキーアートを大量に保存(もしくは外部から取得)しておき、コミットメッセージによってランダムなAAで装飾するものだったが、綺麗に表示されないAAが多かったため断念。

結局自分の環境で綺麗に表示され、できるだけ他のフォントでも崩れないようなAAをいくつか選んで装飾することにした。

装飾例

Roboto Mono Medium for Powerlineサイズ12での表示

短いコミットメッセージの場合

タイポを修正
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch test
# Changes to be committed:
#       modified:   test

20191214-011457.png

長いコミットメッセージの場合

簡潔な説明が書けず長ったらしくなったコミットメッセージの場合

詳細なメッセージが残されている場合もある
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch test
# Changes to be committed:
#       modified:   test

20191214-001241.png

マージコミットの場合

Merge branch 'test2' into test

# Conflicts:
#       test2
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
#       .git/MERGE_HEAD
# and try again.


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch test
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#       modified:   test2

20191214-003249.png

実装

commit-msg
#!/bin/sh

DOUNIDEMO(){
    cat << EOS
       *'\`\`・* 。
        |     \`*。
       ,。∩∧_,,∧   *
      + (´・ω・\`) *。+゚
      \`*。 ヽ、 つ *゚*
       \`・+。*・'゚⊃ +゚
       ☆   ∪~ 。*゚
        \`・+。*・ ゚
EOS
}

DOG() {
    cat << EOS
\
   ̄ヽ、   _ノ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
    `'ー '´
      ○
       O 
         __,.....--‐―― ― ― --..、  
       ,/    l    ヽ     \
      /      /         ヽ`
     l       l          ! 
     ヽ     /   ●      ● |
     ! ヽ     l         ヽノ/  と思うわんわんであった
      ,!   \ │         _ ヽ
      ,!    `´         (::)l
    |        `---、      ̄ l  
    !             `ー 、.._./⌒iノ 
    !             ヽ   ̄
EOS
}

N_TONE(){
    cat << EOS

         ,-、           ,.-、
        ./::::\         /::::::ヽ
       /:::::::::;ゝ--──-- 、._/:::::::::::|
       /,.-‐''"´          \::::::::|
     /                ヽ、::::|
    /                   ヽ|
    l                        l
   .|    ●                |  んーと
    l  , , ,           ●    l
    \` 、      (_人__丿    、、、   / 
      \`ー 、__              /
         /\`'''ー‐‐──‐‐‐┬'''""´

         ,-、           ,.-、
        ./::::\         /::::::ヽ
       /:::::::::;ゝ--──-- 、._/:::::::::::|
       /,.-‐''"´          \::::::::|
     /                ヽ、::::|
    /     ●                  ヽ|
     l   , , ,             ●   l
    .|        (_人__丿     、、、 |  $first_line
     l                   l
    \` 、                     /
      \`ー 、__              /
         /\`'''ー‐‐──‐‐‐┬'''""´
EOS
}

max_len=0
first_line=''
is_merge=false

IFS=$'\n';
for line in `cat "$1"`
do
    # コミットメッセージのうち最も長い行の長さを調べる
    msg=$(echo $line | awk -F '[#]' '{print $1}');
    if [ ${#msg} -gt $max_len ]; then
        max_len=${#msg};

        if [ -z "$first_line" ]; then
            first_line=$msg;
        fi
    fi
    # マージコミットかどうかを調べる
    if [ "`echo $line | grep 'Merge'`" ]; then
        is_merge=true;
    fi
done

if [ $max_len -eq 0 ]; then
    exit 0;
fi

# マージコミット用のAA
if $is_merge; then
    echo "$( DOUNIDEMO )" >> $1;
    exit 0;
fi

# コミットメッセージの横の長さによってAAを変える
case $max_len in
    [1-9])
        echo "$( N_TONE )" > $1;;
    *)
        echo "$( DOG )" >> $1;;
esac

git commitでメッセージを確定させると末尾にAAが追加され、そのメッセージでcommitする。

学べたこと

ざっくり簡潔に

  • 文字列の長さを表示したい時は${#hensumei}と書く

  • whileでパイプを使うと別プロセスで実行され、ループ内部の変数の変化がループ外部で反映されない(ループ外部では値が変化していない)
  • forを使いパイプなしでファイルを一行ずつ読み込むことでそれを回避できる

  • ヒアドキュメント内にカッコが片側だけある場合の出力
test.sh
#!/bin/sh

echo $(cat << EOS
ヒアドキュメントの

例(
EOS
)

#$ sh test.sh
#  test.sh: line 3: unexpected EOF while looking for matching `)'
#  test.sh: line 9: syntax error: unexpected end of file
  • `" "`で囲むかfunctionの戻り値から受け取ることでエラーを回避できる
test.sh
#!/bin/sh

echo "`cat << EOS
ヒアドキュメントの

例(
EOS
`"

#$ sh test.sh
#  ヒアドキュメントの
#
#  例(
test.sh
#!/bin/sh

MY_FUNC(){
    cat << EOS
ヒアドキュメントの

例(
EOS
}

echo "$( MY_FUNC )"

#$ sh test.sh
#  ヒアドキュメントの
#
#  例(

おまけ

githubからコミットメッセージを見る

Mac
20191214-004410.png

Windows
commit.png

AAのバリエーションがもっと増やせるとよかったなあ と思うわんわんであった

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