20200524のGitに関する記事は15件です。

現在のブランチでpushする方法

現在ポートフォリオを作成する中で、

git add -A
git commit -m "test"
git checkout master
git merge XXXXXXX
git push 

の手順で、いつもリモートリポジトリにpushしていたのですが、

git push origin HEAD

でカレントブランチをリモートにpushできるみたいです。
gitは、チーム開発で必須なので、スムーズに使えるようにせねばですね。
コマンドも決まったものしか覚えていないので、少しずつ覚えていきたい所。

それでは。

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

git push時のエラー

状況

いつもどおりにgithubにリポジトリを作成したあとに、

$ git init
$ git add .
$ git commit -m "Initial commit"
$ git remote add origin https://github.com/XXXX/XXXXXX.git
$ git push -u origin master

をするとエラーが発生。

エラー内容

...
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
...

どうやらデータが大きすぎるようです。

解決法

ファイル直下に.gitignireファイルを生成し、中に必要ないファイル(/dataset,*/.dbなど)を書き込と、無事pushが成功しました。

参考

https://qiita.com/inabe49/items/16ee3d9d1ce68daa9fff

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

Git & GitHub (Enterprise) セットアップガイド on Mac OS X

インストールするソフトウェア

ここでは書かないが環境の前提

Termina: https://www.iterm2.com/ からインストール可能
zsh: Mac OS X default (since catalina) だが、 brew install zsh して最新版をインストールし、それを使う事を推奨。

Visual Studio Code

https://code.visualstudio.com/ からダウンロードしてインストール出来る。

起動語に、 [Command] + [Shift] + P から Install 'code' command in PATH を選択して、code というコマンドで起動するようにしておく。

image.png

shell で code --version と入力すると正しくインストールが終わったことを確認できる

% code --version
1.45.1
5763d909d5f12fe19f215cbfdd29a91c0fa9208a
x64

Source Tree

https://www.sourcetreeapp.com/ ここからダウンロードしてインストールする。

※ AppStore からダウンロードしたものは、shell コマンドがインストール出来ないのでアンインストールして↑から再インストールしないといけない。

無料のユーザー登録が必要なので、しておく(今無くなった?)

左上から、[コマンドラインツールをインストール] でコマンドラインツールのインストールを完了させる

image.png

% stree --version
stree version 1.3

git / git-lfs

  • git / git-lfs は brew 経由で入れれば良い brew install git git-lfs

確認は次の hub と同時に

hub

% brew install hub

hub コマンドは aliasing しておく必要があるため、以下を ~/.zshrc に記入します。

~/.zshrc
eval "$(hub alias -s)"

.zshrc を書き換えた後は、シェルの再読み込みが必要。
git / git-lfs とあわせて、以下の表示になるはずです。

% git --version
git version 2.26.2
hub version 2.14.1
% git-lfs --version
git-lfs/2.11.0 (GitHub; darwin amd64; go 1.14.2)

memo; GitHub CLI について

GitHubは米国時間2月12日、リポジトリーの管理をターミナル上のコマンドラインインターフェース(CLI)から行いたいと考えている開発者らに向け、公式のCLIツールを公開した。
https://japan.zdnet.com/article/35149382/

と鳴り物入りで作成された GitHub CLI ではあるが、2020-05 時点ではまだ GitHub Enterprise と連携できないなど、不十分な点が多い。

スグに patch されそうな気もするが、beta 期間中は対応予定が無いらしい。

While in beta, GitHub CLI is available for repos hosted on GitHub.com only. It does not currently support repositories hosted on GitHub Enterprise Server or other hosting providers. We are planning support for GitHub Enterprise Server after GitHub CLI is out of beta (likely toward the end of 2020)
https://github.com/cli/cli/tree/v0.8.0#availability

ghq

複数のリポジトリで作業する時、リポジトリを管理するためのコマンドです https://github.com/x-motemen/ghq
また、hub コマンドと組み合わせて使うため peco コマンドもインストールします

brew install ghq peco でインストール可能です。

https://github.com/Songmu/ghq-handbook/blob/master/ja/05-ghq-list.md を参考に、 ~/.zshrc に以下の項目を記入しておきます。
移動時に使います。

~/.zshrc
peco-src () {
    local repo=$(ghq list | peco --query "$LBUFFER")
    if [ -n "$repo" ]; then
        repo=$(ghq list --full-path --exact $repo)
        BUFFER="cd ${repo}"
        zle accept-line
    fi
    zle clear-screen
}
zle -N peco-src
bindkey '^]' peco-src

基本的な設定

以下では、ソースコードは ~/dev/src/ に checkout するものとします。(オススメ)

まず、以下の設定は必ずやっておきます。

git config --global user.name "FIRST_NAME LAST_NAME"
git config --global user.email "MY_NAME@example.com"

user.email は、会社で使う PC の場合、会社から貸与された email address にします。
(いずれにせよ、リポジトリ・サーバー単位で変更可能です)

氏名のフォーマットは、解らなければ周りの commit ログを確認しましょう。

code を editor として利用する

以下の設定で VS Code が editor として利用できます。

https://help.github.com/en/github/using-git/associating-text-editors-with-git#using-visual-studio-code-as-your-editor

$ git config --global core.editor "code --wait"

ghq

ルートディレクトリを指定します

$ git config --global ghq.root "~/dev/src/"

ここまでのテスト

ここまでの設定が旨く行けば、 github.com のリポジトリが簡単にクローンできるようになっていると思います。

試しに、 https://github.com/line/line-bot-sdk-java をクローンします

git clone は使う必要はありません

リポジトリをクローンしたい場合、単純に URL を copy して

image.png

任意のディレクトリで

ghq get (URL を貼り付け)

コマンドを実行すれば、自動的に ~/dev/src/github.com/line/line-bot-sdk-java/ にコードがコピーされます。

このときのパスは深いのですが、 [Ctrl] + ] で移動できますので、特に気にする必要はありません。

QUERY> sdk-java
/Users/kazuki-ma/dev/src/github.com/line/line-bot-sdk-java

GitHub enterprise に応じた設定

http://git.example.com で自社の GitHub enterprise が展開されているとします。

hub

hub コマンドに対して、サーバー git.example.com が GitHub Enterprise server だと通知する必要がある(複数設定可能)

