- 投稿日:2020-02-18T22:27:05+09:00
一度gitにアップしてしまった物をgitignoreする。
最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです!一度、git上にあげたものをignoreする
以前、robots.txtの内容・書き方を作成したんですが
robots.txtをStaging環境だけに反映し、本番環境には反映させないために一度、develop branchに上げた後、gitignore ファイルに追加する必要がありました!
master branchにも反映されてしまうのを防ぐために!
しかし、.gitignoreに記載したのに反映されず。問題
一度gitにアップしたものを、.gitignoreに追加したことが原因
キャッシュにインデックスが残っている状況
解決方法
こちらの方の方法通りにしたら無事、gitignoreに正しく反映されました!
.gitignoreに記載したのに反映されない件手順
1:.gitignore 編集
2:キャッシュを削除
3:commit & pushrobots.txtのgitのキャッシュを削除
$ git rm -r --cached robots.txt //ファイル指定してキャッシュ削除これで、gitでは管理されなくなりmasterに影響を与えずに済みました!
- 投稿日:2020-02-18T12:45:52+09:00
Git rebase は使えなくてもいい。あとGit cherry-pick と Git merge --squash も
おことわり:あくまでも個人の意見です
Microsoft本社で6年、いくつかのプロダクトチームで開発してきて思ったことです。
Git のコマンドで要らないもの
Git rebase は要らない
いろいろと利点だと思える点もあるようですが、マージコミットが無くて済むとか、コミットグラフが読みやすくなるとか、そういうコミットグラフの質が「製品・サービスの価値」に深く関わるとは思えない、というのが理由です。プライベートなブランチ間でやるなら構わないけれど「チーム全体のルール」にしてしまうと逆に作業効率が落ちると思う。
git rebase
の作業をする時間があったら、次のタスクに移った方がいいと思う。実際使ってる人はほとんど見かけない(というか使ってても見えてないだけかもしれないけど)。少なくとも自分使わない。Git cherry-pick は要らない
個人的には「百害あって一利なし」だと思います。一見便利そうだし実際便利かもしれませんが、開発のベストプラクティスというよりは「one-off(一度きり)のハック」だと感じます。例えば、緊急のバグを治す時に、開発ブランチから派生したホットフィックスブランチで治し、リリースブランチにチェリーピックする、という流れがありますが、ベストプラクティスは逆でリリースブランチから派生したホットフィックスブランチでそのバグだけを治し、リリースブランチにマージしてからさらに開発ブランチにもマージする、そうするとチェリーピックは要りません。
ある機能を限定的にリリースしたい場合、そもそも設計にフライティングの機能を入れて「露出していない」状態でリリースします。その後、フライティング設定で特定の機能を「露出」させると目的を達成できます。その機能のコミットが特定のブランチに含まれるかどうかが、ユーザがその機能にアクセスできるかどうかを制御してしまうのはブランチには荷が重すぎると思うのです。ベストプラクティスに近づけるためにも
cherry-pick
を使った裏技はチーム単位で非奨励とすべきだと個人的には思います。Git merge --squash は要らない
コミット毎にメッセージを細かく残したくないというのが動機のひとつのようです。ですが仮にコミットグラフに無駄なコミットやコミットメッセージが多く残ったとして、それが数週間後、数か月後、数年後にどのぐらい問題になるかとういうと、大した問題にはなっていないと思うのです。昔はせっせとsquashしてたけど今は全くやらない、って人も多いのでは?どうせsquashするからと、雑なコミットをすることを助長するぐらいなら、見えるからこそ「キリのいいところでコミットする」という習慣を付ける方が大切だと思う。周りでもsquashをする・しないを気にする人はあんまりいないと思う。
これだけ分かってればいい Git のコマンド
Git clone
レポジトリのコピー(クローン)を作るのに絶対必要。僕の場合、同じリモートのレポジトリでも複数作ります。同時にいくつかのブランチで作業をするめることもあるので。その時は下のように、末尾に2、3、4、と数字を付けてクローンします。
git clone https://github.com/yoshiwatanabe/test.git test2Git add
特に、
.
ワイルドカードを使って全てファイルをステージングエリア(インデックス)に移動するやり方git add .を多用してます。
間違ってステージングに入れてしまったファイルは
git reset HEAD <ファイルのパス>でステージから引きずり下ろします。
Git commit
git commit -m "コミットの目的"ほとんどこれで済ませます。
たまーに、
--amend
で忘れものを届けますが、それはまだコミットを例えばGitHubにまだpush
してない時に限ります。git commit --amendでもこれは絶対に必要というわけではありません。新しいコミットで忘れ物を届ければいいだけです。
「コミットはちゃんと完全なものにして、あとからコミットで忘れた箇所を変更するのはやめて。まだpushしてないなら commit --amendして」って同僚・上司に言われる、みたいなシチュエーションだとしたら、それはその人が「妙にこだわってるだけ」で、まぁお国柄とかチームの文化にもよるでしょうが、私がいたMicrosoftのチームでコミットの完全さにこだわる人は見たことがないです。そんなことよりさっさと次の仕事に移った方がいいですから。
Git fetch
もっとも安全でなおかつ出来るだけ頻繁に実行すべきGitコマンド。
git fetch手元にあるGitHubなどの中央レポジトリの状態を最新のものにしてくれます。
実は、このコマンドは中央レポジトリの最新の状態をダウンロードしてくるだけなのでこれだけではあまり意味がありません。私の作業ワークフローでは、このコマンドの後に
git pull
git merge
git remote prune origin
などが続きます(後述)
- ネット環境がないキャンプ場で仕事する予定がある場合、同僚のトピックブランチも含めて完全に最新の状態で出発したい
- 同僚のトピックブランチも見える状態になるので、だれがどのあたりのコードをいじってるか分かる
git pull
は実はgit fetch
とgit merge
のショートカットだという理解を深めるといった利点があります。
どちらにしろ、手元のレポジトリが中央レポジトリの最新版であることは悪いことではないです。
Git pull
じつは
git fetch
も裏でやってくれます。僕は癖でgit fetch
を個別にやってから、git pull
しますが、本当はgit fetch
は要らないですね(以前は 「git fetch
からのgit merge
」コンボでgit pull
そのものを使ってませんでした)git pull現在
checkout
中のローカルブランチを最新(=中央レポジトリでの該当ブランチの最新状態)のものにしてくれるんですが、その理由としてを2つのシチュエーションがあります。シチュエーション1
トピックブランチで作業を続けていて、まだしばらく作業時間がかかりそうな時、合流予定の合流先ブランチ(例:master)を最新にして、それを
git merge
でトピックブランチに引っ張って来る場合。この作業は大切です。なぜなら、自分のトピックブランチ(が含む合流予定先ブランチの内容)が遅れて居ればいるほど、同僚がすでに直したバグを再度治すというヘマ、同僚がすでにリファクターした便利な仕組みを見逃すヘマ、同僚がすでに削除してしまった古いコードのバグをお節介にも直して上げるヘマ、などが発生する確率が上がってしまうからです。
また頻繁にやるほど、コンフリクトが起こった場合の規模が小さくて済みます。
シチュエーション2
新しいタスクのためにコーディングを始める前、つまり新規トピックブランチを作成する直前に、出来るだけ最新の状態(中央レポジトリのそのブランチの最新のコミット)をスタート地点にするため。
Git merge
上の
git pull
のシチュエーション1の流れで、git merge
を使う、というパターンが9割りですね。たまに、同僚が進めている、完了間近のトピックブランチを自分の作業ブランチに取り込むために
git merge
することもあります。この場合、当然同僚が中央レポジトリにgit push
して該当ブランチを公開していることが前提になります。Git checkout
2つのシチュエーションがあります
シチュエーション1
ブランチの間を行ったり来たりする、つまり作業ディレクトリをいろんなブランチの状態に切り替えるため。特に頻繁に使うのが作業中のトピックブランチを、合流予定ブランチ(例:master)に対して、最新のものにする一連の作業をする時。
git checkout master git pull git checkout topics/task2 git merge masterみたいな感じで
checkout
で移動します。シチュエーション2
新規のトピックブランチを作成するとき。
-b
を指定して「新しいブランチを作って、そのブランチをチェックアウトする」という意味でgit checkout -b topics/task3とやります。
Git push
git push自分のトピックブランチを中央レポジトリにアップロードするために使います。私の一日の仕事は、
git push
で終わることが多いです。中央レポジトリにpush
すれば、クラウドストレージでバックアップされたことが確定するので、もしかりに自分のノートパソコンがどこかで水没してしまってもその日の作業内容は失われませんから。最終的な目的ブランチ(例:master)へは
push
ではなく、プルリクエストを使います。プルリクエストはGitのコア機能ではないですが、一般的な方法ですGit remote prune origin
これも安全なGitコマンドの1つです。ブランチのお掃除に使います。
git remote prune originからなず
git fetch
からやります。これは安全なコマンドなので使ってみれば簡単に理解できます。手元の中央レポジトリにあるブランチのうち、GitHubなどの中央レポジトリではすでに削除されてしまったブランチもあるかもしれません。というのも、開発者はトピックブランチの役目が終わったらそのブランチを削除してしまうことが一般的だからです。
このコマンドを使うことで、もう存在しない中央レポジトリのブランチを、手元の中央レポジトリでも消してくれます。
この後に
git branch -v
でブランチをリスト表示するとdev/topics/integration 37f95b9f9 [gone] add integration test dev/topics/topic3 711e639e2 [gone] adds unit test for logout feature dev/master e8468657b initial poc load testというように、もう存在しないブランチをトラックしている手元のブランチが見えます。こういった場合、
git branch -d dev/topics/topic3などでブランチを消してしまいます。
ブランチが
Git branch -v
上の例で挙げたように、すでに存在しない中央レポジトリのブランチをトラックしている手元のブランチが見えるようにするために使います。
Git branch -d
これも既出ですが、手元のブランチは出来るだけお掃除して数が増えすぎるのを防ぎます。
まとめ
私個人の作業ワークフローにおいて、必要としないGitコマンドと、頻繁に使うGitコマンドを紹介しました。
- 投稿日:2020-02-18T12:17:30+09:00
複数コミットをcherry-pick
1コミットをもってくる場合
branch-1のコミット履歴$ git log --oneline je903h92 commit 3 03843h90 commit 2 09459090 commit 1 87436843 first commitたとえば、
branch-2
に1つのコミットをもっていきたい場合は、git cherry-pick {commit number}
で解決できます。$ git checkout branch-2 $ git log --oneline 349fi29u new commit $ git cherry-pick je903h92 # commit 3をもってくる $ git log --oneline je903h92 commit 3 # コミットが追加されている 349fi29u new commit複数コミットをもってくる場合
例えばcommit 1、commit 2、commit 3をbranch-2へもってくる場合は、
git cherry-pick {start commit number}..{end commit number}
を叩けばもってくることができます。
ですが、start commit numberの部分は、もってきたい始めのコミットの1つ前のコミット番号を指定しなくてはいけません。$ git checkout branch-2 $ git log --oneline 349fi29u new commit $ git cherry-pick 87436843..je903h92 # commit 1~3をもってくる $ git log --oneline je903h92 commit 3 03843h90 commit 2 09459090 commit 1 349fi29u new commit
- 投稿日:2020-02-18T11:04:49+09:00
Gitコマンド逆引き
- 投稿日:2020-02-18T08:01:06+09:00
同じgit-hooksをリポジトリ個別指定で使えるようにするスクリプトを書いた
先日、globalなgit-hooksを設定して、すべてのリポジトリで共有のhooksを使うという記事で、git-hooksをグローバルに展開する方法を書きました。
今回は、それとは逆にRepositoryごとに個別にスクリプトを展開することが目的です。
グローバルなgit-hooksを用意したくないケース
基本的にはグローバルなgit-hooksの設定を用意すればいいですが、Repositoryごとに行うかどうかを変えたいということもあります。
例えば、会社のgitリポジトリにコミットする際に、git.emailが個人のものになっていないかチェックするスクリプトは、会社のRepositoryには適用したいですが、個人のRepositoryには適用したくないといった形です。
これを実現するために以下のスクリプトを書きました。
copy-git-hooks.sh#!/bin/bash -eu function echo_usage() { echo "usage: ${0} target_git-hooks_name target_git_dir_root_path" exit 1 } if [ $# -ne 2 ]; then echo_usage fi target_script=$1 target_dir=$2 GIT_ROOT=$(git rev-parse --show-superproject-working-tree --show-toplevel | head -1) SCRIPT_DIR="${GIT_ROOT}/git-hooks" if [ ! -e "${SCRIPT_DIR}/${target_script}" ]; then echo "${SCRIPT_DIR}/${target_script} not found." echo "" echo "ls ${SCRIPT_DIR}/*" ls ${SCRIPT_DIR}/* echo "" echo_usage fi if [ ! -d "${target_dir}/.git" ]; then echo "${target_dir} is not git root dir." echo "" echo_usage fi script_name=$(echo ${target_script} | cut -d "." -f 1) script_type=$(echo ${target_script} | cut -d "." -f 2) # まだ対象のhooksファイルがない場合、自動生成 if [ ! -e "${target_dir}/.git/hooks/${script_type}" ]; then echo '#!/bin/bash' >>"${target_dir}/.git/hooks/${script_type}" echo "" >>"${target_dir}/.git/hooks/${script_type}" chmod 700 "${target_dir}/.git/hooks/${script_type}" fi ln -s "${SCRIPT_DIR}/${target_script}" "${target_dir}/.git/hooks/__${script_name}" echo "source \$(dirname \${BASH_SOURCE})/__${script_name}" >>"${target_dir}/.git/hooks/${script_type}"使い方
以下のようなディレクトリ構成でスクリプトを用意します。
. ├── README.md ├── git-hooks │ └── personal_address_not_confirm.pre-commit └── script └── copy-git-hooks.shここでgit-hooksディレクトリには、
スクリプトの名前.git-hookのアクション名
という命名規則で、スクリプトのテンプレートを用意しておきます。たとえば、先程例にあげた「会社のgitリポジトリにコミットする際に、git.emailが個人のものになっていないかチェックするスクリプト」であれば、以下のようになります。
personal_address_not_confirm.pre-commit#!/bin/bash # personal_address_not_confirm ## git configをチェックして、user.emailが個人アドレスになっていないか確認 COMPANY_DOMAIN="example.com" git config user.email | grep -i ${COMPANY_DOMAIN} > /dev/null if [ $? -ne 0 ]; then echo "git user.email is $(git config user.email)." echo "It is not a company email address." exit 1 fiこれをスクリプトを使って、gitリポジトリに展開するときは、以下のコマンドを実行します。
./script/copy-git-hooks.sh personal_address_not_confirm.pre-commit /path/to/target-git-repositoryこれを実行することで、ファイル拡張子から自動的にアクション名を取得、
.git/hooks/
以下にスクリプトを配置します。
.git/hooks/にファイルが存在しない場合は、自動作成も行います。また、配置されるスクリプトは、
__${スクリプト名}
という命名で.git/hooks/
以下にシンボリックリンクを貼った上で、各アクションのスクリプトからsoruceで呼び出す形になっています。たとえば、上記のコマンドで
personal_address_not_confirm.pre-commit
を展開した場合、/path/to/target-git-repository/.git/hooks/pre-commit
には以下が書き込まれます。#!/bin/bash source $(dirname ${BASH_SOURCE})/__personal_address_not_confirmそして、
__personal_address_not_confirm
は、personal_address_not_confirm.pre-commit
へのシンボリックリンクになっています。$ ls -la /path/to/target-git-repository/.git/hooks/ drwxr-xr-x 16 user staff 512 2 18 05:56 ./ drwxr-xr-x 12 user staff 384 2 18 05:33 ../ lrwxr-xr-x 1 user staff 92 2 18 05:56 __personal_address_not_confirm@ -> /path/to/script_dir/git-hooks/personal_address_not_confirm.pre-commit -rwx------ 1 user staff 67 2 18 05:56 pre-commit* (以下略)これにより、git-hooksスクリプトを機能ごとに分割・一括管理した上で、Repositoryごとに展開できるようになりました。
- 投稿日:2020-02-18T00:56:37+09:00
Github CLI使ってみた[コマンド一覧]
前書き
最近出てきたCLIでGithubが扱えるソフトウェアGithub CLIを使ってみました。
いままでたくさんCLIツールはでていたのですが
https://qiita.com/ryuichi1208/items/45fd2cdd865097a7ad3d
公式出のツールは2つめ?っぽいです。(hubが最初?)この記事ではプルリクエストをPRと表記するときがあります
コマンド→解説の構成ですこの記事でやっていること
- Github CLIのコマンドの挙動網羅
この記事でやらないこと
- GithubCLIのインストール法の解説(公式に書いてあります)
- 既存のCLIソフトウェア(hub等)との比較
記事本体
GithubCLIで現在できること
- PRの作成
- PRの一覧表示
- PRのステータス表示
- PRのページをブラウザで開く
- PR対象ブランチへのチェックアウト
- issueの作成
- issueの一覧表示
- issueのステータス表示
- issueのページをブラウザで開く
今回全部試してみたので書いていきます。
プルリクエストの操作
PRの作成
Github CLIのプルリクエスト関連操作をまとめています
$gh pr create > Creating pull request for ブランチ名 into [Base Branch名] in ユーザー名/リポジトリ名現在のGitブランチを認識し、そのブランチからBase branch(github側で設定)へのPRとして作成されます
$gh pr create Creating pull request for ブランチ名 into [Base Branch名] in ユーザー名/リポジトリ名 ? Title READMEの開発項目のissue移行に際してのREADME修正 ? Body [(e) to launch nano, enter to skip]eキーを押すとnanoエディタが開き、本文部分のMarkdown記法での入力が可能です。
(ちなみにnanoエディタは書き終わったらCtrl + Oで保存→Enter(本来はここでファイル名を入力.Github CLIは勝手にやるので触らないのが吉?)→Ctrl + Xで閉じる)です
2019/02/18追記
PRのテンプレート(PULL_REQUEST_TEMPLATE.md)とかあると自動で読み込んでくれます!$ gh pr create Creating pull request for ブランチ名 into [Base Branch名] in ユーザー名/リポジトリ名 ? Title fff ? Body <Received> ? What's next? [Use arrows to move, type to filter] > Preview in browser Submit CancelPreview in blowserを選ぶと、Submit前のPRページに飛んでプレビューできます(ラベルとかレビュワーはここで設定する)
Submitはプレビューせずにそのまま送信されるPRの一覧表示
gh pr listで可能。現在出ているPRを、そのブランチと一緒にリスティングされる
PRのステータス表示
gh pr status /*以下出力*/ Relevant pull requests in YaCpotato/project_manager Current branch #17 READMEの開発項目の移行に際してのRE... [update/readme] Created by you #17 READMEの開発項目の移行に際してのRE... [update/readme] Requesting a code review from you You have no pull requests to review現在のブランチと、PRが出ていたらそれも出してくれる。あとは
* 他ブランチの自分が作ったPR
* コードレビューをリクエストされたPR
の3種類が見れるPRのページをブラウザで開く
gh pr view [PR番号(#12みたいな数字)] gh pr view #17このコマンドを打つと対象PRをブラウザで開いてくれる
PR対象ブランチへのチェックアウト
gh pr checkout [PR番号(#12みたいな数字)] gh pr checkout #17そのPRが出されているブランチにチェックアウトする。
issueの操作
Github CLIのissue関連操作をまとめています
issueの作成
gh issue create /*以下出力*/ Creating issue in YaCpotato/project_manager ? Title カレンダーインポートモーダルの実装 ? Body <Received> ? What's next? [Use arrows to move, type to filter] Preview in browser > Submit CancelほぼPRのcreateコマンドと一緒
issueの一覧表示
gh issue list /*以下出力*/ Issues for ユーザー名/リポジトリ名 #16 ガントチャートのレイアウトをガ?... #15 イメージ画像をアップロードでき?... #14 カレンダーインポートモーダルの?... #13 共有カレンダーテンプレートの実装 #12 ログイン済みGoogleアカウントから?...こちらは特にPRのような種類わけはない模様
issueのステータス表示
gh issue status /*以下出力*/ Relevant issues in ユーザー名/リポジトリ名 Issues assigned to you #15 イメージ画像をアップロードできるようにする about 40 minutes ago Issues mentioning you #16 ガントチャートのレイアウトをガチる about 41 minutes ago Issues opened by you #15 イメージ画像をアップロードできるようにする about 40 minutes ago #16 ガントチャートのレイアウトをガチる about 41 minutes ago #14 カレンダーインポートモーダルの実装 about 53 minutes ago #13 共有カレンダーテンプレートの実装 about 57 minutes ago #12 ログイン済みGoogleアカウントからのカレンダー取得 about 59 minutes ago
- アサインされているissue
- メンションされているissue
- 自分が開いたissue の3種類に分かれてリスト表示されます。
issueのページをブラウザで開く
gh issue view [issue番号]PR版とほぼ同じ。対象issueをブラウザで開く
最後に
個人的に便利!と思った点は
gh pr checkout
でPRが出されているブランチにチェックアウトできること
PRページからブランチ名コピーしてチェックアウトするのめんどくさいので
gh pr statusもしくは list
からのgh pr view PR番号
上記とPRのレビュー時にすぐにブラウザに飛べる当方Github用のCLIは初めてだったので既存のものと比較ができなくて残念です。この記事がどなたかの比較の際の参考になれば幸いです。
終わります。
よかったらTwitterフォローしてください