- 投稿日:2019-02-18T22:41:06+09:00
Rails Herokuにpushで詰まった話
git push heroku masterで詰まった
今回は,Herokuにアップロードしようとした所で詰まったので記録しておきます。
$ git push heroku master ・ ・ ・ remote: ! Push rejected, failed to compile Ruby app. remote: remote: ! Push failed remote: Verifying deploy... remote: remote: ! Push rejected to tranquil-wave-48446. remote: To https://git.heroku.com/tranquil-wave-48446.git ! [remote rejected] master -> master (pre-receive hook declined) error: failed to push some refs to・・・以下略remote: -----> Ruby app detected remote: remote: ! remote: ! You must use Bundler 2 or greater with this lockfile. remote: !実行した所複数のエラーが発生し、何が原因化を模索・・・
pgの指定がおかしいのか、gemfile.lock、bundlerのバージョンが問題なのか調べても中々解決策が見つからない、わからない
bundler バージョンが問題?
自分の環境とHeroku上の環境でbundlerのバージョンが異なることによるエラーが原因(?)の様でした。
https://github.com/bundler/bundler/issues/6784
以上の記事を参考にさせていただきました。
$ heroku buildpacks:set https://github.com/bundler/heroku-buildpack-bundler2を実行の後、再びHerokuへPushした所無事にアップロードができました!!!
感想
問題解決後にエラーを再検索してみると、同じ様なエラーになった人の記事がチラホラとありました。
もっと早い段階で気がつくことはできなかったのだろうか?
調べ方に改善の余地があるのかもしれない
- 投稿日:2019-02-18T22:39:33+09:00
Gitでコンフリクトを発生させて、解消してみた。
環境
・Git version 2.20.1.windows.1
お題
今回はGitで発生しうるコンフリクト(競合)がどんなものか体験する。
まずは作業前にコンフリクトについてお勉強。目次
1.競合って?
2.Gitにおけるコンフリクト(競合)とは?
3.ファイルの新規作成
4.リポジトリの初期化
5.TEST.txtを作成してcommitする。
6.トピックブランチAとBを作成する
7.トピックブランチAのTEST.txtを修正してコミットする。
8.トピックブランチBのTEST.txtを修正してコミットする。
9.コンフリクトを発生させて、解消する。1.競合って?
そもそも競合ってなんだ。
と思ったわけではないが一応検索した。
結果、「互いにせりあうこと。」らしい。('ω')2.Gitにおけるコンフリクト(競合)とは?
Gitにおける競合をコンフリクトと呼ぶらしい。
例えばmasterブランチにTEST.txtなるファイルを保持していたとする。
そのmasterブランチから、同じタイミングでトピックブランチAとBに派生させたときに
それぞれトピックブランチAではTEST.txtをtest1 test2とする。
さて、トピックブランチBは
test3 test4といった修正を加えたとする。
それぞれをmasterブランチにA、Bの順番でマージしようとする。
すると、Bをマージした時点で、コンフリクトが発生する。同じ時点で別れたブランチで、別々の内容を持つTEST.txtファイルが
存在することになるので、正常にマージできず衝突してしまうようだ。実際にmasterブランチでトピックブランチAとBをマージしようとすると、masterブランチのTEST.txtに競合を示す記述が記載される。
修正するには、作業者が内容に合わせてファイルを修正して、ステージ、コミットすれば良いことになる。今回は一連の動作を実践してみることにした。
3.ファイルの新規作成
$ mkdir git-conflict $ cd git-conflict/4.リポジトリの初期化
$ git init Initialized empty Git repository in C:/Users/local-pc/documents/work/git-conflict/.git/5.TEST.txtを作成してcommitする。
$ touch TEST.txt $ ls TEST.txt $ git add TEST.txt $ git commit -m "first commit" [master (root-commit) 8c1f140] first commit 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 TEST.txt $ git status On branch master nothing to commit, working tree clean6.トピックブランチAとBを作成する
$ git branch topicA $ git branch topicB $ git branch * master topicA topicB7.トピックブランチAのTEST.txtを修正してコミットする。
$ git checkout topicA Switched to branch 'topicA'(自分用に備忘:vimのペーストはInsertモードにしてからCTL + Insert、保存して終了はwq。)
$ git add TEST.txt warning: LF will be replaced by CRLF in TEST.txt. The file will have its original line endings in your working directory $ git commit -m "topicA" [topicA d35d541] topicA 1 file changed, 2 insertions(+)8.トピックブランチBのTEST.txtを修正してコミットする。
5と全く同じなので省略。
masterブランチをチェックアウトしておく。$ git checkout master Switched to branch 'master'9.コンフリクトを発生させて、解消する。
まずはトピックブランチAをマージしてみる。
$ git merge --no-ff topicA hint: Waiting for your editor to close the file... [main 2019-02-18T13:20:51.237Z] update#setState idle Merge made by the 'recursive' strategy. TEST.txt | 2 ++ 1 file changed, 2 insertions(+)catでTEXT.txtの中身を除くと…
$ cat TEST.txt test1 test2うんうん。ちゃんと入ってる。
では今回の本題。
トピックブランチBをマージしてみる。$ git merge --no-ff topicB Auto-merging TEST.txt CONFLICT (content): Merge conflict in TEST.txt Automatic merge failed; fix conflicts and then commit the result.無事(?)コンフリクト発生。
中身をのぞいてみる。
$ cat TEST.txt <<<<<<< HEAD test1 test2 ======= test3 test4 >>>>>>> topicBこんな感じにGitが気を利かせて書き換えをしてくれている。
=======よりも上の行が現在のTEST.txtの内容で、つまりトピックブランチAの内容をマージした状態。
=======よりも下がトピックブランチBの内容を表している。
たぶん、このままaddしてcommitもできるんだろうけど、きちんと修正しとく。
修正した内容をcatする。$ cat TEST.txt test1 test2 test3 test4これをadd、commitできれば、masterブランチで発生したコンフリクトを解消できたことになる。
$ git add TEST.txt $ git commit -m "conflict clear!" [master 653eba8] conflict clear!ログをグラフでみるとこんな感じ。
うん。わかりにくい(´・ω・`)$ git log --graph * commit 653eba813bfd6d0181463f769b6872c4bfbd6edf (HEAD -> master) |\ Merge: 0d5193d 41afa16 | | Author: 僕の名前 <僕アドレス> | | Date: Mon Feb 18 22:28:32 2019 +0900 | | | | conflict clear! | | | * commit 41afa1692ddd5e251b816e2e2420f4f51bc80921 (topicB) | | Author: 僕の名前 <僕アドレス> | | Date: Mon Feb 18 22:19:13 2019 +0900 | | | | topicB | | * | commit 0d5193df3dfea53967673fe13477ffc541ce7645 |\ \ Merge: 8c1f140 d35d541 | |/ Author: 僕の名前 <僕アドレス> |/| Date: Mon Feb 18 22:20:50 2019 +0900 | | | | Merge branch 'topicA' | | | * commit d35d541744457ed7b7f0f4df173b67db936e26f3 (topicA) |/ Author: 僕の名前 <僕アドレス> | Date: Mon Feb 18 22:17:03 2019 +0900 | | topicA | * commit 8c1f140cd4a3622ee1066f83b0900741eca35263 Author: 僕の名前 <僕アドレス> Date: Mon Feb 18 22:09:43 2019 +0900 first commit (END)無事コンフリクトを解消できました。
慣れてしまえば以外と簡単ね。今日はここまで!
明日はここで作ったファイルをGitHubのリモートリポジトリにpushしてみます。こっからはJunitのお勉強だ(:3 」∠)
- 投稿日:2019-02-18T22:32:45+09:00
ローカル修正済みのファイルがリモートでフォルダ構成を移動されていた場合に対象ファイルを抽出する
ローカル修正済みの(pushしていない)ファイルがリモートでフォルダ構成を移動されていた場合に、ローカルの対象ファイルを抽出するコマンド
そんなことある??????と思われるかもしれないが、あった。
フォルダ構成を(
git mv
あるいはfilter-branch
を使わずに)変更した場合はファイルが削除&追加されてしまう。そのままマージすると、同じファイルが(別の履歴・内容を持った状態で)2つ存在することになるはずである。従って、ローカルのコミットに含まれる当該ファイルを排除した状態でマージを実行したい。
普通にdiff --name-status
を取るとリモートで移動したファイルがすべて(DおよびAで)表示されてしまう。今回は変更ファイルが数百程存在したため諦めた。欲しいものは、ローカルの変更ファイルとリモートの移動済みファイルの集合である。
順序はどちらでも良いが、今回はローカル側の変更ファイルの方が少なかったため「ローカルの変更ファイルのうち、移動済みだったものを探す」方向で考えた。bash$ git diff HEAD~..HEAD --name-only | xargs -n1 -I{} git diff --name-status --diff-filter=A origin/develop..HEAD {}
git diff <SHA1>..<SHA1> --name-only
の標準出力をxargs
コマンドによるパイプで繋いでorigin/develop
とのdiffに渡している。フィルダ構成が変わっている=gitは新ファイルとして認識しているので--diff-filter=A
で抽出している。diff
の--name-status
はdiff-filterと効果が被るが、分かり易さ優先で付けた。更にパイプで繋ぐ場合は--name-only
にすると良いと思う。出力A some/file/path/and/file_name.cpp A some/file/path/and/file_name.h ...以下差分ファイル一覧今回は結局、ローカルのコミットが1つだけであり、さらに対象のファイルは2つだけだったため、一旦
reset --soft HEAD~
してからgit reset */file_name.*
してコミットした。その後にマージしたりなんやかんやして、ローカルの変更をコピペで反映して事なきを得た。
- 投稿日:2019-02-18T20:12:45+09:00
[輪読] Pro Git 7.1章
背景
- 弊ラボでは輪読と称して、技術書をまとめて発表する機会があるのですが、最近下書きでMarkdownで書き始めたこともあり、折角なのでQiitaにも投稿しておこうという所存です。
- ラボでの公開が目的+Pukiwiki投稿のためインラインとかに関しては葛藤があり、あったりなかったりです...
- 今回はProGitを読んでます。と言ってもProGitの内容は公式ページに日本語でも公開されており、内容もまとまっているので価値としては薄いかもしれません...
- 意外と量がある+それぞれの関連性は薄いので細かく公開していこうかと
7. Git のさまざまなツール
本章
- Gitの強力な機能を見ていく
- 日々使うというよりは、知っておくと役立つこと
7.1 リビジョンの選択
- 特定のリビジョンやコミットを参考にする方法はいくつかある
単一のリビジョン
- ハッシュの指定で特定のコミットを参照にすることができる
- 例えば、git logでcommitのハッシュ値を確認できる
❯ git log commit ae621679a236564cf937256e4b275cba90399ac6 (HEAD -> master) Author: pika1675@yahoo.co.jp <pika1675@yahoo.co.jp> Date: Fri Feb 15 18:30:41 2019 +0900 change_to_helloworld commit a8f67e8be00fb1043b7f03cdfb0fbb3107aad28e Author: pika1675@yahoo.co.jp <pika1675@yahoo.co.jp> Date: Fri Feb 15 18:29:36 2019 +0900 add_hello.py commit 9c32e945a41bdef37b37ddaf5e476c251e9f33fc (origin/master, origin/HEAD) Author: Pika <32129921+pikasigu@users.noreply.github.com> Date: Fri Feb 15 18:25:39 2019 +0900 Initial commit
- 特定のコミットを指定するにはコミットのハッシュ値を参考にすれば良い
- ハッシュ値も全てではなく、4文字以上であれば特定は可能(一意であることはもちろん必要)
❯ git show 9c32e945a41bdef37b37ddaf5e476c251e9f33fc commit 9c32e945a41bdef37b37ddaf5e476c251e9f33fc (origin/master, origin/HEAD) Author: Pika <32129921+pikasigu@users.noreply.github.com> Date: Fri Feb 15 18:25:39 2019 +0900 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..21201ff --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# ProGitTest +Test repository for reading Pro Git ❯ git show 9c32 commit 9c32e945a41bdef37b37ddaf5e476c251e9f33fc (origin/master, origin/HEAD) Author: Pika <32129921+pikasigu@users.noreply.github.com> Date: Fri Feb 15 18:25:39 2019 +0900 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..21201ff --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# ProGitTest +Test repository for reading Pro Git
- git log に -abbrev-commit のオプションで一意に特定できる省略形で出力が可能
- デフォルトは7文字だが、特定できない場合は長くなる
❯ git log --abbrev-commit --pretty=oneline ae62167 (HEAD -> master) change_to_helloworld a8f67e8 add_hello.py 9c32e94 (origin/master, origin/HEAD) Initial commit
- 今回の場合はcommitが少ないのでデフォルトの7文字
- まぁ、基本的にハッシュ値は被らないものとして考えても良い
ブランチの参照
- 直感的にコミットを参照にしたい場合はコミットレベルというよりも、ブランチレベルの可能性もある
- ブランチを参照することも可能
- ブランチを指定するとブランチの最新のコミットが参照される
- 適当にブランチを切って
❯ git checkout -b add_wiki_md_file Switched to a new branch 'add_wiki_md_file'
- 適当にコミットしてマージ
❯ git log commit d2b51048ff55ba7faff617620fb5372a4ec193a5 (HEAD -> master, add_wiki_md_file) Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:08:32 2019 +0900 wip_input_7.1 commit 129e7654eb17c61643c31257ad173185d5c059f9 Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:02:37 2019 +0900 create_md_file
- ブランチを参照するのと、最新のコミットは同じ参照というのが確認できる
❯ git show d2b5104 commit d2b51048ff55ba7faff617620fb5372a4ec193a5 (HEAD -> master, add_wiki_md_file) Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:08:32 2019 +0900 wip_input_7.1 diff --git a/wiki_reading.md b/wiki_reading.md index e69de29..b227885 100644 --- a/wiki_reading.md +++ b/wiki_reading.md ❯ git show add_wiki_md_file commit d2b51048ff55ba7faff617620fb5372a4ec193a5 (HEAD -> master, add_wiki_md_file) Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:08:32 2019 +0900 wip_input_7.1 diff --git a/wiki_reading.md b/wiki_reading.md index e69de29..b227885 100644 --- a/wiki_reading.md +++ b/wiki_reading.md
- ブランチの指しているハッシュを探すには
$git rev-parse
❯ git rev-parse add_wiki_md_file d2b51048ff55ba7faff617620fb5372a4ec193a5
- ブランチの最新のコミットを指しているのが確認できる
参照ログ(reflog)
- Gitが裏でやっていることの1つ
- HEADとブランチの参照がどう動いたかのログ
$git reflog
で実行❯ git reflog d2b5104 (HEAD -> master, add_wiki_md_file) HEAD@{0}: merge add_wiki_md_file: Fast-forward ae62167 HEAD@{1}: checkout: moving from add_wiki_md_file to master d2b5104 (HEAD -> master, add_wiki_md_file) HEAD@{2}: commit: wip_input_7.1 129e765 HEAD@{3}: commit: create_md_file ae62167 HEAD@{4}: checkout: moving from master to add_wiki_md_file ae62167 HEAD@{5}: commit: change_to_helloworld a8f67e8 HEAD@{6}: commit: add_hello.py 9c32e94 (origin/master, origin/HEAD) HEAD@{7}: clone: from https://github.com/pikasigu/ProGitTest.git
- ブランチの先端(HEAD)更新のたびに情報が格納されている
- このログから過去のコミットを指定することもできる
HEAD@{n}
で参照❯ git show 129e765 commit 129e7654eb17c61643c31257ad173185d5c059f9 Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:02:37 2019 +0900 create_md_file diff --git a/wiki_reading.md b/wiki_reading.md new file mode 100644 index 0000000..e69de29 ❯ git show HEAD@{3} commit 129e7654eb17c61643c31257ad173185d5c059f9 Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:02:37 2019 +0900 create_md_file diff --git a/wiki_reading.md b/wiki_reading.md new file mode 100644 index 0000000..e69de29
- HEADの番号以外にも期間で遡った時のブランチの指定も確認できる
❯ git show master@{yesterday} warning: Log for 'master' only goes back to Fri, 15 Feb 2019 18:25:57 +0900. commit 9c32e945a41bdef37b37ddaf5e476c251e9f33fc (origin/master, origin/HEAD) Author: Pika <32129921+pikasigu@users.noreply.github.com> Date: Fri Feb 15 18:25:39 2019 +0900 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..21201ff --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# ProGitTest +Test repository for reading Pro Git
- このリポジトリ作成当日に前日のリポジトリを呼んだので、warningが出ている
- 期間的に最も古いGitHubのinitの部分が呼ばれている
- 参照ログが残っている期間は直近数ヶ月であり、それ以前のコミットに関しては使えない
$git log -g
でgit log
っぽく出力できる❯ git log -g master commit d2b51048ff55ba7faff617620fb5372a4ec193a5 (HEAD -> master, add_wiki_md_file) Reflog: master@{0} (飯尾直樹 <pika1675@yahoo.co.jp>) Reflog message: merge add_wiki_md_file: Fast-forward Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:08:32 2019 +0900 wip_input_7.1 commit ae621679a236564cf937256e4b275cba90399ac6 Reflog: master@{1} (pika1675@yahoo.co.jp <pika1675@yahoo.co.jp>) Reflog message: commit: change_to_helloworld Author: pika1675@yahoo.co.jp <pika1675@yahoo.co.jp> Date: Fri Feb 15 18:30:41 2019 +0900 change_to_helloworld commit a8f67e8be00fb1043b7f03cdfb0fbb3107aad28e Reflog: master@{2} (pika1675@yahoo.co.jp <pika1675@yahoo.co.jp>) Reflog message: commit: add_hello.py Author: pika1675@yahoo.co.jp <pika1675@yahoo.co.jp> Date: Fri Feb 15 18:29:36 2019 +0900 add_hello.py commit 9c32e945a41bdef37b37ddaf5e476c251e9f33fc (origin/master, origin/HEAD) Reflog: master@{3} (pika1675@yahoo.co.jp <pika1675@yahoo.co.jp>) Reflog message: clone: from https://github.com/pikasigu/ProGitTest.git Author: Pika <32129921+pikasigu@users.noreply.github.com> Date: Fri Feb 15 18:25:39 2019 +0900 Initial commit
- git logと比べるとreflogのデータも出力されている
- あくまでmasterのログであるので、別ブランチのコミットは見ていない
❯ git log -g add_wiki_md_file commit d2b51048ff55ba7faff617620fb5372a4ec193a5 (HEAD -> master, add_wiki_md_file) Reflog: add_wiki_md_file@{0} (飯尾直樹 <pika1675@yahoo.co.jp>) Reflog message: commit: wip_input_7.1 Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:08:32 2019 +0900 wip_input_7.1 commit 129e7654eb17c61643c31257ad173185d5c059f9 Reflog: add_wiki_md_file@{1} (飯尾直樹 <pika1675@yahoo.co.jp>) Reflog message: commit: create_md_file Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:02:37 2019 +0900 create_md_file commit ae621679a236564cf937256e4b275cba90399ac6 Reflog: add_wiki_md_file@{2} (飯尾直樹 <pika1675@yahoo.co.jp>) Reflog message: branch: Created from HEAD Author: pika1675@yahoo.co.jp <pika1675@yahoo.co.jp> Date: Fri Feb 15 18:30:41 2019 +0900 change_to_helloworld
- ブランチも見るとわかりやすい
- 参照ログは完全にローカルなログ
- クローンした時の参照ログは空
- 試しにそれなりに色々しているリポジトリ(卒論の手書きのやつ)をクローンしてみる
❯ git clone https://github.com/pikasigu/Tegaki.git Cloning into 'Tegaki'... remote: Enumerating objects: 157, done. remote: Total 157 (delta 0), reused 0 (delta 0), pack-reused 157 Receiving objects: 100% (157/157), 5.41 MiB | 3.32 MiB/s, done. Resolving deltas: 100% (93/93), done. ❯ git log -g master commit cb5245e21feec1b70df373c2bd8e95a8a9a99ab1 (HEAD -> master, origin/master, origin/HEAD) Reflog: master@{0} (飯尾直樹 <pika1675@yahoo.co.jp>) Reflog message: clone: from https://github.com/pikasigu/Tegaki.git Author: Pika <32129921+pikasigu@users.noreply.github.com> Date: Tue Nov 20 18:12:25 2018 +0900 Create Readme
- 最新のコミットだけになっている
家系の参照
- コミットの特定に使われやすいのは家系から辿っていく方法
- 参照の最後に~をつけることで、それをコミットの親とする
❯ git log --pretty=format:'%h %s' --graph * d2b5104 wip_input_7.1 * 129e765 create_md_file * ae62167 change_to_helloworld * a8f67e8 add_hello.py * 9c32e94 Initial commit
- fast-forwardだったので分岐感がないですね...
❯ git show HEAD~ commit 129e7654eb17c61643c31257ad173185d5c059f9 Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:02:37 2019 +0900 create_md_file diff --git a/wiki_reading.md b/wiki_reading.md new file mode 100644 index 0000000..e69de29
- 折角なので卒論の方のgit logも
❯ git log --pretty=format:'%h %s' --graph * cb5245e Create Readme * dbabd26 OC opt dic * 33b3e93 Merge branch 'change_DB_alg' |\ | * 0fc3006 optimize sp | * c1f2728 optimize server | * 87b4cd7 del_log | * dfbc600 fix some |/ * d6d839e bug fix * 4245f39 Merge branch 'add_DB_GUI' |\ | * 8de62f6 delete log * | 01e4ed1 Merge branch 'add_DB_GUI' |\ \ | |/ | * 97830b1 post_DB deleteFLG | * 7670643 add_getDB |/ * 056d854 Merge branch 'new-branch-name' |\ | * e6abcef ver1.0 | * 97ece8d 評価実験直前修正 | * 8c00897 add particle & pos | * 98415f5 textarea + copy | * b0aa0fc 辞書追加修正 | * 74969a7 改造前ver | * dda674b 辞書機能完成(β) | * 7f0f6ef 不安定ver |/ * ddf78cc parsererror * 36a9602 php+sqlを追加 * 0ffe1f8 no message * 150a626 基本動作初期
- 管理が汚くてあれですが...
- 8de62f6 delete logのコミットの親を見てみると
❯ git show 8de62f6~ commit 97830b1a25ccb6752478fe5795e1887646ea8f3d Author: naoki <pika1675@yahoo.co.jp> Date: Tue May 15 03:24:12 2018 +0900 post_DB deleteFLG diff --git a/DB-index.html b/DB-index.html index 109af79..299485d 100644 --- a/DB-index.html +++ b/DB-index.html
- 時間的に直前の01e4ed1ではなくて、ちゃんと親の97830b1を見ていますね
- ちなみに~~や~2の様に書くことで親の親の様な参照もできます
- ^でも少し違った親の参照の仕方で同様の参照をするようですが、自分の環境で動作しなかったので今回は省略します
コミットの時範囲指定
- ここのコミットの指定ではなく、コミットの範囲指定を考える
使うイメージはメインのブランチにマージしていないのはどのブランチだっけという状態の時
上の図で言うとmasterブランチとexperimentブランチでブランチが切られています
masterブランチからみるとexperimentブランチにコミットされたC,Dブランチは見えません
そういうコミットをたどるにはmaster..experimentのように支持することでコミットを参照することができます
構文としては(あるブランチから見た)..(あるブランチの辿れない範囲)みたいな感じです
$git log master..experiment D C
逆にすればA,Bが出力されます
つまり、masterからこれらのようにブランチを指定することでmasterにマージされていないコミットを知ることができるというわけですね
もう1つの使い方として、origin/master..HEADのように見ることでこれからpushするコミットを確認するという使い方もあります
❯ git log origin/master..HEAD commit d2b51048ff55ba7faff617620fb5372a4ec193a5 (HEAD -> master, add_wiki_md_file) Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:08:32 2019 +0900 wip_input_7.1 commit 129e7654eb17c61643c31257ad173185d5c059f9 Author: 飯尾直樹 <pika1675@yahoo.co.jp> Date: Fri Feb 15 19:02:37 2019 +0900 create_md_file commit ae621679a236564cf937256e4b275cba90399ac6 Author: pika1675@yahoo.co.jp <pika1675@yahoo.co.jp> Date: Fri Feb 15 18:30:41 2019 +0900 change_to_helloworld commit a8f67e8be00fb1043b7f03cdfb0fbb3107aad28e Author: pika1675@yahoo.co.jp <pika1675@yahoo.co.jp> Date: Fri Feb 15 18:29:36 2019 +0900 add_hello.py
- pushしていないclone後のコミットが出力されています
- このダブルドット構文は片方を省略することが可能で、省略した場合はそこがHEADとして考えられます
- ダブルドット構文以外にも同様の意味を持つ表現は可能です
$ git log refA..refB $ git log ^refA refB $ git log refB --not refA
- ダブルドットはできませんが、他の表現だと3つ以上の参照を考えられます
$ git log refA refB ^refC $ git log refA refB --not refC
- 2つは同じ意味で、A,Bからは辿れるけれど、Cからは辿れないコミットを参照します
- トリプルドット構文も実はあり、トリプルドットは片方どちらかにのみ辿れるコミットを参照します
$ git log master...experiment F E D C
- A,Bはどちらのブランチからでも参照できるので、含まれません
- このlog出力には--left-rightオプションをつけることで、どちらのブランチに含まれるコミットかを表示してくれます
$ git log --left-right master...experiment < F < E > D > Cまとめ
- ブランチ参照はハッシュ参照くらいしか知らなかったですね
範囲指定とか使い所はありそうですが、実際的確に使えるかというと難しそうです...
- 投稿日:2019-02-18T20:02:04+09:00
git diffの全オプション一覧
GitのサイトにはPro Git 2nd ed. Editionという本が全文無償公開されていて、日本語訳も公開されています。
なのでGitの使い方についてはこの本を読めば概ね事足ります。
ちなみに最新版はGitHubにあります。それはいいのですが、なにげに意外なことにリファレンスは日本語訳が、というか英語以外の言語がないみたいです。
以下は、諸事情で
git diff --break-rewrites
について知りたかったのだけど日本語解説が一件たりとも存在しなかったので調べたついでに全オプションについて軽く調べてみたメモです。
マニュアルのバージョンは2.20.0。git diff
SYNOPSIS
書式。
基本的にgit diff
、オプション、対象コミット、--
、対象ファイル名の順に書く。git diff [<options>] [<commit>] [--] [<path>…] git diff [<options>] --cached [<commit>] [--] [<path>…] git diff [<options>] <commit> <commit> [--] [<path>…] git diff [<options>] <blob> <blob> git diff [<options>] --no-index [--] <path> <path>DESCRIPTION
git diff [<options>] [--] [<path>…]
最新インデックスから現在までの差分を表示する。
addするとインデックスが更新されるので出てこなくなる。
git diff [<options>] --no-index [--] <path> <path>
Git管理外のファイルも
--no-index
を付ければ対象にできる。
付けなければGit管理下にあるファイルのみが対象となる。
git diff [<options>] --cached [<commit>] [--] [<path>…]
最新コミットから最新インデックスまでの差分を表示する。
要するに最後のaddまでの差分。addした後の変更は出てこない。
--staged
も同じ。
git diff [<options>] <commit> [--] [<path>…]
現在のブランチ(HEAD)と指定のコミットとの差分を比較する。
git diff [<options>] <commit> <commit> [--] [<path>…]
指定のふたつのコミットの差分を比較する。
片方を省略するとHEADを指定したものとなる(上と同じ)。
git diff [<options>] <commit>..<commit> [--] [<path>…]
スペース区切りと同じ。
片方省略もできる。
git diff [<options>] <commit>...<commit> [--] [<path>…]
指定のふたつのコミットについて、共通の祖先まで遡ってそこから後者への差分を比較する。
言葉だとわかりにくいが、画像を見れば一発だろう。
画像はWhat are the differences between double-dot ".." and triple-dot "..." in Git diff commit ranges?より拝借。
git diff [<options>] <blob> <blob>
コミットではなくBLOBオブジェクト同士の差分を比較する。
オプション一覧
-p
-u
--patch
パッチを作成する。デフォルトの動作。
-s
--no-patch
差分を標準出力に出さないようにする。
git show
などと一緒に使うとよいが、git diff
に使うと何も出ない。-U<n>
--unified=<n>
変更された行の前後に出力する、変更されていない行の行数を変更する。
デフォルト3。
0にすると変更された行しか出さない。--raw
diffをRawフォーマットで出力する。
RawフォーマットはGitの内部形式らしい。--patch-with-raw
-p --raw
と同じ。
なのだが、-p --raw
より長い。--indent-heuristic
意図しているだろう感じで差分がうまく出るよう判定を改善する。
デフォルトでオン。--no-indent-heuristic
--indent-heuristic
を使わない。--minimal
できるだけ差分が少なくなるように比較する。
そのぶん処理に時間がかかる。--patience
patience diffアルゴリズムを使って差分を生成する。
--histogram
histogram diffアルゴリズムを使って差分を生成する。
--anchored=<text>
anchored diffアルゴリズムを使って差分を生成する。
ということらしいのだが結果を見てもよくわからない。--diff-algorithm={patience|minimal|histogram|myers}
任意のアルゴリズムを使って差分を生成する。
値を指定しない場合はmyers
が使われる。
値を--diff-algorithm=default
とすると、設定ファイルに書かれているdiff.algorithm
が使われる。--stat[=<width>[,<name-width>[,<count>]]]
diffstat形式で出力する。diffstatは↓のような形式。
path/to/hoge,html | 5000 +++-- path/to/fuga,html | 1234 -------カンマ区切りで3つまで指定可能な引数で出力範囲を指定できる。
第1引数widthは全体の横幅。
第2引数name-widthはそのうちファイル名部分の横幅。
第3引数countは行数。指定行数を超えるとそれ以降は省略される。--stat-width=<width>
--stat-name-width=<name-width>
--stat-count=<count>
↑の
--stat
をそれぞれ個別に設定する。--compact-summary
diffstat形式に、ファイル作成・削除などのサマリを追加表示する。
new、gone、+l
(シンボリックリンク)、+x
(実行権限追加)など。
表示内容はstatのファイル名とグラフの間に出力される。--numstat
statと似ているがより省力で、追加行数、削除行数、ファイルパスだけを出力する。
100 50 path/to/hoge,html--shortstat
statの最後の行、変更されたファイル数、追加行数、削除行数の合計だけを出力する。
999 files changed, 765 insertions(+), 573 deletions(-)--dirstat[=<param1,param2,…>]
ファイルの差分がどのディレクトリに多いかをパーセンテージで表示する。
ディレクトリ内のファイルが変更された割合ではない。パラメータをカンマ区切りで追加することで動作を変更できる。例:
git diff --dirstat=files,10,cumulative
changes
はコードの移動はカウントせず、追加削除された行のみを計算する。
lines
は行数でカウントする。通常のカウント。
files
は変更されたファイル数をカウントする。中身は見ない。
cumulative
はサブディレクトリも集計に入れる。合計は100%を超える。
数値は足切り。それ以下のディレクトリは親にまとめられる。--summary
ファイル追加削除、権限変更など拡張ヘッダ情報のみを表示する。
--patch-with-stat
-p --stat
と同じ。
-p --stat
より長い。-z
--name-only
や--numstat
などと一緒に使うと、区切りが改行ではなくNULになる。
--stat
などには効かない。--name-only
変更されたファイル名のみを表示する。
--name-status
変更されたファイル名とステータスを表示する。
--submodule[=<format>]
サブモジュールのdiffの表示形式を指定する。
short
はサブモジュール内のcommitは最初と最後しか表示しない。
log
はサブモジュール内のcommitを全て一覧表示する。
diff
は普通にdiffを表示する。--color[=<when>]
カラー表示をどうするか指定する。
デフォルト設定はcolor.ui
およびcolor.diff
で変更できる。
always
はdiffをカラー表示する。
never
は必ず白黒表示する。
auto
はよくわからない。--no-color
--color=never
と同じ。--color-moved[=<mode>]
移動したコードの色をどうするか指定する。
指定可能な値はno
、default
、zebra
、plain
、blocks
、dimmed-zebra
。--color-moved-ws=<modes>
--color-moved
を検出する際に空白を取り扱う方法を指定する。
デフォルト設定はdiff.colorMovedWS
で変更できる。
ignore-space-at-eol
は改行を無視する。
ignore-space-change
はスペースの量の変化を無視する。スペース数0→1や1→0は検出するが1→10などは無視。
ignore-all-space
はスペースの変化を完全に無視する。
allow-indentation-change
は、スペースの変化量が全て同じブロックをグループ化する。--word-diff[=<mode>]
行単位ではなくワード単位でdiffを表示する。
color
は色だけで表示する。コピペすると区切りがわからなくなる。
plain
は追加を{+ +}
で、削除を[- -]
で括って表示する。中のテキストをエスケープしないので、同じ文字が入っていると区切りがわからなくなる。
porcelain
は区切りを改行で表す。元々の改行は~で表す。正直わかりにくい。
none
は何もしない、未指定と同じ。--word-diff-regex=<regex>
ワード単位でdiffを表示する際のワードの区切りを正規表現で指定する。
--color-words[=<regex>]
--word-diff=color -word-diff-regex
と同じ。--no-renames
ファイル名を変更しただけのファイルは検出しない。
--check
スペースの次にタブ、および末尾スペースがあったときに警告メッセージを出す。
動作はcore.whitespace
で変更できる。--ws-error-highlight=<kind>
行末の空白をエラー表示するか否か。引数は,区切りで複数指定可能。
old
は変更前をエラーとして表示する。
new
は変更後をエラーとして表示する。
all
はold,new,context
に同じ。
表示色はcolor.diff.whitespace
で設定する。--full-index
commitハッシュを省略形ではなくフル表示する。
--binary
--full-index
に加え、git apply
で使えるバイナリのdiffも出力する。
と書いてあるのだが手元では--full-index
の効果はなかった。--abbrev[=<n>]
diff --raw
などに出力するハッシュの桁数を指定する。-B[<n>][/<m>]
--break-rewrites[=[<n>][/<m>]]
diffを書き換えではなく、削除と挿入のペアとして表す。
引数を-B/70%
とか-B100%/0%
のように渡すことで、ファイルが編集ではなく完全な書き換えと判断する基準を変更することができる。
となっているみたいなのだが正直よくわからなかった。-M[<n>]
--find-renames[=<n>]
リネームを検出する。
-M90%
とすると、中身の90%以上が同じファイルは削除+追加ではなく名前変更とみなす。
デフォルトは50%。-C[<n>]
--find-copies[=<n>]
コピーを検出する。
オプションの指定方法はリネームと同じ。
コピー元の候補になるのは、中身が変更されたファイルのみ。--find-copies-harder
--find-copies
と同じだが、全てのファイルをコピー元の候補として調べる。
そのためとても重い。-D
--irreversible-delete
削除されたファイルは差分を表示しない。
-l<num>
-M
および-C
を使用した際、この制限を超えたら処理を打ち切る。
理由としてはそれらの処理時間がO(n^2)
オーダーであるため。--diff-filter=[(A|C|D|M|R|T|U|X|B)…[*]]
diffの出力をフィルタリングする。
A
は追加されたファイルのみ、D
は削除されたファイルのみ、C
はコピーされたファイルのみ、R
はリネームされたファイルのみ、M
は変更されたファイルのみ。
TUXB
はサブモジュールなど。
複数のオプションを--diff-filter=ACDM
のように指定可能。
*
を入れると、該当の差分がないときは何も表示せず、該当の差分があれば全ての差分を表示する。小文字にすると逆になる。
--diff-filter=a
であれば追加された以外の変更があったファイルを全て検出する。-S<string>
差分で引数の文字の出現回数が変更されたファイルを検出する。
-f"hoge"
とすると、hoge
の出現回数が変わったファイルを差分出力する。
100行目でhoge
を追加し、200行目から削除したような場合は出力されない。-G<regex>
差分で引数の文字が出現したファイルを検出する。
文字列には正規表現を使用可能。
100行目でhoge
を追加し、200行目から削除した場合でも出力される。--find-object=<object-id>
指定のオブジェクトの出現回数が変更されたファイルを検出する。
使い方は-S
と同じ。--pickaxe-all
-S
と-G
において、ひとつでも変更が見つかったら全ファイルの差分を表示する。--pickaxe-regex
-S
において正規表現を使えるようになる。-O<orderfile>
diffの出力ファイルの順番を、引数のファイルの設定に変更する。
ファイルの書式はfnmatchで.gitignore
と同じ。
引っかかった上から順に表示するとなっているのだが、手元ではどうやっても順番が変わらなかった。-R
diff
の元ブランチと先ブランチを入れ替える。
つまりdiff AAAAAA BBBBBB
とdiff -R BBBBBB AAAAAA
は同じ。--relative[=<path>]
--relative
だけだと、サブディレクトリからdiffを実行した際にカレントディレクトリ以下のファイルしか見ない。
--relative="foo/bar/"
とすると、foo/bar/
ディレクトリでdiff --relative
を実行したかのような出力になる。
サブディレクトリから実行する場合でも、パスの指定はgitルートからの指定になる。-a
--text
全てのファイルをテキストファイルとみなして扱う。
--ignore-cr-at-eol
改行の前にあるCRを無視する。
--ignore-space-at-eol
改行の前にあるスペースを無視する。
-b
--ignore-space-change
スペースの個数だけの変更は無視する。
0から1になった、1から0になった場合は無視しない。
function
→func tion
は無視しない。-w
--ignore-all-space
0から1を含め、あらゆるスペースの変更を無視する。
function
→func tion
でも無視される。--ignore-blank-lines
空行のみの追加削除を無視する。
空行以外の変更があった場合は無視しない。--inter-hunk-context=<lines>
1ファイルに変更箇所が複数ある場合、デフォルトでは8行くらい離れているとdiff出力が別に分かれる。
この数値を大きくすると、離れた行もひとつの変更とみなす。-W
--function-context
変更があったファイルは全てを表示する。
--exit-code
差分があれば終了ステータス1、なければ終了ステータス0で終了する。
--quiet
標準出力しない。
--exit-code
を含む。--ext-diff
外部diffヘルパーを使用する。
ということらしいが実際はgit config
等で指定が必要なので、単に↓と揃えただけと思われる。--no-ext-diff
外部diffヘルパーを使用しない。
デフォルトで外部diffヘルパーを使っている場合にそれをキャンセルする。--textconv
--no-textconv
バイナリファイルのテキスト変換フィルタを指定している場合に、それを使って差分を表示する、もしくは使用しないでバイナリのまま比較する。
--ignore-submodules[=<when>]
サブモジュールへの変更をどうするか。
none
はサブモジュールの変更を全て取得する。
untracked
は、変更は追跡する、新規ファイルは追跡しない。
dirty
はサブモジュールで管理されているファイルは無視され、親プロジェクトで管理されているファイルは追跡する。
all
はサブモジュール内の変更は全て無視する。
デフォルトはall
。1.7.0まではdirty
。--src-prefix=<prefix>
変更元ファイルのプレフィックスを
a/
ではなく指定した値にする。--dst-prefix=<prefix>
変更後ファイルのプレフィックスを
b/
ではなく指定した値にする。--no-prefix
両方のファイルからプレフィックスを表示しない。
--line-prefix=<prefix>
出力の全行にこのプレフィックスを表示する。
--ita-invisible-in-index
--ita-visible-in-index
git add -N
で追加したファイルは、git diff
では登録済みの空ファイルとして、git diff --cached
では未登録のファイルとして表示される。
--ita-invisible-in-index
オプションを入れるとgit diff
では未登録の新規ファイルとして表示し、git diff --cached
では何も出てこない。
--ita-visible-in-index
は未指定と同じ。-1 --base
-2 --ours
-3 --theirs
merge
時のコンフリクトなど、3状態を比較する際に使用する。-o
マージされていないエントリについては出力を省略して、単に
Unmerged
とだけ出す。<path>…
パスを与えると、そのディレクトリ以下のファイルに対してのみdiffを実行する。
感想
なんだこりゃ。
何も考えず節操なく付け加えていった結果にしか見えない、
指定しても出力が変わらなくて何を意味するのか全くわからないオプションとかあって、少し整理したほうがいい気がする。
- 投稿日:2019-02-18T17:29:17+09:00
Gitのコミット数と行数を確認する
Gitで自分のコミット数を計測したいときありますよね。
そんなときに使ったコマンドを残しておきます。
私のGitのアカウントは、noracornなのでそこは読み替えてください。全体のコミット数を確認するコマンド
リポジトリ内に移動して打ってください。
git log --date=iso --pretty=format:"[%ad] %h %an : %s" | grep "noracorn :" | wc -l月ごとのコミットを見るコマンド
git log --date=iso --pretty=format:"[%ad] %h %an : %s" | grep "noracorn :" | grep 2019-01 | wc -l修正した行数を見るコマンド(合計行数、追加行数、削除行数)
git log --numstat --pretty="%H" --author='noracorn' --since=2013-01-11 --until=2019-01-01 --no-merges | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("%d (+%d, -%d)\n", plus+minus, plus, minus)}'
- 投稿日:2019-02-18T16:37:49+09:00
Gitで一つ前にチェックアウトしていたブランチに移動する`git checkout -`というコマンドに感動したお話
背景
最新のmasterを開発中のブランチに取り込んだり、他の人が開発中のブランチを取得する時、一度ブランチをチェックアウトしてすぐ元の作業ブランチに戻る、といった事をすることがあるかと思います。
私は今までgit checkout master
→git pull origin master
→git checkout my_branch
→git merge master
としていました。
そして、開発中のブランチ名ってなんだったっけ・・?えーと・・・あ、これこれ。となっていたのです。
git checkout -
一つ前のディレクトリに戻る
cd -
コマンドのように、一つ前にチェックアウトしていたブランチに移動するgit checkout -
というコマンドが存在することを10分前に初めて知りました。
上記のコマンドが以下のようになります。
git checkout master
→git pull origin master
→git checkout -
→git merge master
何が嬉しいのか
「開発中のブランチ名を確認する」という小さなタスクの存在がなくなりました。
こういう小さなワンアクションが消える事に喜びを感じるマンなので軽いパラダイムシフトですね。みなさんも
git checkout -
で良いGitライフを!
- 投稿日:2019-02-18T16:35:15+09:00
ポータブル環境でVSCodeからGitHubプライベートリポジトリを使う
ポータブル環境でVSCodeからGitHubプライベートリポジトリを使う
最終更新:2019年2月22日 Mac VMware上での動作状況を追記しました
このドキュメントは、ワクワクしながらVSCodeからGitHubのプライベートリポジトリを使おうとして、
とか、
の悪夢に悩まされている方向けです。それズバリ認証失敗です。
スマートな解決策が他にあるかもしれませんが、僕が色々試したところでは、どうしても/dev/tty問題が解決できず、VSCodeのパスフレーズ入力ダイアログを回避してssh-agentに認証を任せるしかありませんでした。ここではその手法を説明します。
構築に使用した環境
- Windows10 Version 1803
- Visual Studio Code 1.31.0 zip版
- (Portable)Git for Windows 2.20.1
- ポータブル環境ではないVSCodeとGitもインストールされている(がこちらは使わない)
- ポータブル環境は以下の様にVSCodeとPortableGitが展開されている
[jtHiuPortable] ├───[apps] │ └───[win] │ ├───[VSCode] │ ├───[PortableGit] │ └───Code.cmd ├───[files] └───VSCode_Win.lnk
- 自前で用意した2つのファイルのうち、
Code.cmd
は以下の様な内容で、VSCode_Win.lnk
はCode.cmd
へのトリックショートカットである1コマンドプロンプト> echo start %~dp0VSCode\Code.exe > Code.cmdここまでで「えぇっと…」と思った方は、このページではなくステップバイステップの方で進めてください。
確認済みの事項
- ○ Windows7での動作を確認しました。
- ○ ネットワークドライブ(情報大のZ:ドライブ)での動作を確認しました。
- ○ OneDrive上での動作を確認しました。
- × パス中に日本語フォルダ名を含むとダメです。
- × UNCパスもダメです。
- Windowsエクスプローラーのホーム→新規→ショートカット→「ドライブとしてマップ」からドライブレターを割り当ててください。
- × Mac上VMwareのvmware-host経由では、ドライブとしてマップでもダメでした。
- デバイスごとWindowsに接続している場合は大丈夫です。OneDriveもOK。ただし、なぜかVSCode起動用バッチのコマンドプロンプトが終了しませんので、気にしないのが吉です。
ポータブル環境用Gitの使用を明示する
デフォルトでは当然、マシンにインストールされているGitを使いに行こうとしますが、まずはこれをポータブル環境へ引き込むためにパスなどの環境変数を設定するバッチファイルを作成します。
コマンドプロンプトD:\jtHiuPortable> touch apps\win\setPath.cmdsetPath.cmd@echo off if Defined AppsWinRoot GoTo PostPathSettings echo Portable Console is preparing environment variables. set NOW_CD=%cd% cd /D %~dp0..\.. set HOME=%cd% cd /D %NOW_CD% set AppsWinRoot=%HOME%\apps\win set GitD=%AppsWinRoot%\PortableGit set PATH=%GitD%\cmd;%GitD%;%GitD%\usr\bin;%path% :PostPathSettings echo Portable home has located in %HOME% echo Portable applications have located in %AppsWinRoot%要点解説:
- 2行目 … 多重起動によるPATH登録の無限増殖を防いでいます。
- %~dp0 … 「動作中のスクリプトファイルがあるパス」です。
- 環境変数HOMEの設定 … sshなどMSYS2(MinGW64)なコマンドは環境変数HOMEをホームディレクトリとして使用します。環境変数に相対パスの部分を残したくなかったので、ちょっと面倒な手順を踏んで設定しています。
- PATHへの追加項目
%GitD%\cmd
… git起動用%GitD%
… git-bash起動用%GitD%\usr\bin
… MSYS2(MinGW64)各種コマンド向けこれを、きちんとポータブル環境で動作しているか確認するため、あえて標準のホームから叩いてみます。sshはもちろん接続にコケますが、ポータブル環境のホームに
.ssh
フォルダが自動的に作成されたことを確認してください。コマンドプロンプトMicrosoft Windows [Version 10.0.17134.590] (c) 2018 Microsoft Corporation. All rights reserved. C:\Users\MyName>D:\jtHiuPortable\apps\win\setPath.cmd Portable Console is preparing environment variables. Portable home has located in D:\jtHiuPortable Portable applications have located in D:\jtHiuPortable\apps\win C:\Users\MyName>git --version git version 2.20.1.windows.1 C:\Users\MyName>git-bash (git-bashのウィンドウが開く) C:\Users\Nyname>ssh -T git@github.com The authenticity of host 'github.com (192.30.255.113)' can't be established. RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8. Are you sure you want to continue connecting (yes/no)? (とりあえず空Enter) Host key verification failed.MINGW64:/c/Users/MyNameMyName@MyWin MINGW64 /c/Users/MyName $ ls ~ apps/ files/ VSCode_Win.lnkこれで、gitやsshが起動することと、git-bash上でホームディレクトリがきちんとポータブル環境のフォルダになっていることを確認できました。
apps\win
にあるVSCode起動用バッチファイルも、これを経由するようにします。Code.cmd@echo off call %~dp0setPath.cmd start %~dp0VSCode\Code.exeVSCodeのGit自動検索を回避する
VSCodeは起動時に、標準的なGit for Windowsのインストール場所を巡回して探してくるというポータブル環境にとっては大変余計なことをしてくれます。そんな訳で仕方なく
settings.json
のgit.path
にフルパス書くんですが汎用性が低い。なんで、これでいいです。てか、こう書いてください。settings.json{ "git.path": "git" }セキュリティリスクは判るけどこれをデフォルトにしてくれよ…とも思うんですが… こうするとパスの通ったGit環境を使ってくれます。もちろん既に色々設定している方は、この一行(と行末にコンマも付けて)追加してください。ちなみに
settings.json
はCtrl+Shift+P
でコマンドパレットを開いて、open settings (j
ぐらいまで打てば開けます。ポータブル環境向けのSSHキーを作成し登録する
既にSSHキーをお持ちの方も多いとは思いますが、ポータブルデバイス紛失のリスクを考えると、大事な秘密鍵を持ち歩きたくはありませんので、ポータブル用のキーペアを新たに作成する方が安心です。フォーマットはGitHubの流儀に従って作成します。メールアドレスは自分のものに変更します。
-f
オプションで保存先とキーペアの名前も指定します。コマンドプロンプト> ssh-keygen -t rsa -b 4096 -C "j-t@s.do-johodai.ac.jp" -f %HOME%\.ssh\rsa_GitHub_HIU Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): (パスフレーズ(パスワード)を入力する) Enter same passphrase again: (パスフレーズを再入力する) Your identification has been saved in D:\jtHiuPortable\.ssh\rsa_GitHub_HIU. Your public key has been saved in D:\jtHiuPortable\.ssh\rsa_GitHub_HIU.pub. The key fingerprint is: SHA256:~~~~~~ j-t@s.do-johodai.ac.jp The key's randomart image is: +---[RSA 4096]----+ | ステキなアート | +----[SHA256]-----+ > clip < %HOME%\.ssh\rsa_GitHub_HIU.pub最後の1行は、GitHubの流儀にもある、生成した公開鍵をクリップボードにコピーするためのものです。これに従って、自分の公開鍵を登録します。
GitHubの画面右上の自分のアイコンからsettings
を選び、
サイドバーのSSH and GPG Keys
を選択して、右上の方のNew SSH key
ボタンを押して、
Title
には、複数のキーを登録した時に自分で区別が付けられるような名前を入力し、Key
欄でCtrl+V
で貼り付けたら、Add SSH key
ボタンを押します。
パスワードを聞かれたら(鍵生成時に入力したパスフレーズではなく)GitHubアカウントのパスワードを入力してConfirm password
ボタンを押して完了です。
これでGitHubにSSH接続するためのキーを登録することが出来ました。2SSH・Gitの設定をする
GitHub向けのSSH接続設定を、ポータブル環境フォルダ直下に作成された
.ssh
の下にconfig
というファイルを作成して書きこみます。User
はgit
固定です、書き換えないように注意してください。IdentityFile
は作成したキーペアへのパスです。ここはUnixスタイルのパス表記になります。configHost github.com User git Hostname github.com IdentityFile ~/.ssh/rsa_GitHub_HIU IdentitiesOnly yes
次に、Gitでのコミットをサインオフするためのユーザ名とパスワードを設定します。もちろん自分のものに変更して入力してください。詐称はいやん。
コマンドプロンプト> git config --global user.name "TANAHASHI, Jiro" > git config --global user.email "j-t@s.do-johodai.ac.jp"エラーも何も表示されなければ成功です。ポータブル環境のホームに
.gitconfig
ファイルの作成が確認できます。それではアクセスチェックです。
コマンドプロンプト> ssh -T git@github.com The authenticity of host 'github.com (192.30.255.112)' can't be established. RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8. Are you sure you want to continue connecting (yes/no)? (Enterキーではなく、「yes」としっかり入力する) Warning: Permanently added 'github.com,192.30.255.112' (RSA) to the list of known hosts. Enter passphrase for key '/d/jtHiuPortable/.ssh/rsa_GitHub_HIU': Hi jtFuruhata-HIU! You've successfully authenticated, but GitHub does not provide shell access.みたいに、
You've successfully authenticated
って言われたら、ここまでの手順はOKです。known_hosts
も.ssh
に自動的に作成され、ここまでのフォルダ構造を確認すると以下の様な感じです。[jtHiuPortable] ├───[.ssh] │ ├───config │ ├───known_hosts │ ├───rsa_GitHub_HIU │ └───rsa_GitHub_HIU.pub ├───[apps] │ └───[win] │ ├───[VSCode] │ ├───[PortableGit] │ ├───Code.cmd │ └───setPath.cmd ├───[files] ├───.bash_history //もちろんこれはなくてもいい ├───.gitconfig └───VSCode_Win.lnkssh-agentを起動する
これでOKなはずなんですけどどうにもパスワードを聞いてくれない。そこで
ssh -v
とか色々とデバッグログを見ていると、きちんとポータブル環境のファイルは見に行ってるんだけど、パスフレーズの入力で/dev/tty
がねぇぞってことでコケる。もちろんコマンドで叩けばちゃんとcloneできる。ってなわけで、GCMとか色々物色して試したんですけどダメで、普通に(?)ssh-agentを使うことにしました。まず、
start-ssh-agent
を使うのですがバッチファイルから呼び出すとcmd
を起動してダンマリするので塩梅が悪いため、ファイルをコピーして、コマンドプロンプト> copy %GitD%\cmd\start-ssh-agent.cmd %AppsWinRoot%\summon-ssh-agent.cmd 1個のファイルをコピーしました。下から2行目の
cmd
起動部をREMっちゃいます。summon-ssh-agent.cmd~ 省略 ~ @IF NOT ERRORLEVEL 1 @( REM @CALL cmd %* )そして、パス設定のバッチファイル最後で召喚します。一応全掲。
setPath.cmd@echo off if Defined AppsWinRoot GoTo PostPathSettings echo Portable Console is preparing environment variables. set NOW_CD=%cd% cd /D %~dp0..\.. set HOME=%cd% cd /D %NOW_CD% set AppsWinRoot=%HOME%\apps\win set GitD=%AppsWinRoot%\PortableGit set PATH=%GitD%\cmd;%GitD%;%GitD%\usr\bin;%path% :PostPathSettings echo Portable home has located in %HOME% echo Portable applications have located in %AppsWinRoot% call %~dp0summon-ssh-agentVSCodeを黙らせることが目的ですので、VSCode起動バッチの方に使用するキーを追加します。ちょっとだけ多重起動対策してます。4行目の
ssh-add
以降は、.ssh
のconfig
のIdentityFile
に書いたものをコピペしてください。ハードコードは美しくないんですが、この辺は後々構築が進んだら環境変数を使うことにします。Code.cmd@echo off call %~dp0setPath.cmd ssh-add -l if ErrorLevel 1 ssh-add ~/.ssh/rsa_GitHub_HIU start %~dp0VSCode\Code.exeあとは、VSCodeをバッチ経由で起動しようとすると、ssh-agentがいない場合は召喚し、パスフレーズが入力されていなければそれを承認してからVSCodeが起動します。
バッチファイル動作中Portable Console is preparing environment variables. Portable home has located in D:\jtHiuPortable Portable applications have located in D:\jtHiuPortable\apps\win Removing old ssh-agent sockets Starting ssh-agent: done The agent has no identities. Enter passphrase for /d/jtHiuPortable/.ssh/rsa_GitHub_HIU: (パスフレーズを入力してEnterキー)ssh-agentを停止する
通常の使用であればVSCodeを開き直してもパスフレーズを再入力する必要がないので便利ですが、共有マシンなどでログインしっぱなしなのは問題がある場合も多いですし、何よりssh-agentの召喚中は「ハードウェアを安全に取り外してデバイスを取り出す」ができないので、召還するスクリプト
recall-ssh-agent.cmd
をapps\win
に用意して、ここに飛ぶトリックショートカットRecallAgent_Win.lnk
もポータブル環境フォルダに作成、必要に応じてダブルクリックして自動認証を終了させられるようにします。recall-ssh-agent.cmd@SETLOCAL EnableDelayedExpansion @FOR /f "tokens=1-2" %%a IN ('tasklist /fi "imagename eq ssh-agent.exe"') DO @( @ECHO %%b | @FINDSTR /r /c:"[0-9][0-9]*" > NUL @IF "!ERRORLEVEL!" == "0" @( @SET SSH_AGENT_PID=%%b %~dp0PortableGit\usr\bin\ssh-agent -k ) )要点解説:基本的には
start-ssh-agent.cmd
からPID取得部を持ってきています。
- 1行目 … 遅延展開の使用を宣言します。
- 2-3行目 … tasklistコマンドをforから用いて、起動中のssh-agentを検索し、PIDの部分を取得します。
- 4-6行目 … きちんと取得できたら、ssh-agentが参照する環境変数に代入し、さよならします。
オプション:VSCodeの英語モード起動をなんとかする
インストール直後はしょうがない。ただ、ポータブル環境デバイスを他のマシンで利用する時(恐らくドライブレターが変更された時)、初回のみ英語モードで起動してしまいます。
code.cmd --locale ja
でもダメです。恐らく、起動時に拡張機能(各国語対応も拡張機能)を遅延読み込みするため、環境が変わってElectronが混乱している間に日本語拡張が読み込まれないままワークベンチが表示されてしまうからでは、と推測していますが、初回時(パスフレーズを入力する時)には自動的にVSCodeを再起動するように変更したCode.cmd
を示します。気にならない方はウザいだけですので変更しなくて結構です。Code.cmd@REM WARNING: This Windows command script is tainted with BASH commands @echo off call %~dp0setPath.cmd ssh-add -l if ErrorLevel 1 ( setlocal EnableDelayedExpansion ssh-add ~/.ssh/rsa_GitHub_HIU echo ------------------------------------------------------------ echo ** WARNING ** echo Visual Studio Code will *RESTART* after boot. Please wait... echo ------------------------------------------------------------ start %~dp0VSCode\Code.exe :loop sleep 1 set COUNT=0 for /f "skip=3 tokens=1" %%a in ('tasklist /fi "imagename eq code.exe"') do ( set /a COUNT+=1 ) if "!COUNT!" LSS "6" goto :loop echo Visual Studio Code is restarting now. Please wait... for /f "tokens=3" %%a in ('%~dp0VSCode\bin\code.cmd --status ^| grep code') do ( taskkill /PID %%a > nul 2>&1 ) endlocal ) start %~dp0VSCode\Code.exe要点解説:割愛
これが読めるようになると、大抵のバッチファイルは書けるはず。Electronがウィンドウ作るんで/minも>nulも効かないのがお騒がせになって残念。や、VSCodeのバグ取れるといいっすね。クローンする
はいこれで本当にOK。早速git cloneしましょう。プライベートリポジトリの初期化はGitHubサイトの方で済ませておいてください。
リポジトリを開いたら右側のClone or download
ボタンをクリック、そのダイアログがClone with SSH
になっていることを確認、もしもClone with HTTPS
となっていたら、その横(画像ではUse HTTPSとなっている場所)にUse SSH
リンクがあるのでそれをクリックして切替、その下のアドレスがかかれた右側にある、クリップボードに左矢印ボタンを押してアドレスをコピーします。
Ctrl+Shift+P
でコマンドパレットを開き、git clone
ぐらいに入力するとGit: クローン
が出るのでそれを選択、
リポジトリのURLを聞かれるので、入力欄をクリックしてCtrl+V
で貼り付け、
Enter
キーを押すとダイアログが出るので、ポータブル環境のfiles
フォルダを選択してリポジトリの場所を選択
ボタンを押します。するとfiles
の下にリポジトリと同名のフォルダを作成して持ってきます。git initもいらないです。下の奴が出てもこれはエラーじゃないんでビビらなくてOKです。
手順通りにやると、最終的にはこの様な配置になります。もちろん
files
以下はクローンしたリポジトリによって様々です。[jtHiuPortable] ├───[.ssh] │ ├───config │ ├───known_hosts │ ├───rsa_GitHub_HIU │ └───rsa_GitHub_HIU.pub ├───[apps] │ └───[win] │ ├───[VSCode] │ ├───[PortableGit] │ ├───Code.cmd │ ├───recall-ssh-agent.cmd │ ├───setPath.cmd │ └───summon-ssh-agent.cmd ├───[files] │ └───[sandbox] │ ├───[.git] │ ├───.gitignore │ ├───LICENSE │ └───README.md ├───.bash_history ├───.gitconfig ├───VSCode_Win.lnk └───RecallAgent_Win.lnk以上です。では、Happy Coding!
- 投稿日:2019-02-18T14:54:37+09:00
gitとGitHubを連携しクローン、プッシュ
はじめてGitHubを使う前に
知っておきたい用語を簡単に説明すると、
ローカル
作業しているパソコン
ローカルレポジトリ
作業しているパソコンの中にあるフォルダ
リモートレポジトリ
作業しているパソコンの外にあるサーバー上のフォルダ
git clone
git cloneとはGitHubで作ったリポジトリを作業中のパソコンにコピーするためのコマンド。
cmdcd Desktop¥workspace¥workspace-testまずクローンしたフォルダを置く、ローカル上のフォルダへ移動する。例えばデスクトップ上のworkspaceフォルダの中のworkspace-testというフォルダに移動するには上のように入力。(¥は半角です)
フォルダに移動したらgit cloneを実行。
cmdgit clone http://github.com/<GitHubのアカウント名>/<クローンするレポジトリ名>cloning into <クローンするレポジトリ名>... とクローンが始まります。
先ほど移動したローカルのフォルダに、新しくクローンしてきたフォルダが作成されていたら完了です。
gitとGitHubを連携する
クローンが終わったら、パソコン上のgitを操作するためにgitを設定します。
cmdgit config user.name "GitHubのユーザー名" git config user.email "GitHubに登録しているメールアドレス"git push
git pushとは、作業しているパソコンに入っているフォルダの内容を、サーバー上のフォルダに反映させるためのコマンドです。
まず、git pushするファイルへ移動します。
cmdcd Desktop¥workspace¥workspace-test¥<フォルダ名>gitにアップするために次のコマンドを入力。
cmdgit add --all git commit -m "<コメント>" git push以上でプッシュ完了です。
プッシュできないとき
複数人でパソコンを使っていたり、gitとGitHubが上手く連携していないとプッシュできないことがあるので、その場合はアカウントの連携をしなおします。
cmdgit remote set-url origin http://<GitHubのアカウント名>:<GitHubのパスワード>@github.com/<GitHubのアカウント名>/<レポジトリ名>
- 投稿日:2019-02-18T00:33:20+09:00
チーム開発に混ぜてもらいたい人のための【Git入門】その1
はじめに
技術研修の基礎編を終えて、やっとサービスの一部に携われるようになりました。そこで、「今まで独学でプログラムの勉強をしてきたけど、まだチーム開発をしたことがない…」という方々に向けて、チーム開発をする上では欠かせない【Gitとは何ぞや】ということを、私なりにまとめさせて頂きます。
Gitとは
Git(ギット)は、プログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムである。
チームで開発をする際に、どこの誰がどのような意図を持ってコードを変更したのかということがすごく大切です。【Git】を使うことで簡単にそれらの記録が行えます。
Gitの用語
リポジトリ
Gitは時系列でファイルの記録を整理できます。その管理するデータベースのことをリポジトリと言います。写真のアルバムみたいなものですかね!
画像:Section-9よりコミットとコミットメッセージ
リポジトリにファイルの変更内容を記録すること、その結果作られた記録のことをコミットといいます!アルバム(リポジトリ)の中にある写真みたいなものですね!
また、インスタなどで使われるハッシュタグのようにコミットメッセージをつけることで、どのような修正を行ったか詳細に記録に残すことができます。
画像:Instagram(インスタグラム)にパソコンから写真を投稿する方法よりワークツリー
Gitによってコードやファイルの変更を監視されているフォルダのこと。
ワーキングディレクトリー、ワーキングコピー、作業コピーとも呼びます。
ステージング
コミットにはコミットメッセージにそぐわない無関係の変更を含むべきではありません。しかし作業によってはワーキングツリーに大量の変更が積まれる場合があります。その時にコミットに含めたい変更を選別することをいいます。
たくさん写真を撮ったけど、どれをインスタに投稿しようかな〜ってのと同じ感じですね!
ブランチとマージ
ブランチとは履歴の流れを分岐して記録していくためのものです。分離したブランチは他のブランチの影響を受けないため、同じリポジトリの中で複数の変更を同時に進めていくことができます!
画像:猿でもわかるGit入門より逆にマージとは枝分かれした変更履歴を一つにまとめることをいいます!
画像:MARTECHTODAYよりコンフリクト
- 同じ箇所を
- 別々のブランチで
- 別々の変更をかけてしまったのに
- マージする
と起こってしまう「衝突」現象です。どっちの変更を受け入れればいいの?ってことですね!
こうなるとブランチのマージは一旦保留になり、ユーザが手動でコンフリクトを解消する必要があります。次回予告
【Gitとは何ぞや】ということを簡単にですがご説明させて頂きました。次回は具体的なGitコマンドをまとめさせて頂きたいと思います。
*説明に不備やおかしな点がございましたらご指摘いただけると幸いです。
リファレンス
本当の初心者向け!Git入門のための概念から基本用語まで
git add ってなんのためにやるの? Gitの「ステージング」をイラストで解説します!
サルでもわかるGit入門〜バージョン管理を使いこなそう〜
コンフリクトって!?Gitバージョン管理でマージしたときに発生した衝突を解決する