git config --global hub.host git.example.com

設定を変更する

git.example.com 会社用 GitHub Enterprise と github.com のリポジトリそれぞれに対して操作する機会がある場合、サーバー名またはリポジトリ名毎のファイルを作って、条件つき include をすると良い。

以下の用に会社 mail address を global に設定している場合でも

git config --global user.email "MY_NAME@example.com"

~/.gitconfig_github.com を作成し、

~/.gitconfig_github.com
[user]
email = matsuda.kazuki@gmail.com

~/.gitconfig に条件付き include 設定を書いておけば良い

~/.gitconfig
[includeIf "gitdir:~/dev/src/github.com/"]
    path = ~/.gitconfig_github.com

minor, やる必要が無いことがほとんど) この方法は、Organization / Repository 単位でも有効なので、 github.com でも更に自分の organization xxx 向けの設定が必要であれば

~/.gitconfig
[includeIf "gitdir:~/dev/src/github.com/xxx/"]
    path = ~/.gitconfig_github.com_xxx

としておき、 ~/.gitconfig_github.com_xxx に自分の organization 向けの設定を書けば良い。

日常操作

リポジトリのデータを更新したいときは

ともかく PR するときは、fork することを基本だと思うのが良い。

ただし、fork してはいけない文化の所もある?(要出典)なので最終的にはリポジトリ毎のルールに従う必要がある
& 業務で GitHub の private repository を利用している場合、基本的に fork ができない。

fork したリポジトリで作業する方法

git の remote は複数登録できる、git において、リモートネーム origin は特別な意味を持つので、 origin は fork した自分の repository を指定しておくのがよい。

ghq で checkout した場合は多少手間なのだが、fork してから checkout するか、checkout したものに対して origin を fork 先に切り替えるのかで諸説ある。。

他の人の PR を review する方法

fork すると他の人の PR が review しにくくなる、という意見があります。

ディレクトリ移動

基本的に [Ctrl] + ] で移動が完了するはず。

普段の更新

普段の更新であれば、今の working tree (ディレクトリの中身) をそのまま commit したいはずなので、以下のコマンドを実行すればよい

git add -A && git commit

Visual Studio Code が起動して、メッセージ編集ができる。保存して閉じれば commit 完了

fixup

些末な修正でいちいち新規 commit を作る必要は無いので merge されるまでの修正は commit 追加ではなく、 commit を修正 (amend = 修正する、(欠点などを取り除いて)改める) する場合は、専用のコマンドがある。

staging していない場合は git add -u (or git add -A) した後

git commit --amend --no-edit すればよい

  • --amend = 直前の commit を修正する
  • --no-edit = commit log は修正しない

--no-edit を含めないと、amend したあとの commit ログを書き換える事ができる

git には alias の機能があるので、 git config --global alias.fixup 'commit --amend --no-edit' として、 git fixupcommit --amend --no-edit が呼び出せるようにしておいても良いだろう。

特定のファイルのみ commit

git add そのファイルのpath で staging した後に commit すればよい。
(この機能を使わなければならない場合、何かおかしいことをしている可能性もある

特定の patch のみ commit

git add -p でpatch を見つけても良いし、一般的には Sourcetree を使うのがよいだろう。

『ステージングを分割して表示』オプションを有効にするのがオススメ。

image.png

stree コマンドを実行すると、Sourcetree が起動するので、 commit したいものを staging (下の画面から check を付けて上に移す)をすれば良い。

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

Gitを使ってみた(windows)

この記事のモチベーション

コロナの影響で、会社以外で作業することが増えました。
それにより会社pcとリモートpcでのファイル同期をとる必要が出てきました。

現在は”Googleバックアップ同期”や”Dropbox”によるクラウドを使ったもので事足りていますが、そのうちバージョン管理をしておく必要のあるファイルも出てきそうなので、これを機にはじめてのGitにチャレンジしてみました!

この記事はその記録です。

前提条件と注意事項

  • Windowsでの操作を対象とします。
  • この記事は、Gitの全体像と操作の流れをなんとなく把握した人が、とりあえず自分だけでGitを試してみようときに見るとひょっとしたら役に立つかもしれない、という内容になっています。用語の解説はしません。チーム開発ではメンバに迷惑をかけないためにもう少し深い知識が必要になるかと思いますので、そういう方は他の記事で補足したほうがよろしいかと思います。

この記事で紹介する範囲

  1. 会社のpcでGitをインストールしてリモートリポジトリにpushし、
  2. 自宅pcでクローンして変更してpush、
  3. 会社のpcで変更を確認する、

と、いうところまでの最低限の内容になります。

1-0 会社のpcでの操作

1-1 GitHubの登録

https://github.com/ にアクセスしてサインインする

1-2 Git for windows のインストール

https://gitforwindows.org/ にアクセスし、OSにマッチしたセットアップファイルをダウンロードしてインストールする。
2020-05-24_16h52_53.png

1-3 差分の確認

1-3 GitBashでコマンドラインでの操作

Git for windows をインストールすると自動的にGitBashというターミナルアプリケーションがインストールされるので開きます。
こGitの操作はGitbashで行っていきます。
GitbashではWindowsのコマンドは使えなくなり、Unixライクなコマンドになるので注意です。

(win)chdir > (gitbash)cd
(win)rmdir > (gitbash)rm
(win)cd > (gitbash)pwd
(win)dir > (gitbash)ls

1-4 Gitバージョン確認

$ git --version
$ git version 2.25.1.windows.1

1-5 Gitの初期設定

# コミットする時の名前。チーム開発の場合は他者がわかる名前を使用しよう
$ git config --global user.name "YOUR NAME"
# メールアドレスの設定
$ git config --global user.email YOUR MAILADDRESS
# vscodeを使用するエディタとして設定。waitオプションを何故つけるかはググろう。とりあえずみんなつけてるからつける。
# 他のエディタを使用する場合はその設定をする。
$ git config --global core.editor 'code --wait'
$ git config user.name #ユーザ名の確認
$ git config user.email #Email設定の確認
$ git config core.editor #使用エディタの確認
"C:\Users\user\AppData\Local\Programs\Microsoft VS Code\Code.exe" --wait

1-6 Gitのローカルリポジトリを作成する

$ mkdir myportfolio #ローカルリポジトリとなるフォルダを新規作成する。
$ cd myportfolio #そのフォルダに移動する
$ git init #ローカルリポジトリとしてこのフォルダを設定する。
Initialized empty Git repository in C:/Users/user/myportfolio/.git/
# ↑これが表示されたらおk
# initコマンドにより.gitという隠しフォルダが作成される。下記はその中身。
$ ls .git
config  description  HEAD  hooks/  info/  objects/  refs/

1-7 ローカルリポジトリにaddしてコミットする

git add

$ git add ファイル名   #ファイル単位のadd
$ git add .   #カレントディレクトリ配下のファイル全部add

複数ファイルのaddには他にも-A-uがあります。

(公式ドキュメント) https://git-scm.com/docs/git-add

git commit

$ git commit -m "my first commit from my home"
[master (root-commit) c50ff18] my first commit from my home
 1 file changed, 1 insertion(+)
 create mode 100644 readme.txt

mオプションを省略すると、紐づいたエディタが起動してCOMMIT_EDITMSGが開きます。
最上行にコミットメッセージを入力して保存して閉じます。
2020-05-26_00h27_18.png

1-8 Gitリモートリポジトリを作成する

image.png

image.png
リポジトリ名を入力し、PrivateにしてCreateします。

image.png
赤枠①がリモートリポジトリのURLです。②のコマンドを実行するのでコマンドを1つずつコピーして実行していきます。

1-9 リモートリポジトリにpushする

先ほど作成したリモートリポジトリにローカルリポジトリのファイルを追加します。

git remote add origin

pushする際にリモートリポジトリURLを使用しますが、URLは長いのエイリアスを設定します。
エイリアス名として"origin"とすることが一般的なようです。

git remote add origin [リモートリポジトリURL]

git push origin master

git remote add origin [リモートリポジトリURL]

2-0 自宅pcでの操作

この項は自宅pcで操作した内容です。自宅PCで上記1-2から1-5までを実行する。

2-1 リモートリポジトリURLの取得

image.png

先ほど作成したリモートリポジトリを開き、clone or downloadをクリックし、表示されたURLをコピーする。

2-2 Cloneの作成

initの代わりにcloneコマンドを使用します。管理するディレクトリにcdし、クローンコマンドを実行します。

$ git clone [リモートリポジトリのURL]

カレントディレクトリ配下にディレクトリが作成されるのでlsで確認する。

2-3 変更してaddしてcommitしてpush。

試しにpublicというディレクトリ配下にindex.htmlを作成したので、それをpushする。

$ git add public/index.html
$ git commit -m "first change from mobile pc"
[master 320bd13] first change from mobile pc
 1 file changed, 1 insertion(+)
$ git push orijin master
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 377 bytes | 377.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/JojiOkawa/myportfolio.git
   67c855a..320bd13  master -> master

3-0 会社PCで変更ファイルを受け取る

この項では会社PCでリモートPCが変更した差分ファイルを受け取ります。

3-1 git pull origin master

他の人(pc)の変更を、受け取るにはfetchpullで受け取ります。
本来はfetchしてmergeすることが一般的というか安全なようですが、今回は一人での作業ですのでpull(fetchしてmergeをいっぺんに実行するコマンド)を使おうと思います。

# 変更を受け取る
$ git pull origin master

3-2 差分を確認する

差分を受け取ることができたので確認してみましょう!

3-3 おわり

以上です。

error

  • fatal: remote origin already exists.
    • git remote origin [url]しようとしたときにすでに存在するといわれた。

    - git remote rm originして削除したらおkでした。

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

[Git] コミットメッセージをわかりやすく!ヒアドキュメント・prefixを使おう

コミットメッセージbefore/after

今見返してみると
Git使い始めの自分のコミットメッセージはカオスなものです。

早速、見てみましょう

改善前

Screenshot from Gyazo

現時点では
改善を加えた結果、わかりやすくなったと思います。

改善後

Screenshot from Gyazo

何ということでしょう、
あのカオスなコミットメッセージが読めるものとなっているではないですか‥!

では、どのようなことを変更して改善したのか記したいと思います。

改善① コミットメッセージの改行機能を使った

コミットメッセージはターミナル上でも改行することが可能なんですよね。
それを知らず、内容を1行に詰め込まなければ‥と思いこうなってしまっていたわけです。  
(再掲)

Screenshot from Gyazo

コミットメッセージを改行するには

ヒアドキュメントを使います。

$ git commit -F- <<EOM
# Fは大文字でなければ、エラーが出ます
# ヒアドキュメントの識別子としてEOM(End Of Message)を使います

コミット作成してみましょう。

Screenshot from Gyazo

returnキーでどんどん改行することができます。
改行時に現れるheredoc>はコミットメッセージには残りません。

$git log で先ほど作成したコミットを確認すると

commit 691e97d7bc729922500cb1ae176b254e734d9f46 (HEAD -> #16)
Author: Watashi <Watashino@mailaddress.com>
Date:   Sun May 24 14:51:34 2020 +0900

    [feat]Commit

    line1
    line2
    line3

改行できてます!

改善② Prefixを使うことにした

こちらで紹介されているPrefixを使うことにしました。

・[feat] : 新機能追加

・[fix] : バグの修正

・[docs] : documentの修正のみ

・[style] : コードの機能に影響しない修正(空白スペース、セミコロン抜け修正など)

・[refactor] : featでもfixでもない修正

・[perf] : パフォーマンスを上げるためのコード修正

・[test] : テストコードの修正

・[chore] : ビルドプロセスの変更、補助ツール、ライブラリの変更など

よく使うのはやはり[feat][fix]ですが、
RUNTEQの課題に勤しむ時、
RoboCopのLintチェックの指摘部分を修正する時は[style]
RSpecのhave_contentで指定したテキストにしていなくてテストが通らない時は[docs]
などを使うようにしています。

本記事の改善で
・コミット内容を多く記述できるようになり、コミット粒度を大きくすることが可能になった
・のちのちのコミットの確認に困ることが少なくなった
というような感じです

コミットも捗って、草もどんどん生やせますね♫

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

データサイエンティストがPythonでシステム開発する前に読む記事

広告運用自動化関連のプロジェクトで、他部署のデータサイエンティストがアルゴリズムの開発担当として、私がシステム担当兼レビュワーとしてアサインされました。

ただまだ分析以上のプログラミング経験はあまり無いそうで、知らない単語が芋づる式に出てくる状態のようです。それぞれの考え方を教えようにも、このコロナ影響下ではホワイトボードも使えないし、zoomのミーティングの時間を取るのもお互い負担が大きかったので、まずQiitaで共有することにします。

同僚に間違ったことを教えていたら困るので、もし誤っている箇所やアドバイスがあればコメント頂けると嬉しいです。

バッチプログラムの実行について

現在開発している広告運用自動化システムでは、AWS Data Pipelineを使っておおよそ以下のような環境で動いています。

  • 事前にソースコードをまとめてzipファイルにしてS3にアップロードしておく
    • この処理はリポジトリのmasterブランチにpushしたときにCI/CDツールが動いて自動で行っています
  • Data Pipelineの定期実行機能により、EC2インスタンスを立ち上げる
  • Data Pipelineが「S3からプログラムや依存ライブラリをインストールして実行する」シェルスクリプトを実行する
  • EC2インスタンスをシャットダウンする

もし今後Dockerを使ったシステムに移行した場合は「ソースコードをまとめてzipファイルにしてS3にアップロード」が「DockerイメージをビルドしてAmazon ECRにプッシュする」に変わります。少し余談ですが、「アプリ開発者自身がDockerfileでプロダクトに必要な言語やミドルウェアを記述できるようになり、インフラ部門に依存せずに素早く設定を更新できる」というメリットもあります。

そもそも、AWSのサービスが多すぎて「このサービスとこのサービスって何が違うんだ?」などと困る場面もあるかもしれません。私も苦労しました。AWSのソリューションアーキテクトのテキストの関連項目に目を通しておくことといいかもしれません。

また、現状では各バッチ処理を指定時間にcron実行しているだけで、連鎖的に失敗して再実行にも手間がかかっています。それをバッチの依存関係を明示して解決するのがAirflowやDigDagなどのワークフローエンジンです。(※AWS Datapipelineもワークフローとして実行するためのサービスなのですが、GUIの管理が煩雑でうまく設定できていません)

他の問題を優先して対処していたのですが、ずっと解決しないのも問題なのできちんと動こうと思っています。

開発用ツールについて

gitやpoetryなどについて質問された項目です。

Pythonやライブラリのバージョンについて

開発では「プロジェクトAでは最新のPython3.8を使いたいが、プロジェクトBではライブラリが対応してないのでPython3.7を使いたい」というような場合があります。

私は pyenv でPython本体のバージョンを切り替え、ライブラリは poetry を使って管理しています。次の記事を参考にしてください。

少し前まで poetry と同じ用途で Pipenvが流行っていたのですが、現在開発が滞っているようです。例えば「If this project is dead, just tell us」というISSUEが作られてしまっていました。(※ただし、先程確認したら2020年4月1日に2年越しにリリースされているようで、完全に開発が止まっているわけでは無さそうです)

poetryを利用すると pyproject.tomlpoetry.lock というファイルが生成されます。 pyproject.toml が利用しているPythonライブラリのバージョンなどのプロジェクトの設定で、 poetry.lock が実際にインストールした依存ライブラリのバージョンを固定するためのものです。それには以下のようなメリットがあります

Committing this file to VC is important because it will cause anyone who sets up the project to use the exact same versions of the dependencies that you are using. Your CI server, production machines, other developers in your team, everything and everyone runs on the same dependencies, which mitigates the potential for bugs affecting only some parts of the deployments.

(Google翻訳)このファイルをVCにコミットすると、プロジェクトを設定したすべてのユーザーが、使用している依存関係とまったく同じバージョンを使用するようになるため、重要です。CIサーバー、プロダクションマシン、チーム内の他の開発者、すべておよび全員が同じ依存関係で実行されるため、デプロイメントの一部にのみ影響するバグの可能性が軽減されます。

Pythonに限らず、他のプログラミング言語でも同じようなツールが存在します。例えばRubyのrbenvやBundler、node.jsならnvmやnpm(他にもいろいろあるらしい)などを使います。他言語でもツールごとに微妙にカバーしている範囲は違いますが、お互い影響を与え合って似ている部分も多く、例えば ***.lock が用意されていたりします。

コードのバージョン管理(git)について

gitについては長くなってしまうので入門記事を読んでください。最初は難解だと思いますが、「ブランチ」の必要性を理解すると自分で調べられるようになると思います。

基本的に「別のブランチで開発(コミット)して、リリース用ブランチにマージする」というスタイルで開発します。これにより複数人が別の機能を追加したいとき、同時に別ブランチで開発できます。

SubversionとGitの大きな違いはブランチ管理あると私は考えています。最近のソースコードのバージョン管理では、機能開発やバグ修正の専用ブランチを作ってリリース用ブランチへマージする開発スタイルが主流になってきており、開発プロジェクトにおいてコードのブランチ管理は必要不可欠であると言えます。

上記にある通り、git以前からSubversionというツールもあったのですが、ブランチの使い勝手が非常に悪いせいでほぼ駆逐されてしまったそうです。余談ですが、リーナス・トーバルズ(gitやLinuxカーネルの開発者の偉大なプログラマーだが、口が悪いことでも有名)が特にこの点でSubversionをこき下ろしているというニュースもありました。

「Github上でリリース用ブランチにマージすることを依頼する」のがよく聞くプルリクエストです。また、ブランチの運用方法にはgitflowやgithubflowなどがあり、今やってる広告運用自動化のシステムではgitflowを採用しています。

sshについて

ssh接続して作業することもあると思います。その際に、秘密鍵のほうを絶対に他人に漏らさないように気をつけてください。

公開鍵認証において、サーバに登録するのはユーザの公開鍵です。そして、認証時には秘密鍵そのものではなく、生成した署名データ、それも流用困難なものをサーバに提示します。そのため第三者はもちろんサーバであっても秘密鍵を入手したり、署名を悪用することは困難です。

実装について

Pythonのコードを実装する際に気をつける点をまとめておきます。

ドキュメンテーションや型ヒントについて

他の人が読みやすい状態にしておく。ひとまずこれやっといてください。

  • README.mdをきちんと書く
  • Docstrings(関数にあるコメント)をきちんと書く

Docstringsも何種類かスタイルがあり、numpyスタイルやGoogleスタイルなどがあります。自分たちはGoogleスタイルを採用しています。

私はVSCodeのプラグインのPython Docstring Generatorで補完するように設定しています。他のIDEやエディタでも同様のツールがあると思います。

型ヒントも基本的にはドキュメンテーションの役割だけを果たしています。そのためコードの実行時に間違った型を入れてもエラーが出ません。

def greeting(name: str) -> str:
    return f"Hello, {name}"

print(greeting(1))
# => "Hello, 1"

「基本的」というのは、 mypy という静的解析ツールで型情報が間違ってないか自動でテストを行うことができることと、一部のライブラリ(後述するpydanticなど)では実行時に型の情報を使う場合もあるからです。

型ヒントを使う際は、 List[str] だとか Dict[str, str] などの記述方法を知っておく必要があります。余裕があるときに次の記事を読んでおくと良いです。

ロギングについて

私のコードの中に logging を使ったコードがあり、Pythonの公式ドキュメントのLogging HOWTOも圧があるので困ってしまったと思います。

簡単に説明すると、 print 関数に比べてログを残す際に便利な以下のような機能があります。

  • 出力先(ログファイル、標準出力)を設定できる
  • ログレベル(DEBUG, INFO, ERRORなど)を切り分けられる。また「開発環境ではDEBUGを表示するが、本番ではINFO以上にする」などの切り捨て設定もできます。

より具体的には以下の記事を参考にすると良いと思います。

ただ、私も開発時は厳密にやっているわけではなく、実装時のデバッグは print を使って必要なら後で logging を使った形に置き換えるように実装しています。

アプリケーションの設定について

アプリケーションの設定(どのS3パスを使うとか、不動産マーケットを実行するかとか)は以下のような方法で行います。

  • 環境変数にセットする
  • コマンドライン引数で渡す
  • 設定ファイル(jsonやyamlなど)を用意する

環境変数を使う

アプリケーションの設定は、基本的に環境変数にセットします。Twelve-Factor Appという有名なアプリケーション開発の指針にこの項目があります。

アプリケーションの 設定 は、デプロイ(ステージング、本番、開発環境など)の間で異なり得る唯一のものである。設定には以下のものが含まれる。

  • データベース、Memcached、他のバックエンドサービスなどのリソースへのハンドル
  • Amazon S3やTwitterなどの外部サービスの認証情報
  • デプロイされたホストの正規化されたホスト名など、デプロイごとの値

こうすることで、いろいろとメリットがあります。実感しやすいのだと以下のようなものです。

  • 開発環境と本番環境でデータソース(S3、RDB、BigQuery...)を切り替えたい場合にも、コードを変更せずに実現できる
  • 秘匿情報がコード内に現れないので安全で、OSSとしても公開できる

Pythonのコードでは普通、環境変数は os.environ を使って以下のようなコードを書くことになります。

import os
SOME_VALUE = os.environ['SOME_VALUE']

# 数値のリストがほしいときなど、少し型変換が必要だったり煩雑なんですよね…
SOME_INT = int(os.environ["SOME_INT"])

ただ、私は最近 pydantic というライブラリを使っています。それを使うと以下のようなコードになります。

from pydantic import BaseSettings

class Settings(BaseSettings):
    some_value: str
    some_int: int # 自動でintに変換してくれる

settings = Settings()

開発時に .env というファイルを利用することがあり、自分の使っているMacの環境変数をセットせずに、一時的にファイルから読み込むことができます。ちなみにpydanticも.envの利用もサポートしているので便利です。

ここで実際に私が実装したコードを見て、「pydanticで環境変数を読み込んでいるのに、osモジュールがimportされているのはなぜだろう」と疑問に思ったと思います。それは消し忘れなので後で隠滅しておきます。

また、今のシステムで動いているコードでも、環境変数として切り出すべき設定項目がコード内に含まれてしまっているものも多いです。他のコードを参考にする場合は気をつけてください。

コマンドライン引数を使う

環境変数との使い分けは明確な基準を持っていたわけではありませんが、コマンドライン引数と環境変数の使い分け基準という記事を見つけました。今回実装している広告運用費のアラート機能では、「開発時に賃貸マーケットごとだけ実行して確認する」みたいな用途も多そうだったのでコマンドライン引数で指定するようにしています。

Pythonの標準にも argparse というライブラリがありますが、多くのPythonプログラマーは clickを使っています。

少し余談ですが、awesome-pythonというリポジトリにPythonの便利ライブラリのうち、 click のような評判の良いものの情報がまとまっています。他のプログラミング言語に挑戦する場合もawesome-xxxで調べると大抵同じような情報が見つかるでしょう。

テストコードについて

今回は単純な通知処理なのでテストコードはサボってしまいましたが、各モジュールごとにユニットテストを行います。標準ライブラリと unittest とサードパーティ製の pytest がありますが、私は使い勝手の面で pytest をおすすめします。

あと、toxというツールも見つかると思いますが、「複数のPythonバージョンでpytestやunittestを実行するためのツール」であり、特定のシステム上で動かす場合はPythonバージョンは固定されているはずなので今は考えなくていいです。ライブラリを自作するときに導入を考えればいいです。

境界値分析などの知識が多少必要となります。コロナ騒ぎが明けたら、QAの人にこの本を借りると良いと思います。

その他、プログラミング全般で気をつけること

コードレビューで教えます。書籍であれば、このあたりがおすすめです。

また、こちらの本もピッタリかもしれません。今回WEBサーバーの話は全く書いていませんが、この本にはそこで詰まるだろうことも書かれています。

最後に

強くなれ?

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

Visual Studio Code で Git Commit 時に Signed-off-by: を commit message に入れるには?

「設定」の「拡張機能」の「Git」で「Always Sign Off」にチェックを入れると良い。

Screenshot from 2020-05-24 13-26-23.png

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

Visual Studio Code で Git Commit 時に GPG署名するには?

「設定」で拡張機能「Git」の「Enable Commit Signing」にチェックを入れれば良い。
Screenshot from 2020-05-24 13-10-33.png

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

ブランチを切って過去のコミットを取り入れる方法

前提

・現在masterブランチにいる。
・masterブランチには最新のコミットをpush済み。
・テストが通らなくなったので怪しいコミットの部分まで遡りたい。

$  git log   #戻りたいコミットIDをコピーする

$  git checkout -b testbranch   #masterブランチから検証用のブランチを作成

$  git reset --hard #戻りたいコミットID

$  git log  #過去の怪しいコミットに戻れているか確認。

念の為ローカルのファイルにも反映されているか目視で確認しましょう。

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

プルリクエストを使用した開発について 〜自分用〜

プルリクストとは

Pull Requestの略で、Githubの機能の一つ。誰でもどんなリポジトリに対しても、修正や機能追加を提案できる機能。

共有のリポジトリ(master branch)を操作することが出来るのは、基本的にリポジトリの管理者だけである。チーム開発をする際はBranchを切り、別のBranchから、本番環境に対してプルリクを出し、採用となれば(マージ)、本番環境に反映する。

プルリクエストを使った開発プロセス

プルリクエストを利用したプロセスは、以下の流れで行う。

1.[ 開発者 ] 作業対象のソースを clone または pull。

2.[ 開発者 ] 作業用のブランチを作成。

3.[ 開発者 ] 機能追加、改修といった開発作業を行う。

4.[ 開発者 ] 作業が完了したら pushを行う。

5.[ 開発者 ] プルリクエストを作成する。

6.[ レビュー・マージ担当者 ] 通知されたプルリクエストから変更を確認しレビュー。

7.[ レビュー・マージ担当者 ] レビュー結果を判断し、必要ならば開発者にフィードバック。

8.[ レビュー・マージ担当者 ] レビューの結果、問題がない場合はマージする。

9.[ レビュー・マージ担当者 ] レビューの結果、対応自体が不要となるなど、プルリクエスト自体が必要ない場合はクローズする。

上記の3〜7の工程を、必要な分だけ繰り返す。その結果、最終的にマージされるソースコードの品質を向上させる。

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

【Railsチュートリアル】第2章のまとめ


はじめに

この記事ではRails チュートリアルの第2章
についてまとめた記事です。
ベストプラクティスや間違いがあれば
チュートリアルをやりながら書き直していく予定です。

今回知ったこと

・データモデルを作成できる。
・データモデルを作成するときはscaffoldジェネレータを使う。
・データモデルを作成したらマイグレーションを必ず行う。
・データモデルはModelsにhas_manyとbelongs_toを使うことで関連付けできる。

・Railsにはルーティングという仕組みがある。
・ルートURLにアクションを指定すると表示するページを操作できる。
・modelsを編集することで簡単な入力のサニタイズが可能

データモデルを作成

データモデルを作成するときはscaffoldジェネレータを使う。

nameカラム,emailカラムをもったUserというデータモデルを作成する。
rails generate scaffold User name:string email:string

データモデルを作成したらマイグレーションを行う。
rails db:migrate

ルーティングという仕組み

インフラ屋でIPアドレスのルーティングを書いたことがある人は
ちょっとだけ親しみのある言葉かと思う。

リクエスト文字列に応じて
表示するページや動作を変更できる。

チュートリアルでは動作のことをアクションと表記している。

URL/show 表示
URL/new 新規作成
URL/edit 編集

入力のチェック・無害化

入力のサニタイズはmodelsを編集することで可能

チュートリアルではmicropostのデータモデルを編集した。

class Micropost < ApplicationRecord
  belongs_to :user
  validates :content, length:{maximum:140},
                      presence: true
end

Rubyとオブジェクト指向(OOP)

今回作成したデータモデルmicropostを操作するMicropostは
ApplicationRecord クラスを継承したクラス

まぁ、わからない人は2代目 ApplicationRecord という
認識でだいたい問題ないです。

ApplicationRecordというのがスーパークラス(ベースクラスともいう)

親:ApplicationRecord
子:Micropost

という感じ

エラー対応

gitでリモートリポジトリにpushしてたら
いろいろ行き詰ったのでメモ

SSH RSAキーを登録していないパティーン

アクセス拒否(publickey)
リモートリポジトリが読み込めませんでした。
Permission denied (publickey).
fatal: Could not read from remote repository.

対処方法

1:鍵を作成する。
2:作成した鍵をコピーする。
3:gitghubに公開鍵を登録する。
4:configファイルを作成し直す。(接続確認)
鍵がすでにあれば cat コマンドで表示する。
鍵があるリポジトリ内で以下のコマンドを叩き
GitHubに登録
cat ~/id_rsa.pub

リモートリポジトリにリポジトリがあるパティーン

リモートリポジトリにすでにoriginが存在しています。
fatal: remote origin already exists.

解決策
git remote rm origin originの削除
git remote add origin git@bitbucket.org:ユーザー名/アプリ名.git
git push -u origin master

削除しちゃって問題ないのかって?
今、自分の手元にあるリポジトリが最新であれば問題ないかと思う。
そもそも、リモートのほうが新しい状態って結構異常かと思う。

今回忘れてたこと・コマンド

git remote add origin リポジトリ
git push -u origin master

出力メッセージの英語翻訳(まとめ)

チュートリアルの最中に気になった文言

単語 日本語
On branch master マスターブランチを参照しています
No commits yet まだコミットされていません
Changes to be committed コミットされる変更
Changes not staged for commit 変更がステージングされていません
nothing to commit, working tree clean 作業ツリーにコミットするものは何もありません
discard changes in working directory 作業ディレクトリの変更を無視する
fatal: remote origin already exists. リモートリポジトリにすでにoriginが存在しています。
Permission denied (publickey). アクセス拒否
fatal: Could not read from remote repository. リモートリポジトリを読み込めませんでした。
GitHub found 6 vulnerabilities GitHubが6個の脆弱性をみつけたよ

herokuのインストール方法
source <(curl -sL https://cdn.learnenough.com/heroku_install)

スペルミスで発生したエラー文
Range unspecified. Specify the :in, :within, :maximum, :minimum, or :is option.

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

【Railsチュートリアル】第2章にあるGitのこと


はじめに

この記事ではRails チュートリアルの第2章
についてまとめた記事です。
ベストプラクティスや間違いがあれば
チュートリアルをやりながら書き直していく予定です。

今回知ったこと

・データモデルを作成できる。
・データモデルを作成するときはscaffoldジェネレータを使う。
・データモデルを作成したらマイグレーションを必ず行う。
・データモデルはModelsにhas_manyとbelongs_toを使うことで関連付けできる。

・Railsにはルーティングという仕組みがある。
・ルートURLにアクションを指定すると表示するページを操作できる。
・modelsを編集することで簡単な入力のサニタイズが可能

データモデルを作成

データモデルを作成するときはscaffoldジェネレータを使う。

nameカラム,emailカラムをもったUserというデータモデルを作成する。
rails generate scaffold User name:string email:string

データモデルを作成したらマイグレーションを行う。
rails db:migrate

ルーティングという仕組み

インフラ屋でIPアドレスのルーティングを書いたことがある人は
ちょっとだけ親しみのある言葉かと思う。

リクエスト文字列に応じて
表示するページや動作を変更できる。

チュートリアルでは動作のことをアクションと表記している。

URL/show 表示
URL/new 新規作成
URL/edit 編集

入力のチェック・無害化

入力のサニタイズはmodelsを編集することで可能

チュートリアルではmicropostのデータモデルを編集した。

class Micropost < ApplicationRecord
  belongs_to :user
  validates :content, length:{maximum:140},
                      presence: true
end

Rubyとオブジェクト指向(OOP)

今回作成したデータモデルmicropostを操作するMicropostは
ApplicationRecord クラスを継承したクラス

まぁ、わからない人は2代目 ApplicationRecord という
認識でだいたい問題ないです。

ApplicationRecordというのがスーパークラス(ベースクラスともいう)

親:ApplicationRecord
子:Micropost

という感じ

エラー対応

gitでリモートリポジトリにpushしてたら
いろいろ行き詰ったのでメモ

SSH RSAキーを登録していないパティーン

アクセス拒否(publickey)
リモートリポジトリが読み込めませんでした。
Permission denied (publickey).
fatal: Could not read from remote repository.

対処方法

1:鍵を作成する。
2:作成した鍵をコピーする。
3:gitghubに公開鍵を登録する。
4:configファイルを作成し直す。(接続確認)
鍵がすでにあれば cat コマンドで表示する。
鍵があるリポジトリ内で以下のコマンドを叩き
GitHubに登録
cat ~/id_rsa.pub

リモートリポジトリにリポジトリがあるパティーン

リモートリポジトリにすでにoriginが存在しています。
fatal: remote origin already exists.

解決策
git remote rm origin originの削除
git remote add origin git@bitbucket.org:ユーザー名/アプリ名.git
git push -u origin master

削除しちゃって問題ないのかって?
今、自分の手元にあるリポジトリが最新であれば問題ないかと思う。
そもそも、リモートのほうが新しい状態って結構異常かと思う。

今回忘れてたこと・コマンド

git remote add origin リポジトリ
git push -u origin master

出力メッセージの英語翻訳(まとめ)

チュートリアルの最中に気になった文言

単語 日本語
On branch master 親ブランチを参照しています
No commits yet まだコミットされていません
Changes to be committed コミットされる変更
Changes not staged for commit 変更がステージングされていません
nothing to commit, working tree clean 作業ツリーにコミットするものは何もありません
discard changes in working directory 作業ディレクトリの変更を無視する
fatal: remote origin already exists. リモートリポジトリにすでにoriginが存在しています。
Permission denied (publickey). アクセス拒否
fatal: Could not read from remote repository. リモートリポジトリを読み込めませんでした。
GitHub found 6 vulnerabilities GitHubが6個の脆弱性をみつけたよ

herokuのインストール方法
source <(curl -sL https://cdn.learnenough.com/heroku_install)

スペルミスで発生したエラー文
Range unspecified. Specify the :in, :within, :maximum, :minimum, or :is option.

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

対象ファイルがいつ・どのcommitで削除されたかを調べる

これ何

対象ファイルを削除したcommitを見つける git コマンドをまとめる。

コマンド

次のコマンドで検索することができる。

git log -- target_file_path

git log-- の間にoptionも追加することができる。
自分は次のようなコマンドをよく使う

  • コミットメッセージを1行で表示したい場合は --oneline
  • 最後の1commitだけみたい場合は -n 1

参考文献

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

ひとりぼっち開発のGit入門

Gitについて話してほしいというリクエストがあったので作成しました。勉強会用の資料です。

対象として想定しているユーザー

チームではなく、個人で使用するときに便利な使い方を紹介します。
全体像というより、個人で開発するときに使うものだけをピックアップしています。

  • gitを使ったことない人
  • チームではなく、個人のローカル環境で効率よく開発を進めたい人
  • 基本的なコマンドは学習している人

を対象にしています。

導入

Gitの使い方を紹介します。
個人開発をするにあたって、gitが使えるようになるとすごく便利です。

何かしらのチュートリアルに沿って学習するとき、設定ファイルを編集して、動かなくなった経験はないでしょうか?

私はあります。

gitを知らなかったころは、最初のフレームワークをインストールするところからチュートリアルをやり直すということも何度かありました。

そういった悪習を変えるためにgitを学びましょう。

gitはある段階まで戻るということを可能にします。
フラれたあの子にもう一度、今度は違うアプローチで告白してみよう。そんなことを可能にするのがgitです。

失敗をなかったことに、また、あのセーブポイントからやり直す。

それがgitです。

さあ、terminalを開いて、作業をしているディレクトリに移動しましょう。

git init

僕と契約して魔法少女になってよ!
という感じで、gitと契約するコマンドです。

これでアタナはタイムリープを行う権利を獲得します。
現在いるディレクトリに.gitという名前の隠しファイルが作成され、そこにセーブデータが保存されていきます。

ユーザー登録

名前とアドレスを登録します。
だれが編集したかわかるようにするためのものです。個人で使う場合はあまり意味がありませんが、以下のコマンドで登録します。

git config user.name user
git config user.email user@test.com

git add .

addの後ろについている.はすべてのファイルを指します。
コマンドを実行したディレクトリのすべての状態を仮セーブします。

git commit -m 'first'

セーブです。最初のセーブはfirst commitと言います。
addとcommitは個人開発ではセットで使って良いです。
addが下書き保存。commitが本当の保存というイメージです。

commitしたときだけセーブポイントが作成されます。

-mはセーブする際にメッセージを一緒に書くときにつかうコマンドオプションです。git commitとするだけとメッセージを記載するファイルが自動的に開いて面倒です。
基本的にgit commit -m 'メッセージ'を基本形として覚えてよいと思います。

使いこなす

udemy等で、チュートリアル等でコードを書き写したりする際に、gitを使ってみましょう。

下記のような感じでレッスンごとに区切りのタイミングでgitにcommitすることでセーブポイントを作成しています。万が一直せないような失敗をしてしまった場合でも被害が少なくて済みます。

Screen Shot 2020-05-22 at 16.17.23.png

レッスン名や、何を学習したのか、コメント等で振り返れるようにします。

git status

addやcommitした内容と現在を比べて変更したファイルを表示させることができます。
いじってしまったけど、どこをいじったのかわからない。というときに使えます。

Screen Shot 2020-05-24 at 7.33.43.png

git diff

git statusの詳細バージョンです。
git statusではファイル名のみでしたが、どこを変更したのか確認することができます。フレームワークとか入れてみたときにどこが変更されたのか、など確認できます。

Screen Shot 2020-05-24 at 7.39.47.png

git reset HEAD

git add .した内容を取り消すことができます。

git reset --hard HEAD^

直前のcommitで作成したセーブポイントを取り消します。

前回のcommitしたセーブポイントからやり直す

git checkout .

前回のコミットからファイルの変更をリセットしてくれる。
新規追加したファイルは削除されない。
追加したファイルも消して、完全に元に戻したいのであれば別途消去コマンドを打つ。

git clean -df .

git log

commitしたセーブポイント一覧を見ることができます。

Screen Shot 2020-05-24 at 7.27.06.png

git logのオプション

git logコマンドは様々なオプションをつけることで多様な参照をすることができます。

git log -oneline

長ったらしくなりがちな、git logの記述を一行で表現することができます。
Screen Shot 2020-05-24 at 7.51.51.png

git log -p

commitされたセーブポイント間の差分を見ることができます。

Screen Shot 2020-05-24 at 7.25.28.png

git log 応用編

色指定したり、ほしい情報だけ出力したり、いろいろできます。私はコミットメッセージに日時と時間を入れていましたが、git logのオプションコマンドを使うことで不要になりますね。

git log --graph --date=short --decorate=short --pretty=format:'%Cgreen%h %Creset%cd %Cblue%cn %Cred%d %Creset%s'

Screen Shot 2020-05-24 at 8.05.26.png

Tips

個人的に使っている設定

git ignore

差分を表示します。

作業ファイル内にメモを残すので、メモを除外するように設定しています。
メモした内容がセーブポイントを遡るごとに初期化されては困りますもん。
せっかくなので、vimを使ってファイルの作成と編集を行います。

vim .gitignore

vim内で、マークダウン形式のファイルをすべて除外すると設定して、:wqで保存して閉じます。

*.md

.gitignoreファイルに、gitでセーブポイント作成するときに除外してほしいファイルやディレクトリのパスを書き込むことでそれを無視して進めてくれます。
パスを書くときは改行してくださいね。

エリアス

gitコマンドはエリアスと呼ばれるショートカットを作成することができます。

.gitディレクトリの中のconfigファイルを編集することで反映させることができます。

 [alias]
   st = status
   co = commit
   logs = log --graph --pretty=format:'%Cred%h%Creset %Cgreen%cd%Creset %s %C(yellow)%d%Creset %C(244)%cr:' --date=format:'%Y/%    m/%d %H:%M'     

コマンドで設定する場合は、git config [option] alias.短縮形 展開形の形で記述します。
git config alias.st statusみたいな感じですね。

エリアスについては、この記事が詳しいのでおすすめです。
gitで便利なエイリアス達 - Qiita
色指定する場合はこちら
ターミナルで使える色と色番号を一覧にする - Qiita

まとめ

ぶっちゃけ、ここで紹介したことのほとんどが、vscodeの拡張機能でできちゃいます。
ただ、カスタマイズしたり、こういう機能があるということを知っていれば、検索等もしやすくなると思うので紹介しました。

ブランチの切り替えも重要なgitの要素だと思いますが、現状ブランチを分けるほどの開発をしていないので、また使うようになったら追記するかも。

いろんなツールを使いこなして、快適な開発ライフを送りましょう。

参考

git log よく使うオプションまとめ - Qiita
git ignoreを使ってファイルを無視する方法 | TechAcademyマガジン
【git addの意味とは?】必要性と便利なオプション[-A,-p…]を調査しました | memorandumrail

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

自分だけ git ignore したいファイルがあるときは git ignore global を使おう

概要

自分だけ git ignore したいファイルがあります。

例①

rubymine を使っており、.idea ファイルができてしまった。プロジェクト配下の .gitignore に追記したいが、
他のチームメンバー全員は他のエディタを使っているので .idea は生成されない。
.gitignore に自分の環境だけに生成されるファイルを追記したところで悪影響があるわけではないが、なんだか追記しにくい。

例②

.gitignore に追記した方が良いファイルを見つけたが直近で作成予定のプルリクエストにその修正を入れるのは
メインの変更内容の趣旨とは外れるのでやりにくい。しかし、ローカル環境での作業効率を上げるためにファイルを ignore したい。

git ignore global を使おう

すべてのgitプロジェクトに影響するignoreファイルを作ります。

参考: git ignore document
git ignore global

ドキュメントによると、プロジェクト配下の.gitignoreよりも前に読み込まれるパスがあり、
そこにignoreファイルを置くと、全プロジェクトに適用されるignoreになるということらしいです。

具体的には、下記記事の通りにします。

https://qiita.com/ueokande/items/e0409219e7c68e4277b9

下記ファイルにグローバルに適用したい設定を書いてください

mkdir $HOME/.config/git
vim $HOME/.config/git/ignore
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む