- 投稿日:2020-09-16T22:52:51+09:00
意外と知られていないGithubの便利なショートカット
まずはこれ
shift
+?
リポジトリトップにて
key 機能 g → i issue一覧へ g → p プルリク一覧へ g → a actionsページへ g → b プロジェクトページへ g → w wiki一覧へ ※ → は、1つめを押した後すばやく2つめを押すという意
プルリクエストページにて
key 機能 q Reviewers サジェストを開く (Re q
uest Reviewers で覚える)a Assigner サジェストを開く g → 4 Files changes ページへ(4つめタブへgoで覚える) プルリクエスト Files changes ページにて
key 機能 v Review changes ボタンを押す c コミット一覧表示 t ファイル一覧表示 ファイルビューにて
key 機能 e 編集する 全般
key 機能 s 検索フォームにフォーカス 余談
最近、腱鞘炎になりかけてしまい、Macトラックパッドを極力使わない、かつ作業効率化するためにまとめてみました
他にも便利なショートカットあればそっと補足お願いいたします
- 投稿日:2020-09-16T22:36:57+09:00
“Beyond the Twelve-Factor App” & “The Twelve-Factor App”から学びAWSで実践する (1)1つのコードベース、1つのアプリケーション / コードベース - バージョン管理されている1つのコードベースと複数のデプロイ
解説
本ファクターでは、アプリケーションのソースコードの管理方法、デプロイの考え方を述べています。
アプリケーションはバージョン管理されたリポジトリに単一のコードとして管理されていること
ようするにGitでソースコードを管理しましょうということです。ソースコードの変更がきちんと管理されているというのがアプリケーション開発の出発点になります。企業やチームで開発する場合はもちろんですが、個人で開発する場合も必ずバージョン管理ツールを使いましょう。ソースの修正は意図をもって行い、その意図が記録されているという状況が健全です。アプリケーションは単一のコードから複数の環境にデプロイされること
アプリケーションをデプロイする場合には、管理されているコードから実施しましょう。デプロイは開発用、テスト用、ステージング用、プロダクション用といったように様々な用途で複数の環境に展開することができるようにしておく必要があります。なお、単一のコードといっても、同じバージョンのコードがデプロイされている必要はありません。バージョン管理されているコードのどの部分からでも、好きな環境にデプロイできるようになっているべきです。例えば、プロダクション環境はテストがすべて完了したコードのバージョンでデプロイするべきだし、開発やテスト用の環境には新規に追加した機能を含んだコードからデプロイすることになるでしょう。一つのコードから複数のアプリケーションを生みださないこと
一つのコード管理の中に複数のアプリケーションを入れるのはやめましょう。具体的には、複数の起動スクリプトやmain関数などが単一のコードに入っていることを禁じています。この状態は複数の開発チームが単一のコードに対してメンテしている状態になっていることを示しているという指摘です。この状態では他にも、異なるライフサイクルのアプリケーションが一つのコードに入っているということになります。あるタイミングのソースコードはアプリ1はプロダクションレベル、アプリ2が開発中というような状況になると適切なバージョン管理ができません。このようになっている場合には、アプリケーション毎にそれぞれリポジトリを用意し別々に管理することを始めましょう。ソースの分割に当たって、共通ライブラリ的な部分があれば、これも別のリポジトリで管理し分けて管理していきます。
Beyondの中では、さらにコンウェイの法則(組織やチームの構成はソフトウェアアーキテクチャに反映される)に関してもここで触れています。アプリケーションを適切な単位に分解しマイクロサービス化することを提唱しています。モノリシックで大きなシステムが一つのコードとして管理されている場合、この時も一つのリポジトリで多くの開発チームが同時に作業をしていることでしょう。たとえ複数のアプリケーションを生みだしていなくても結局は同じ状況になります。それを解消するための方法論としてマイクロサービスとなります。これは先ほどの分割よりは大変でしょうが、継続して開発を続けていく上では必要なリファクタリングです。実践
Gitを使ったソースコードの管理手法
世の中には多くのGit互換のリポジトリが存在します。最も有名なのがGitHubです。他にも、Bitbucket、GitLabといったパブリックサービスが存在します。使い勝手はそれぞれでしょうが各チームの事情に合ったものを選択してよいと思います。個人で利用する場合でも必ずこういったリポジトリを利用しコードの管理をしましょう。なお、古い体質の日本企業だと「パブリックサービスにソースを預けるなんて」となり簡単には使わせてもらえないこともあるでしょう。その時はGitLabを独自で運用するという選択が現実的かもしれません。また、AWSを使ったサービスの開発を行っているのであれば、CodeCommitを使ってしまうのもありかもしれません(グレーゾーンですが・・・)。
Gitの運用ワークフロー
Gitを運用する上で、ワークフローを決める必要があります。有名どころは、Git Flow、GitHub Flow、GitLab Flowといったところです。開発の現場に合わせたフローを導入すれば良いですが、筆者としてはGitHub Flowをおすすめします。この中では最もシンプルでわかりやすく、普段の開発をスピード感を持って進められます。あまり複雑な手順を開発チーム全員に理解してもらうのは導入コストがかさみますし、複雑なフローは日常の開発でストレスがたまります。GitHub Flowだと開発者にとっての手順は非常に簡単です。デプイに関しては少し工夫が必要かと思いますが、開発のコミットの方がデプロイの回数よりも圧倒的に多いですし、開発作業に携わる人よりもデプロイを担当する人のが少ないのが一般的なので複雑なことをやる人が全体では少なくなります。普段の開発しやすさを重視するのがチーム全体としてはプラスになるのではないかと思います。
上がGitHub Flowの簡単な模式図です。GitHub Flowのポイントをまとめると以下になります。
master
ブランチ を常にデプロイ可能な状態に保ちます- 新しい何かを始めるときには、
master
ブランチから説明的なブランチ(feature-X、bugfix-Yといった、何を目的にどんなことをやっているのかがわかるブランチ)を作成して作業を行います- 作業ブランチへのコミットに対して意見をもらいたい場合や、
master
ブランチにマージしてもらいたいときにはプルリクエストを作成しレビュアーに送ります- レビュアーはプルリクエストに対応して、コードをレビューし
master
ブランチにマージします変更するたびにブランチを作り、変更をすぐに''master''ブランチに反映してしまうモデルです。開発者は''master''ブランチからブランチを作って開発し、''master''ブランチにマージするという作業をひたすら繰り返すとこになります。
この時最も重要なのは''master''ブランチを常にデプロイ可能な状態に保つというところです。master
ブランチに変更をマージするときには、ソースコードのレビューだけでなく、きちんとテストを通してから行うことが必須になります。マージリクエスト実施時やマージ時などにCIでテストが自動で動くようにしておく必要があるでしょう、これができていないとmaster
ブランチがビルドできなくなったり、まったく動かなくなったりすることになるのでこのGitHub Flowの大原則が破綻してしまいます。デプロイスクリプトの管理
デプロイは当然自動化のためのスクリプトを用意することになると思いますが、ソースコードの
master
ブランチが常にデプロイ可能ということは、どのタイミングのmaster
ブランチでもデプロイできるようになっている必要があります。デプロイのためのコードもソースコードと一緒に管理することが理想だと思います。なお、デプロイをJenkinsを使って実施するといつ構成はよくあるのですが、Jenkinsジョブ自体をこのソース管理と一緒にバージョン管理をするのは結構難しいです。デプロイスクリプトに与えるパラメータに非互換の変更を入れてしまったりすると、XXバージョンまでのデプロイ用ジョブと、XXバージョン以降のデプロイ用のジョブといった形になってしまうことがあります。これは広義の意味で単一のリポジトリでバージョン管理されることを破ってしまっているので。Jenkinsのジョブに修正が必要になるような変更があったとしても過去のデプロイスクリプトが動作するのかといったことはケアするとよいでしょう。様々なバージョンのデプロイ
GitHub Flowであれば、デプロイは常に
master
ブランチの成果物から実施されることになります。日本メーカのように品質保証部門でテストをし品質を担保してから市場へリリースするといった製品ライフサイクルを持つ場合、いくつかの例外ケースでGitHub Flowがはまらないところが出てきます。ここでの話は、組み込みやパッケージといったソフトウェア製品を前提とした製品ライフサイクルがクラウドサービスの開発にも適応されているような現場での話になりますので、いつでも当てはまるわけではなく限られた条件下での話なのでご了承ください。前提条件
- 市場へのリリースには、品質保証部門がテストを行い問題ないことを確認したのち行われる(裏を返すと品質保証部門のテストが実施されていないアプリケーションはリリースしてはいけない)
- 第三者(品質保証部門)によるテストが実施されているので品質は高く市場での障害発生頻度は低い
- 製品のリリースサイクルは長く、典型的なウォーターフォール開発である
次々バージョンの開発開始
次バージョンの実装は完了し、品質保証部門での評価が行われている途中から次々バージョンの実装が始まることはよく発生します。この場合
master
ブランチの状態は品質保証部門へ投入したもの、もしくは品質保証部門で発見された障害に対して修正を行ったバージョンとなります。次々バージョン向けの修正が次バージョン向けの製品に混入することはプロセス上許されないので、master
ブランチへの次々バージョン向け実装のマージは許されません。ずっとブランチのまま実装をマージせずに放置するのも開発効率という点で良いことがありません。この場合。GitHub Flowの原則を少し破り、一時的に次々バージョンの開発のためにブランチを増やして対応します。下の図で示したV2.0
ブランチがそれにあたります。このブランチのライフサイクルは短く、次バージョンであるV1.1のコードがFixするまでの間の短期的なものになります。この期間だけは複数バージョンの平行稼働が行われます。なお、master
ブランチのモジュールは品質保証環境に、V2.0
ブランチのコードは、開発環境へデプロイするといったこともできるようにしておく必要があります。
なお、逆パターンとしてV2.0を始めざるを得ないタイミングで_V_1.1__側をブランチして
master
ブランチを次々バージョンの開発とする手もありますがGitHub Flowの原則を考えると前者の方法の方が良いと思います。(
master
`ブランチが最も安定しているバージョンで、次々バージョン用の説明的なブランチがある状態)障害発生時の対応
次バージョンの開発中にすでにデプロイ済みの現行製品で市場障害が発生した場合の対応です。障害が致命的な場合、直ちに現行バージョンを修正して修正版をリリースする必要があります。評価が完了していない次バージョンがコミットされている''master''ブランチからリリースすることは当然許されません。この場合、一時的なブランチを追加します。下の図に示した
V1.0.X
ブランチがそれにあたります。このブランチのライフサイクルは現行バージョンに障害が出てから、次のバージョンのリリースが完了するまでです。障害が発生し、急ぎで修正が必要な場合のみなので、障害の少ないプロダクトでは、このブランチは多くの場合存在しないことになります。なお、一度このブランチを作成したらそれは破棄するのではなく、V1.0の障害対応版であるV1.0.1を市場投入した後もV1.1リリースまではブランチを維持しておきます、万が一次の障害が発生したら、このブランチをもとに開発を行いリリースします。まとめ
最初のファクターとして、アプリケーションのソースコードの管理方法、デプロイの考え方をGitHub Flowを前提において話を進めてきました。AWS色がほぼない記事になってしましたが、このファクターの内容では無理にAWSを利用しなくても良いと思います。
- 投稿日:2020-09-16T21:27:31+09:00
【Git】conflict(コンフリクト)の解決方法まとめ
【Git】conflict(コンフリクト)の解決方法まとめ
gitで作業していると時折発生するコンフリクトを慌てず・冷静に対処するための、コンフリクトの発生要因と解決法のまとめ。
目次
コンフリクトとは?
conflictは矛盾や対立の意味。ここでは同じファイルで相容れない状況が発生しているということ。
異なるコミットを統合したり・持ってくるときに、2つのコミットで同じファイルの重複する箇所で変更が発生していたときに生じるエラー。
Gitはどちらの変更内容が正しいかを判断できないため、エラーとして打ち上げこちらで判断できるようにしてくれる。
コンフリクトが発生する主なコマンド
コミットの統合や移動で発生する。
git merge
: 統合
git rebase
: 移動
git cherry-pick
:選択的に移動それぞれのコマンドの詳細は以下。
・git merge
・git rebase
・git cherry-pick
gitコンフリクトの発生方法
練習でコンフリクトを発生させる。コンフリクトの発生自体は簡単。
#コンフリクト発生用のフォルダを作成 $ mkdir conflict #作成したフォルダに移動 $ cd conflict #git初期化 $ git init #index.htmlを作成(コンフリクトを発生させるファイル) $ touch index.html #インデックス $ git add . #レポジトリに追加(作業中のブランチがmasterブランチになる) $ git commit -m "first commit" #topicブランチを作成し移動する $ git checkout -b topic #index.htmlを編集(適当にテキストを追加。:wqで保存終了) $ vim index.html #コミット $ git commit -am "revise index.html at topic" #masterブランチに移動 $ git checkout master #index.htmlファイルを編集(適当にテキストを追加。:wqで保存終了) $ vim index.html #コミット $ git commit -am "revise index.html at master" #マージ ※コンフリクトを発生させる $ git merge topic Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result.無事(?)コンフリクトが発生。
コンフリクトの内容の確認方法
コンフリクトが発生した時点で、
git status
を実行すると、コンフリクトが発生しているファイルが確認できる。ファイルの特定$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: index.html no changes added to commit (use "git add" and/or "git commit -a")
Unmerged paths
マージできなかった内容を表している。
both modified: index.html
index.htmlファイルが両者で変更されている(矛盾が発生している)。
▼コンフリクトが発生したファイルファイルの中身<<<<<<< HEAD <h1> add h1 </h1> ======= <h1> h1です。</h1> >>>>>>> topicコンフリクトが発生したファイルには、下記3つの記号が挿入されている。
<<<<<<< HEAD
=======
>>>>>>> トピックブランチ名
見方は1と2で挟まれた部分が、現在いるブランチ(HEAD)の内容。2と3で囲まれた部分がmergeで指定したトピックブランチの内容。
2つの変更内容が一つのファイルに統合され、ユーザーが中身を確認できる状態となっている。
ファイルの中身<<<<<<< HEAD {現在のブランチで保存されている内容} ======= {topicブランチで保存されている内容} >>>>>>> topic
コンフリクトの修正方法
コンフリクトの修正方法は複数存在する。
mergeをキャンセルする
最も単純なのが、先ほど実行したmergeをキャンセルして実行前の状態に戻す方法。
進行中の処理の中断を表--abortオプションを使う。
・
git merge --abort
--abortはrebaseやcherry-pickなど他のコマンドでも使える。
手動でファイルを修正する
コンフリクトが発生したら、下記手順で解消することができる。
- ファイルを特定(git status)
- 指定のファイルを修正
- インデックス (git add)
- コミット(git commit)
1.ファイルの特定$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: index.html no changes added to commit (use "git add" and/or "git commit -a")コンフリクトが発生しているファイルがindex.htmlだとわかる。
index.html<<<<<<< HEAD <h1> add h1 </h1> ======= <h1> h1です。</h1> >>>>>>> topicファイルを開くと、双方の内容が上下に表示されている。内容を見ながらファイルを修正する。
どちらか一方にするのが一般的。2つを合わせたり、別の記述にすることも可能。
今回はtopicブランチの変更内容を採用する。(不要なテキストを削除)
index.html<h1> h1です。</h1>変更が完了したら、インデックスしてコミットする。
$ git add index.html $ git commit -m "resolve conflict" [master 1264d10] resolve conflict #ログの状態を確認 $ git log --oneline --graph * 1264d10 (HEAD -> master) resolve conflict |\ | * 81f13bc (topic) revise index.html at topic * | 44ef796 revise index.html at master |/ * b70ea8b first branchコンフリクトが解消し、merge成功。
メインブランチの変更内容を採用する(-Xours)
先ほどはコンフリクト発生部を目視でどちらにするか選び、手動で修正したが、オプションで指定することも可能
git merge -Xours トピックブランチ
このコマンドを実行するには一旦、コンフリクトが発生している処理をキャンセルする必要がある。
- git merge --abort で処理キャンセル
- git merge -Xours topic で再度マージ
トピックブランチの変更内容を採用する(-Xtheirs)
コンフリクトが発生した際に、その箇所はトピックブランチの内容を採用する。
git merge -Xtheirs
- git merge --abort で処理キャンセル
- git merge -Xtheirs topic で再度マージ
トピックブランチの内容を無視する(-s ours)
-Xoursと-Xtheirsはコンフリクトが発生した箇所のみ指定したブランチの内容に修正するオプション。
一方で、「-s ours」をつけると、トピックブランチの内容はすべて無視して、現在のブランチの内容でmergeをする。
git merge -s ours
$ git merge -s ours topic Merge made by the 'ours' strategy.
▼参考
merge後のブランチとmerge前のブランチの内容を比較すると何も変化していないことがわかる。$ git diff HEAD HEAD~ $
空白を削除してマージ
コンフリクトしている内容がスペースの数や位置のみの場合、オプションを指定することでマージができる。
違いが空白行の有無や作業者によるTABの使い方のみの場合に使える。
・
-Xignore-all-space
┗ 全てのスペースを無視・
-Xignore-space-change
┗ 2つ以上連続したスペースを無視$ git merge -Xignore-space-change topic Auto-merging index.html Merge made by the 'recursive' strategy.ただし、空白行以外でコンフリクトが発生している場合はエラーになる。
手動でファイルをマージ
応用的なやり方で、コンフリクトしているそれぞれのファイルを一つのファイルに統合する方法がある。
実際に使うことはないと思われるが、git mergeの裏側の処理を理解するために大いに役立つ内容。
git mergeがやっていること
git mergeは(1)両者の共通の祖先のコミット、(2)現在のブランチのコミット、(3)トピックブランチのコミットの3つのスナップショットから新たなコミットを作成している。
▼merge処理のイメージ
下図で見ると、C、G、E3つのコミットから、新たなコミットHを作るのが、mergeの処理内容。A---B---C topic / D---E---F---G master $ git merge topic ↓↓↓ A---B---C topic / \ D---E---F---G---H masterコンフリクトが発生した時点では、masterブランチにC, G, Eに相当するファイル(スナップショット)がそれぞれ作成されている。
3つのファイルの参照方法。
(1)両者の共通の祖先のコミット、(2)現在のブランチのコミット、(3)トピックブランチのコミットの3つのスナップショットにはそれぞれ1〜3の番号が割りふられている。
各ファイルは下記で指定できる。
:n:ファイル名
┗ nは1〜3例えば、index.htmlでコンフリクトが発生した場合に(1)のファイルを参照するには、
git show :1:index.html
で見ることができる。マージされていないファイルの一覧を表示する(ls-files -u)
merge後にコンフリクトが発生した時の3つのファイルは
ls-files -u
コマンドで表示することができる。各ハッシュ値の後に記述されている1〜3がそれぞれのファイルを表してている。
$ git ls-files -u 100755 ac51efdc3df4f4fd328d1a02ad05331d8e2c9111 1 index.html 100755 36c06c8752c78d2aff89571132f3bf7841a7b5c3 2 index.html 100755 e85207e04dfdd5eb0a1e9febbc67fd837c44a1cd 3 index.htmlファイルの統合
ファイルを手動で統合するためには次の手順を踏む必要がある。
- 物理的な3つのファイルに内容を書き込む
- コンフリクトの内容を修正する
- merge-fileコマンドで3つのファイルをマージする
- 不要になったファイルを削除する
1. 物理的な3つのファイルに内容を書き込む
リダイレクト「>」記号を使って、3つのファイルの内容を新たなファイルを作成し書き込む。
$ git show :1:index.html > index.common.html $ git show :2:index.html > index.ours.html $ git show :3:index.html > index.theirs.htmlそれぞれのファイルの内容が何を表しているかわかるファイル名にしておく。
2. コンフリクトの内容を修正する
修正したいファイルを開いてコンフリクトの内容を手動で修正する。
3. merge-file -pコマンドで3つのファイルをマージする
merge-file -pコマンドで3つのファイルを、コンフリクトが発生しているファイルに書き込む。
git merge-file -p 共通祖先 現在 トピックブランチのファイル > コンフリクトが発生しているファイル実例$ git merge-file -p index.common.html index.ours.html index.theirs.html > index.html
4. 不要になったファイルを削除する
git clean -f
を使って先ほど作成したファイルを削除する。
git clean
は現在のディレクトリでgitが認識していないファイルを削除するコマンド。つまり、git addしたことがないファイルをまとめて削除する。
git clean -n
で、gitが認証していないファイルの一覧を表示することができる。#念のため、gitが認識してないファイルの一覧を表示 $git clean -n index.common.html index.ours.html index.theirs.html #ファイルを削除 $ git clean -f Removing index.common.html Removing ours.html Removing theirs.html以上でgit mergeの一連の作業が完了。
- 投稿日:2020-09-16T21:27:31+09:00
【Git】コンフリクト(conflict)が発生しても大丈夫な対処法まとめ 〜自分で発生させて解決する手順〜
【Git】コンフリクト(conflict)が発生しても大丈夫な対処法まとめ 〜自分で発生させて解決する手順〜
gitで作業していると時折発生するコンフリクトを慌てず・冷静に対処するための、コンフリクトの発生要因と解決法のまとめ。
目次
コンフリクトとは?
conflictは矛盾や対立の意味。ここでは同じファイルで相容れない状況が発生しているということ。
異なるコミットを統合したり・持ってくるときに、2つのコミットで同じファイルの重複する箇所で変更が発生していたときに生じるエラー。
Gitはどちらの変更内容が正しいかを判断できないため、エラーとして打ち上げこちらで判断できるようにしてくれる。
コンフリクトが発生する主なコマンド
コミットの統合や移動で発生する。
git merge
: 統合
git rebase
: 移動
git cherry-pick
:選択的に移動それぞれのコマンドの詳細は以下。
・git merge
・git rebase
・git cherry-pick
コンフリクトを発生させる手順
練習でコンフリクトを発生させる。コンフリクトの発生自体は簡単。
#コンフリクト発生用のフォルダを作成 $ mkdir conflict #作成したフォルダに移動 $ cd conflict #git初期化 $ git init #index.htmlを作成(コンフリクトを発生させるファイル) $ touch index.html #インデックス $ git add . #レポジトリに追加(作業中のブランチがmasterブランチになる) $ git commit -m "first commit" #topicブランチを作成し移動する $ git checkout -b topic #index.htmlを編集(適当にテキストを追加。:wqで保存終了) $ vim index.html #コミット $ git commit -am "revise index.html at topic" #masterブランチに移動 $ git checkout master #index.htmlファイルを編集(適当にテキストを追加。:wqで保存終了) $ vim index.html #コミット $ git commit -am "revise index.html at master" #マージ ※コンフリクトを発生させる $ git merge topic Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result.無事(?)コンフリクトが発生。
コンフリクトの内容の確認方法
コンフリクトが発生した時点で、
git status
を実行すると、コンフリクトが発生しているファイルが確認できる。ファイルの特定$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: index.html no changes added to commit (use "git add" and/or "git commit -a")
Unmerged paths
マージできなかった内容を表している。
both modified: index.html
index.htmlファイルが両者で変更されている(矛盾が発生している)。
▼コンフリクトが発生したファイルファイルの中身<<<<<<< HEAD <h1> add h1 </h1> ======= <h1> h1です。</h1> >>>>>>> topicコンフリクトが発生したファイルには、下記3つの記号が挿入されている。
<<<<<<< HEAD
=======
>>>>>>> トピックブランチ名
見方は1と2で挟まれた部分が、現在いるブランチ(HEAD)の内容。2と3で囲まれた部分がmergeで指定したトピックブランチの内容。
2つの変更内容が一つのファイルに統合され、ユーザーが中身を確認できる状態となっている。
ファイルの中身<<<<<<< HEAD {現在のブランチで保存されている内容} ======= {topicブランチで保存されている内容} >>>>>>> topic
コンフリクトの修正方法
コンフリクトの修正方法は複数存在する。
mergeをキャンセルする
最も単純なのが、先ほど実行したmergeをキャンセルして実行前の状態に戻す方法。
進行中の処理の中断を表--abortオプションを使う。
・
git merge --abort
--abortはrebaseやcherry-pickなど他のコマンドでも使える。
手動でファイルを修正する
コンフリクトが発生したら、下記手順で解消することができる。
- ファイルを特定(git status)
- 指定のファイルを修正
- インデックス (git add)
- コミット(git commit)
1.ファイルの特定$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: index.html no changes added to commit (use "git add" and/or "git commit -a")コンフリクトが発生しているファイルがindex.htmlだとわかる。
index.html<<<<<<< HEAD <h1> add h1 </h1> ======= <h1> h1です。</h1> >>>>>>> topicファイルを開くと、双方の内容が上下に表示されている。内容を見ながらファイルを修正する。
どちらか一方にするのが一般的。2つを合わせたり、別の記述にすることも可能。
今回はtopicブランチの変更内容を採用する。(不要なテキストを削除)
index.html<h1> h1です。</h1>変更が完了したら、インデックスしてコミットする。
$ git add index.html $ git commit -m "resolve conflict" [master 1264d10] resolve conflict #ログの状態を確認 $ git log --oneline --graph * 1264d10 (HEAD -> master) resolve conflict |\ | * 81f13bc (topic) revise index.html at topic * | 44ef796 revise index.html at master |/ * b70ea8b first branchコンフリクトが解消し、merge成功。
メインブランチの変更内容を採用する(-Xours)
先ほどはコンフリクト発生部を目視でどちらにするか選び、手動で修正したが、オプションで指定することも可能
git merge -Xours トピックブランチ
このコマンドを実行するには一旦、コンフリクトが発生している処理をキャンセルする必要がある。
- git merge --abort で処理キャンセル
- git merge -Xours topic で再度マージ
トピックブランチの変更内容を採用する(-Xtheirs)
コンフリクトが発生した際に、その箇所はトピックブランチの内容を採用する。
git merge -Xtheirs
- git merge --abort で処理キャンセル
- git merge -Xtheirs topic で再度マージ
トピックブランチの内容を無視する(-s ours)
-Xoursと-Xtheirsはコンフリクトが発生した箇所のみ指定したブランチの内容に修正するオプション。
一方で、「-s ours」をつけると、トピックブランチの内容はすべて無視して、現在のブランチの内容でmergeをする。
git merge -s ours
$ git merge -s ours topic Merge made by the 'ours' strategy.
▼参考
merge後のブランチとmerge前のブランチの内容を比較すると何も変化していないことがわかる。$ git diff HEAD HEAD~ $
空白を削除してマージ
コンフリクトしている内容がスペースの数や位置のみの場合、オプションを指定することでマージができる。
違いが空白行の有無や作業者によるTABの使い方のみの場合に使える。
・
-Xignore-all-space
┗ 全てのスペースを無視・
-Xignore-space-change
┗ 2つ以上連続したスペースを無視$ git merge -Xignore-space-change topic Auto-merging index.html Merge made by the 'recursive' strategy.ただし、空白行以外でコンフリクトが発生している場合はエラーになる。
手動でファイルをマージ(応用編)
応用的なやり方で、コンフリクトしているそれぞれのファイルを一つのファイルに統合する方法がある。
実際に使うことはないと思われるが、git mergeの裏側の処理を理解するために大いに役立つ内容。
git mergeがやっていること
git mergeは(1)両者の共通の祖先のコミット、(2)現在のブランチのコミット、(3)トピックブランチのコミットの3つのスナップショットから新たなコミットを作成している。
▼merge処理のイメージ
下図で見ると、C、G、E3つのコミットから、新たなコミットHを作るのが、mergeの処理内容。A---B---C topic / D---E---F---G master $ git merge topic ↓↓↓ A---B---C topic / \ D---E---F---G---H masterコンフリクトが発生した時点では、masterブランチにC, G, Eに相当するファイル(スナップショット)がそれぞれ作成されている。
3つのファイルの参照方法。
(1)両者の共通の祖先のコミット、(2)現在のブランチのコミット、(3)トピックブランチのコミットの3つのスナップショットにはそれぞれ1〜3の番号が割りふられている。
各ファイルは下記で指定できる。
:n:ファイル名
┗ nは1〜3例えば、index.htmlでコンフリクトが発生した場合に(1)のファイルを参照するには、
git show :1:index.html
で見ることができる。マージされていないファイルの一覧を表示する(ls-files -u)
merge後にコンフリクトが発生した時の3つのファイルは
ls-files -u
コマンドで表示することができる。各ハッシュ値の後に記述されている1〜3がそれぞれのファイルを表してている。
$ git ls-files -u 100755 ac51efdc3df4f4fd328d1a02ad05331d8e2c9111 1 index.html 100755 36c06c8752c78d2aff89571132f3bf7841a7b5c3 2 index.html 100755 e85207e04dfdd5eb0a1e9febbc67fd837c44a1cd 3 index.htmlファイルの統合
ファイルを手動で統合するためには次の手順を踏む必要がある。
- 物理的な3つのファイルに内容を書き込む
- コンフリクトの内容を修正する
- merge-fileコマンドで3つのファイルをマージする
- 不要になったファイルを削除する
1. 物理的な3つのファイルに内容を書き込む
リダイレクト「>」記号を使って、3つのファイルの内容を新たなファイルを作成し書き込む。
$ git show :1:index.html > index.common.html $ git show :2:index.html > index.ours.html $ git show :3:index.html > index.theirs.htmlそれぞれのファイルの内容が何を表しているかわかるファイル名にしておく。
2. コンフリクトの内容を修正する
修正したいファイルを開いてコンフリクトの内容を手動で修正する。
3. merge-file -pコマンドで3つのファイルをマージする
merge-file -pコマンドで3つのファイルを、コンフリクトが発生しているファイルに書き込む。
git merge-file -p 共通祖先 現在 トピックブランチのファイル > コンフリクトが発生しているファイル実例$ git merge-file -p index.common.html index.ours.html index.theirs.html > index.html
4. 不要になったファイルを削除する
git clean -f
を使って先ほど作成したファイルを削除する。
git clean
は現在のディレクトリでgitが認識していないファイルを削除するコマンド。つまり、git addしたことがないファイルをまとめて削除する。
git clean -n
で、gitが認証していないファイルの一覧を表示することができる。#念のため、gitが認識してないファイルの一覧を表示 $git clean -n index.common.html index.ours.html index.theirs.html #ファイルを削除 $ git clean -f Removing index.common.html Removing ours.html Removing theirs.html以上でgit mergeの一連の作業が完了。
- 投稿日:2020-09-16T19:26:03+09:00
git cherry-pick。コミット履歴をきれいに、特定のコミットだけ取り込む方法
git cherry-pick。コミット履歴をきれいに、特定のコミットだけ取り込む方法
Gitのコミット履歴を編集する時にとても便利なcherry-pickコマンド。
cherry-pickとはさくらんぼを選別するの意味。ここでは、欲しいコミットだけ取ってくることを指す。
目次
merge, rebase, cherry-pickの違い
他のブランチから新しいコミットを作成する主なコマンドに、merge, rebase, cherry-pickがある。
違いを図示すると下記のようになる。
merge
メインブランチとトピックブランチ両方のコミットをそのまま保持。
mergeA---B---C topic / D---E---F---G master $ git merge topic ↓↓↓ A---B---C topic / \ D---E---F---G---H masterrebase
トピックブランチのコミットをコピーしてメインブランチの先端に移動
rebaseA---B---C topic / D---E---F---G master $ git rebase master ↓↓↓ topic D---E---F---G---A'---B'---C' mastercherry-pick
欲しいコミットだけをコピーし、メインブランチの先端に移動。
cherry-pickA---B---C topic / D---E---F---G master $ git cherry-pick B ↓↓↓ D---E---F---G---B' master
cherry-pickの使い方
git cherry-pick <コミット>
指定したコミットを取り込むことができる。
別ブランチで作成したテキストファイルを取り込む#トピックブランチのコミットをコピー $ git cherry-pick f90bf08 [master 2a80313] create aaa.txt Date: Wed Sep 16 17:55:13 2020 +0900 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 aaa.txt #logの確認 $ git log --oneline 2a80313 (HEAD -> master) create aaa.txt 2b23890 add line4最新のコミットに取ってきたコミットが追加された。
コミットの複数指定
コミットを個別に指定
git cherry-pick <コミット> <コミット> <コミット> ...
スペースを空けて複数記載すれば、指定したコミットを全てとってくることができる。cherry-pickA---B---C topic / D---E---F---G master $ git cherry-pick A B C ↓↓↓ master D---E---F---G---A'---B'---C'これは、rebaseと同じ処理になる。
rebaseA---B---C topic / D---E---F---G master $ git rebase master ↓↓↓ topic D---E---F---G---A'---B'---C'連続するコミットを指定
「A..B」とすると連続するコミットを指定できる。
git cherry-pick <コミット>..<コミット>
cherry-pickA---B---C topic / D---E---F---G master $ git cherry-pick A..C ↓↓↓ master D---E---F---G---A'---B'---C'
cherry-pickのオプション
コミットメッセージを変更する(-e)
デフォルトでは元のコミットのコメントをそのまま持ってくる。
オプションで「-e」を指定することでコメントを変更できる。
git cherry-pick -e <コミット>
┗ -e = --edit
コミットはしない(-n)
デフォルトでは元のコミットまでされる。
「-n」オプションを指定することで、コミットせず、インデックス(git add)状態で持ってくることができる。
git cherry-pick -n <コミット>
┗ -n = --no-commit
空のメッセージを許可(--allow-empty-message)
デフォルトでは空のメッセージのコミットを持ってこようとするとエラーになる。
「--allow-empty-message」をつけることで、空のまま持ってくることができる。
git cherry-pick --allow-empty-message
処理をキャンセルする(--abort)
cherry-pickをなかったことにしたい場合は「--abort」をつける。
git cherry-pick --abort
おかしなことが起こった場合は一旦--abortで回避できる。
- 投稿日:2020-09-16T18:50:52+09:00
【Git】直前のコミットのコメントを変更。
- 投稿日:2020-09-16T18:33:24+09:00
git revertとresetの違いと使い方 〜間違ったコミットの修正・消してしまったコミットの復活方法~
git revertとresetの違いと使い方 〜間違ったコミットの修正・消してしまったコミットの復活方法~
間違ったコミットを修正するコマンドに、git revertとgit resetがある。
git revertは指定したコミットの内容を打ち消して、新しいコミットを作成する。(ポインタを前に進める)
git resetは指定したコミットを削除する。(ポインタを過去に戻す)
いずれも、マージした処理の取り消しにも使える。
目次
git revertの使い方
指定したコミットの内容を打ち消して、新しいコミットを作成する処理。
git revert <打ち消したいコミット>
実行後にエディタが立ち上がるので、コミットメッセージを入力する。revertのイメージ#コミット履歴(A〜D) A---B---C---D master #コミットBの作業を打ち消して、新しいコミットD'を作る $git revert B A---B---C---D---D' master
エディタを立ち上げない
git revert --no-edit
エディタをひらきたくない場合は「--no-edit」オプションをつける。コミットメッセージなしで、revertを実行する。
conflictの発生要因と対処法
現在のコミットと指定したコミットで同じ内容を修正している場合、conflictが発生する。
conflictの例$ git revert @@{12} --no-edit Auto-merging style.css CONFLICT (content): Merge conflict in style.css error: could not revert 9390048... add line3 hint: after resolving the conflicts, mark the corrected paths hint: with 'git add <paths>' or 'git rm <paths>' hint: and commit the result with 'git commit'
- --abortオプション
- 手動で修正
--abort
git revert --abort
で処理をキャンセルする。revertコマンドを実行していない状態に戻す。手動で修正
#conflictが発生しているファイルを確認する $ git st On branch ft2 You are currently reverting commit 2767830. (fix conflicts and run "git revert --continue") (use "git revert --skip" to skip this patch) (use "git revert --abort" to cancel the revert operation) Unmerged paths: (use "git restore --staged <file>..." to unstage) (use "git add <file>..." to mark resolution) both modified: style.css #vimエディタで修正する vi style.css #add & commit git add <対象ファイル> && git commit -m "メッセージ"
mergeコミットを打ち消す
-mオプションを使い、現在いるブランチかトピックブランチのどちらかを番号で指定する。
git revert -m <パターン番号> <マージコミット>
┗「-m」: --mainline
┗ パターン番号は2つ(1or 2)
┗ 1: 現在のブランチ
┗ 2: 派生しているブランチmerge後のrevertイメージ#コミット履歴(Hがマージコミット) A---B---C / \ D---E---F---G---H master #コミットHの作業を打ち消して、新しいコミットを作る $git revert -m 1 H A---B---C / \ D---E---F---G---H---H' masterパターン番号に1を指定しているので、H'の内容はGと同じになる。
2を指定した場合はCと同じになる。
mergeコミットrevert時の注意点
mergeコミットをrevertした場合、revertしたブランチはmerge済みの認識のままなので、git mergeしようとすると、updatedと表示される。
$ git merge topic Already up-to-date.
git resetの使い方
指定したコミットを無き物にする強力コマンド。
ログが変わってしまうため、複数人で開発している場合は基本的に使わない。
・
git reset <コミット>
┗ 指定したコミットまでポインタを戻す。resetの重要なオプション
git resetには3つの重要なオプションがある。
- --soft
- --mixed
- --hard
項目 --soft --mixed --hard インデックスファイル 残す 削除 削除 ワークツリー 残す 残す 削除 インデックスファイルやワークツリーなどすべてを消去し、真っさらな過去に戻る場合は--hard、
現在のファイルを修正したい場合は、--mixedか--softを選択する。
--mixedと--softの違いはインデックスファイルの扱い。
resetの実例
以下のようなログで、0193c66 add h1以降のコミットをごっそり削除する。(v1.1まで戻る)
$ git log --oneline * ac23875 (HEAD -> ft1, tag: D-E-F) add main.js * 4af9f09 add h3 * 69d15eb add h2 * 0193c66 add h1 * 494777f (tag: v1.1) second ci * 5eeac88 (tag: v1.0) first ci#resetでv1.1まで戻る $ git reset v1.1 Unstaged changes after reset: M index.html #履歴を確認 $ git log --oneline * 494777f (HEAD -> ft1, tag: v1.1) second ci * 5eeac88 (tag: v1.0) first ciコミットがごっそり削除された。
削除したコミットを復活させる
resetで削除したコミットも復活させることが可能。
resetを含め、実行してきたコマンドの履歴をみるには
git reflog
を使う。直近のリセットしたコミットも表示されるので、その手前のコミットを指定して
git reset --hard <コミット>
を実行する。▼実例
#reflogでコマンドのログを確認 $ git reflog 494777f (HEAD -> ft1, tag: v1.1) HEAD@{0}: reset: moving to v1.1 ac23875 (tag: D-E-F) HEAD@{1}: checkout: moving from ft2 to ft1 e76d8cb (ft2) HEAD@{2}: commit: revised css f90bf08 HEAD@{3}: commit: create aaa.txt 5d8ba72 HEAD@{4}: reset: moving to 5d8ba7253189740df0cfcf47ba19c5e7afc8b7dd 5d8ba72 HEAD@{5}: commit: add line4 52ee140 HEAD@{6}: commit: add line3 2767830 HEAD@{7}: revert: Revert "add line3" 7f6da97 HEAD@{8}: reset: moving to HEAD^先ほどのリセットが1番上に表示される。過去に戻るので、resetで戻りたい場所のコミットを指定する。
$ git reset --hard e76d8cb HEAD is now at 5eeac88 first ci #ログを確認 $ git log --oneline e76d8cb (HEAD -> ft1, ft2) revised css f90bf08 create aaa.txt 5d8ba72 add line4 52ee140 add line3 2767830 Revert "add line3" 7f6da97 Revert "create aaa.txt" 9daedcc create bbb.txt ceebb7a create aaa.txt復活完了。
git resetも処理をキャンセルしたい場合は
git reset --abort
で可能。
- 投稿日:2020-09-16T17:11:23+09:00
Pythonしか触ったことのなかった大学生がReact(Gatsby.js)でWeb開発した話
作ったLP(ランディングページ)
SynQ Remote LP https://www.synq-platform.com/
大学1年の10月から福岡市内のITベンチャーでインターンをしており、そこで自社プロダクトのLP(ランディングページ)開発プロジェクトを任せてもらっています。
今月でインターン開始1年になるので、記念に(?)LP開発までの流れを書いていきたいと思います。LPを作るまでの自分のスキルについて
インターン開始前は授業でPythonを触ったのみ
インターンを始める前、大学1年前期の講義で「プログラミング演習」という必修科目を取っていました。これは関数を定義するくらいまでのPythonの基礎を学ぶ科目で、昔からパソコンをいじるのが好きだった自分はとても面白い講義だなと思い、これをきっかけにプログラミングを学びつつバイト代わりにもなるインターンを探すことを決意します。
インターン先を見つけ、プロジェクトに配属される
2ヶ月ほど期間を要しましたが、ようやくWantedlyで自分に合ったインターン先を見つけることができました。早速、鉄板加工工場のオートメーション化プロジェクトに配属され、主にPythonベースのDjango(バックエンド)の開発を任せてもらいます。初めの方はわからないことだらけでしたが、3, 4ヶ月経つと一定の成果をあげることができるようになっていきました。
Python以外に手を出してみたくなる
すると、そろそろPython以外の言語にも手を出してみたくなりました。インターン先CTOに相談したところ、ReactでQiitaトップページを模写するという課題をいただきました。2月に合宿免許に行くことになりインターンできない状況にあったので、その期間をReact勉強期間に充てたのち、Qiita模写を1週間くらいで開発しました。(https://github.com/horri1520/qiita-toppage/)
LP開発プロジェクトを任せてもらうことに
Qiita模写を通してフロントエンド楽しい!!!もっといろいろ作りたい!!!となっていた自分を見て、前述のCTOがLP開発プロジェクトを任せてくれることになりました。当時僕はフロントエンドの技術スタックについて全然詳しくなかったので、CTOがGatsbyなるものを提案してくれました。ここから、LP開発についての詳細を書いていきたいと思います。
技術スタックについて
フレームワークはGatsby.js
Reactベースの静的サイトジェネレータ、「Gatsby.js」を採用しています。僕のアイデアではないですが(笑
しかし開発を通して、Gatsbyを使ったことによる恩恵を十分に享受することができました。Gatsby製のサイトはなんと言ってもパフォーマンスに長けています。爆速です。
爆速になるカギは静的サイトホスティングサービス「Netlify」と、サイト内の画像を最適化してくれるGatsby専用プラグインgatsby-image
にあると思っています。Netlifyと
gatsby-image
Netlifyはサーバーレスで静的サイトをビルド・ホスティングできるサービスです。主な特徴は、GitHubへのpushをトリガーにサイトのビルド・デプロイが走ることと、その際行われるサーバーサイドレンダリングです。(後者は諸刃の剣な側面があって、、、詳しくは後述します。)
gatsby-image
はlazy-load
やサイズ最適化など、画像を軽量化して扱うための機能がひとまとめになっているプラグインです。詳しいことは割愛しますが、GraphQL
のクエリを叩けば軽量化された画像ファイルを生成してくれます。
Netlifyとgatsby-image
を組み合わせるとどういうことが起こるのかについて説明します。まず、GitHub上のコードから静的サイトのビルドが走ります。サイト上の各要素はこの段階で描画(レンダリング)され、1枚のページビューにまとめられます。その際サイト上の画像はぼやけた、モザイクに近いようなものとしていったん生成されます。
そしてそのページにアクセスすると、最初はモザイクに近い画像が表示されますが、ページを読み進めていくにつれ、高解像度の画像の読み込みが走り(lazy-load
)順次置き換えられていきます。一連の流れを視覚化すると、このような挙動になります。
レンダリングがすでに行われているというだけでも十分高速なのですが、さらに重たい原因になる画像まで軽量化してくれるところがGatsbyならではの強みです。
技術スタックまとめ
Gatsby.jsで書いたコード ↓push GitHub ↓pushをトリガーにビルド&デプロイ Netlify実装してみて
とある日、いつものようにビルドを走らせると…
ページがぐっちゃぐちゃになっていた。。。
めっちゃくちゃ萎えました。このスクショ以外にも様々な見た目で崩壊(画像など各要素は表示されるけど位置がはちゃめちゃとか)していましたが、萎えたのでこのスクショしか撮れていないほどです。やはり自分が開発したサイトがバリエーション豊かに崩壊しているのを見るのはへこみますね。しかし、そうも言ってられないので崩壊原因の調査を始めることにしました。
原因調査
いろいろ調べているうちに、同じ現象に悩まされている方々が執筆したいくつかのブログ記事やフォーラムにたどり着きました。おそらく、導入していたMaterial UIの
makeStyles
とレスポンシブ対応プラグインのreact-responsive
がサーバーサイドレンダリングに対応していないことが全ての原因であるとのことです。しかし、どのページにも有効な解決策は示されておらず、GitHubのissueに至っては解決していないのに閉じられていました。絶望です。解決策を求めて
いったん状況を整理するために、コードを書き換えてみたりコメントアウトしてみたりしました。その結果、
react-responsive
は完全にアウト。発生条件は定かではないが、動作しない箇所が出てきてしまう。makeStyles
はindexページのみの適用だと動作するが、他のページに適用するとそのページのCSSが崩壊してしまう。404ページに至っては、404ページ自体もindexページも共に崩壊してしまった。- これらの現象は
localhost
で立てた開発用サーバーでは発生せず、ビルドしてみて初めて異変に気づくのでそもそも気づくのも遅れる上デバッグもしづらい。という結果が得られました。
もうGatsbyやめようかな…という考えも一瞬頭をよぎりましたが、上述したGatsbyのメリットが大きすぎるため、Gatsbyでも正常に動作するプラグインを探し、それに置き換えることにしました。公式ドキュメントを読むことの重要性
ユーザーで困っている人々がいるのなら、公式はそれに対しどのような見解を持っているのだろうかと気になり、ここでいったんGatsby公式のドキュメントに立ち返ってみることにしました。すると、GatsbyでのCSSスタイリングをどうするのかについてのページにたどり着き、(https://www.gatsbyjs.com/tutorial/part-two/)
styled-components
が推奨されているということを知りました。(逆にmakeStylesが非推奨とはどこにも書かれていませんでしたが!笑)このことで、
- 公式ドキュメントをきっちり読むこと
- サーバーサイドレンダリング下において、特に画面描画周りのプラグインとは相性があるので事前に対応状況を確認するべきであるということ
この2点の重要性を再認識できました。また、レスポンシブ対応プラグインについては、同様にGatsby公式プラグインライブラリ(https://www.gatsbyjs.com/plugins/) から
gatsby-plugin-breakpoints
という対応プラグインを見つけ出すことができました。一連の流れについて振り返ると、発見した時は慌てふためきましたが、今となっては
得られた知見だけでなく問題について調査し、解決に向けて試行錯誤していくプロセスにもとても意義があったと思っています。今後新たな技術に触れる際、何かトラブルが起きてももう怖くなさそうです。続いて、
gatsby-plugin-breakpoints
が便利だったので詳しく紹介していきます。
gatsby-plugin-breakpoints
の使い方詳しくはドキュメント(https://www.gatsbyjs.com/plugins/gatsby-plugin-breakpoints/) を参照していただきたいのですが、
gatsby-config.js
内にbreakPoints
を定義すれば各コンポーネントで手軽に使えます。僕は下のように
breakPoints
を定義しました。const breakPoints = { smartphone: "(max-width: 420px)", mobileWide: "(min-width: 421px)", wxga: "(min-width: 1280px)", mobile: "(max-width: 1023px)", pc: "(min-width: 1024px)", portrait: '(orientation: portrait)', }そして、使用したいファイル上で
import { useBreakpoint } from "gatsby-plugin-breakpoints" const Hoge = () => { const breakPoints = useBreakpoint() return ( <> {breakPoints.pc ? // PC用のコンポーネント : null } {breakPoints.mobile ? // モバイル用のコンポーネント : null } </> ) }のように、閲覧しているデバイスの画面サイズに応じて
return
するコンポーネントを切り替えることができます。
breakPointsの中には、{ pc: true, mobile: false, wxga: true, ... }このようにconfigで定義したbreakPointsを満たしているかどうかが
boolean
値で格納されているので、画面サイズに応じた条件処理を自由度高く書くことができました。その結果、CSSのメディアクエリと遜色ないレスポンシブ対応ページを
JavaScript
だけで実装することができました。JavaScript
だけでの実装にこだわってよかったなと思っています。Gatsby.jsでのWeb開発まとめ
- CSS in JSプラグインは
styled-components
をgatsby-plugin-styled-components
とセットで使う- レスポンシブ対応プラグインは専用の
gatsby-plugin-breakpoints
を使う- Gatsbyのサーバーサイドレンダリングに非対応のプラグインはまともに動作しないので注意!事前によく調べるべき
LPの開発を終えて
Gatsby.jsはサーバーサイドレンダリング起因のCSS崩壊や、有効なプラグインを調べてきてカスタマイズ・チューニングが必要なことなど、調整に手のかかるところがあるという欠点もありますが、それ以上に、
gatsby-image
による画像ファイルの最適化だったり、NetlifyやGitHubとの連携だったり、上で紹介しませんでしたがpages
にJSファイルを置けばルーティングまで勝手にやってくれることだったりと、Webサイト開発において優れた点が多いです。今後静的なWebサイトを開発する時も、今回得た知見をもとにGatsbyで開発したいなと思っています。
そして、インターンの今後のプロジェクトですが、LPと並行して、
- インターン先のHP https://quando.jp
- インターン先自社プロダクト SynQ Remote
- 鉄板加工工場オートメーション化プロジェクト Webアプリ開発(Vue.jsとDjango)
- 同プロジェクト用CNN(画像認識)モデル
なども任せてもらっているので、フロントエンドだけでなくバックエンド・機械学習など、フルスタックエンジニアを目指して様々な分野の技術に触れていきたいです。
最後に
https://www.wantedly.com/companies/quando
インターン先である株式会社クアンドでは、エンジニア・デザイナーさんを募集しています!
特にフロントエンド・バックエンド・インフラ・モバイルアプリ・UIデザインなどの分野で募集していますが、Webに限らず様々なプロジェクトをやっているので、分野関係なく純粋に技術が大好きな方の応募をお待ちしております!
- 投稿日:2020-09-16T17:11:16+09:00
ローカルに作ったJavascriptのプログラムをgithubの新規リポジトリにで管理する為のメモ
概要
技術検証用に作成したjavascriptのプログラムがある。色々試した更新を残しておくためにgithubのリポジトリに登録し管理することにしたので、その手順を記す。
手順
大まかな流れとして次のようになる。
- githubにリポジトリを作成する
- 検証作業を行ったローカルのディレクトリをgitリポジトリ化する
- ローカルのリポジトリのリモートリポジトリとしてgithubのリポジトリを設定する
- githubのリポジトリとローカルのリポジトリをマージする
- ローカルのリポジトリをpushする
githubにリポジトリを作成する
https://github.com/new にアクセスし、新しいリポジトリを作成する。
今回は個人的な学習用に作ったプログラムなので公開はせずPrivateとした。
- Initialize this repository with:はAdd a README fileとAdd .gitignore
- .gitignore template:はNodeを選択した。
ローカルのプロジェクトをgitリポジトリとして初期化する
検証用作業を行っていたディレクトリに移動し、同ディレクトリをgitリポジトリとして初期化する。
ちなみに、今回の検証用のディレクトリはnpm initされたディレクトリで、Node.jsのプロジェクト。$ git init # > Initialized empty Git repository in /Users/****/workspace/labo0/.git/ファイルをコミットする
ローカルのファイル群をコミットする。githubのリポジトリには既に.gitignoreファイルがあるので、同ファイルをローカルのリポジトリにコピーしてからコミットする方が余計なファイルをコミットせずに済むのかも。
リモートリポジトリとしてgithubのリポジトリを設定する
以下のコマンドでリモートを追加出来る。
$ git remote add origin https://github.com/****/labo0.git $ git ls-remote origin # > AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA HEAD # > AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA refs/heads/masterこのコマンドを見つけるよりも先に以下のコマンドを見つけ試したが失敗した。
「originというリモートは見つからない」とのことで、事前にoriginが存在していないとダメと言うことなんだと認識。$ git remote set-url origin https://github.com/****/labo0.git # > fatal: No such remote 'origin'githubのリポジトリをmergeする
リモートのorigin/masterをローカルのmasterブランチで追跡するように設定し、マージを実施する。
$ git branch --set-upstream-to=origin/master master # > Branch 'master' set up to track remote branch 'master' from 'origin'.$ git merge --allow-unrelated-histories # > Merge made by the 'recursive' strategy. # > .gitignore | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # > README.md | 1 + # > 2 files changed, 105 insertions(+) # > create mode 100644 .gitignore # > create mode 100644 README.md--set-upstream-to=origin/master master
git pull やgit push を行う際に、引数(<remote> <branch>)を省略しするために必要。
--allow-unrelated-histories
ローカルのリポジトリとgithubのリポジトリは無関係の独立したリポジトリ同士。それらを強制的にマージするためにはこのオプションが必要ということ?
補足 上記設定を行わずにpullやpushを実施た場合のメッセージ
$ git pull # > warning: no common commits # > remote: Enumerating objects: 4, done. # > remote: Counting objects: 100% (4/4), done. # > remote: Compressing objects: 100% (3/3), done. # > remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 # > Unpacking objects: 100% (4/4), done. # > From https://github.com/****/labo0.git # > * [new branch] master -> origin/master # > There is no tracking information for the current branch. # > Please specify which branch you want to merge with. # > See git-pull(1) for details. # > # > git pull <remote> <branch> # > # > If you wish to set tracking information for this branch you can do so with: # > # > git branch --set-upstream-to=origin/<branch> master$ git push origin master # > To https://github.com/****/labo0.git # > ! [rejected] master -> master (non-fast-forward) # > error: failed to push some refs to 'https://github.com/****/labo0.git' # > hint: Updates were rejected because the tip of your current branch is behind # > hint: its remote counterpart. Integrate the remote changes (e.g. # > hint: 'git pull ...') before pushing again. # > hint: See the 'Note about fast-forwards' in 'git push --help' for details.githubのリポジトリにpushする
$ git push
- 投稿日:2020-09-16T14:40:15+09:00
Gitのブランチに名前つける時は ” feat(git hubのイシュー番号) ”
自分用の備忘録。
閲覧した方で何か不備等見つけた方はコメントいただければと思います。使用しているのはWSLでUbuntu20.04
1.コマンド調べる時
サル先生のGit入門がわかりやすい。
↓ブランチ操作編へのリンク
https://backlog.com/ja/git-tutorial/reference/branch/2.いざブランチ切るとき
「git branch feat#3」(#3はgithubのissue番号)
て入力する。
シャープから始めたり、日本語入れたらうまくいかなかった
- 投稿日:2020-09-16T14:40:15+09:00
Gitのブランチに名前つける時は ” feat/(git hubのイシュー番号) ”
自分用の備忘録。
閲覧した方で何か不備等見つけた方はコメントいただければと思います。使用しているのはWSLでUbuntu20.04
1.コマンド調べる時
サル先生のGit入門がわかりやすい。
↓ブランチ操作編へのリンク
https://backlog.com/ja/git-tutorial/reference/branch/2.いざブランチ切るとき
「git branch feat/#3」(#3はgithubのissue番号)
て入力する。
シャープから始めたり、日本語入れたらうまくいかなかった
- 投稿日:2020-09-16T13:54:22+09:00
git mergeとrebaseの違い。ブランチを統合する方法。
git mergeとrebaseの違い。コミットを統合する方法。
gitのブランチを統合するときにgit mergeとgit rebaseコマンドが頻出する。
簡単に言うと、git mergeはブランチの統合。git rebaseはgit merge前にコミット履歴をきれいにする作業。
目次
git mergeとgit rebaseの違い
■git merge
元のブランチとトピックブランチを統合した新しいコミットを作成する方法。
トピックブランチのコミット履歴は残る。(枝分かれしたコミットがそのまま残る)
コマンドの実行は本流となるブランチで行う。(一般的にはmaster)
merge後のコミット履歴のイメージ(git公式ページより)
■git rebase
マージではなく、コミット履歴を移動したり修正、削除したりするコマンド。
マージ前にコミット履歴をきれいにする目的で使用する。
トピックブランチのコミット履歴のコピーを作成し、本流のブランチの先端に付け足す。
枝分かれの枝を根本からポッキっと追って、本流にくっつけるイメージ。
コマンドの実行はトピックブランチで行う。(一般的にはmaster以外)
rebase後のコミット履歴のイメージ(git公式ページより)
上の図からもわかるように、コミット履歴およびトピックブランチ(のポインタ)を移動するのでmaserは移動しない。
最終的に統合するには、mergeが必要。
トピックブランチとは?
派生(枝分かれ)したブランチのこと。
トピックブランチから枝分かれしたブランチをサブトピックブランチと呼んだりもする。
ブランチの名称------------- master \_________ topic \____ subtopic
git mergeの使い方
本流としたいブランチに移動して、トピックブランチを指定する。
・
git merge <トピックブランチ名>
┗ エディタが立ち上がる。コメントを入力・
git merge -m "コメント" <トピックブランチ名>
┗ 「-m」オプションを使えばエディタを立ち上げずにコメントの設定ができる。#本流のブランチに移動(ここではmaster) $ git checkout master #topicブランチをマージ $ git merge -m "first merge" topic Merge made by the 'recursive' strategy. main.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 main.js
#merge後のコミット履歴確認 $ git log --graph --oneline * 9ca1f24 (HEAD -> master) first merge |\ | * ac35267 (topic) create main.js * | 0547564 edit css |/ * 3915358 add h5枝分かれしたtopicブランチがmasterブランチに統合された。
▼補足(git mergeの詳細)
git mergeは3つのコミットから新しいコミットを作成している。例えば下記のようなmergeのコミット履歴の場合、merge後のコミットGは、以下3つから作成される。
(1) コミットF:topicとmasterの共通の祖先 (base/common)
(2) コミットC:masterのコミット(ours)
(3) コミットD:topicのコミット (theirs)A---B---C topic / \ D---E---F---G---H master
git rebaseの使い方
トピックブランチの統合(rebase & merge)
rebaseとは土台を完全に移行するという意味。
つまり、topicブランチの履歴をmasterに移行する。統合までの手順は以下となる。
(1) topicブランチに移動する
(2) rebaseで履歴をmasterに移行する
(3) masterブランチに移動する
(4) topicブランチをmergeする▼rebase & mergeのイメージ
rebase前A---B---C topic / D---E---F---G masterrebaseでtopicの履歴を移動topic D---E---F---G---A'---B'---C' mastermergeで統合D---E---F---G---A'---B'---C' master
実例で確認▼rebase前のtopicブランチの履歴は下記の通り。masterブランチは存在していない。
$ git log --graph --oneline * 51328ce (HEAD -> topic) create main.js * 0547564 edit css * 3915358 add h5
▼rebaseを実行するとtopicブランチがmasterブランチの前に移動している。#rebase実行 $ git rebase master First, rewinding head to replay your work on top of it... Applying: create main.js #ログ確認 $ git log --graph --oneline * 84df830 (HEAD -> topic) create main.js * f35df23 (master) edit css * 0547564 edit css * 3915358 add h5
mergeで統合すると、masterブランチがtopicブランチの位置に移動。綺麗なコミット履歴のみが残る。#mergeを実行するためmasterブランチに移動 $ git checkout master Switched to branch 'master' #merge実行 $ git merge -m "merge rabased branch" topic Updating f35df23..84df830 Fast-forward (no commit created; -m option ignored) main.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 main.js #ログを確認 $ git log --graph --oneline * 84df830 (HEAD -> master, topic) create main.js * f35df23 edit css * 0547564 edit css * 3915358 add h5
仕上げに不要になったtopicブランチを削除。$ git branch -d topic Deleted branch topic (was 84df830).
サブトピックブランチの統合 (rebase --onto)
rebaseの応用編として、サブトピックブランチのみを本流のブランチに統合することも可能。
つまり、枝分かれの更なる枝分かれ部分のみを、本流に移行する。
・
git rebase --onto master topic subtopic
サブトピックブランチの例H---I---J subtopic / E---F---G topic / A---B---C---D master実行後E---F---G topic / A---B---C---D---H'---I'---J' master subtopic--ontoの処理内容
git rebase --onto master topic subtopic
コマンドを実行したときの裏側の処理は以下となる。
- topicとsubtopicの共通祖先(G)までのコミットを一時保存
- 保存したコミット(H-I-J)を、順にmasterに付け替える。
付け替えるとき、中身は同じでも、過去のコミット履歴の流れが変わるので、新たなコミットが付与される(ハッシュ値が変わる)。
コミット履歴やメッセージを変更する
rebaseのオプションで「 -i(--interactive)」を指定するとコミット履歴やメッセージを対話型で変更することができる。
interactiveは対話形モードのこと。
・
git rebase -i <コミット>
┗ 指定したコミット以降のコメントを表示。
┗ 指定したコミットは含まない。
実例
▼以下のようなログのコメントを変更する。
$ git log --graph --oneline * 570184b (HEAD) create main.js * 7fa6a6f edit css * 0547564 edit css * 3915358 add h5 * 77f9b17 (tag: 2020-9-15, origin/master2) create style.css
▼コミットを指定し、それ以降(直近)のコミットを選択する。
コミットの指定方法はハッシュ値でもいいが、今回はタグ名で指定。#-iオプションでコミットを指定 $ git rebase -i 2020-09-15vimエディタpick 3915358 add h5 pick 0547564 edit css pick f35df23 edit css pick 84df830 create main.js # Rebase 77f9b17..84df830 onto 84df830 (4 commands) # # Commands: # p, pick <commit> = use commit # r, reword <commit> = use commit, but edit the commit message # e, edit <commit> = use commit, but stop for amending # s, squash <commit> = use commit, but meld into previous commit # f, fixup <commit> = like "squash", but discard this commit's log message # x, exec <command> = run command (the rest of the line) using shell # b, break = stop here (continue rebase later with 'git rebase --continue') # d, drop <commit> = remove commit # l, label <label> = label current HEAD with a name # t, reset <label> = reset HEAD to a labelvimエディタが自動で立ち上がる。ごちゃごちゃ書かれているが、6行目以降(#がある行)は補足情報なので無視していい。
pick
が現在選択中のコミットということ。これを実行したい内容に合わせて変更する。
rebase -iのオプション一覧
オプション 省略表記 内容 pick p 現在のまま(変更なし) reword r コミットメッセージを編集 edit e 指定したコミットまで残す(以降を消す) squach s 直前のコミットに統合する fixed f 直前のコミットに統合する。その際このコミットメッセージを消す exec x shellでコマンドを実行する break b 処理を中断する drop d コミットを削除する
▼pickを書き換える。
コミットメッセージを変更の場合はpickをr(reword)に。コミットを削除する場合はd(drop)に書き換える。vimエディタpick 3915358 add h5 r 0547564 edit css d f35df23 edit css r 84df830 create main.js再度vimエディタが立ち上がる。
vimエディタadd h5(*rebase -i*)
ログを確認。$ git log --oneline --graph * bfe2b20 (HEAD -> master) create main.js(*rebase -i*) * 64ccdee edit css(*rebase -i*) * 3915358 add h5 * 77f9b17 (tag: 2020-9-15, origin/master2) create style.css変更した内容が反映されている。
コミットの中身が変わるので、コミットを表すハッシュ値も変更となる。
困った時の対処法(--abort)
git mergeやrebaseでコンフリクトが発生したり、rebase -iのコミット履歴変更を元に戻したい場合は、
--abort
オプションをつけて実行する。abortは進行中の作業を強制中断する意味。
git merge --abort
git rebase --abort
- 投稿日:2020-09-16T11:38:15+09:00
git tagの使い方。コミットにタグ付して管理しやすくする方法。
git tagの使い方。コミットにタグ付して管理しやすくする方法。
git tagコマンドを使うとコミットに任意の名前(タグ)と注釈をつけることができる。
タグ名でそのコミットの詳細を参照することもできる。
目次
- git tagを使う上での注意点
- 現在のコミットにタグを設定
- 指定したコミットにタグを設定
- 注釈付きタグの設定(-a)
- 設定したタグの参照
- タグの削除(-d)
- タグの変更
- タグ、ハッシュ値、ブランチ、HEADについて
git tagを使う上での注意点
- 基本的にローカルのみ。ただのpushではリモートレポジトリにタグ名は同期しない
- リモートへのタグ追加:
git push --tags
- リモートのタグ削除:
git push <リモートレポジトリ名>:<タグ名>
- タグ名にスペースや:は使えない
- 一つのコミットに複数のタグを設定することができる
- タグ名の変更コマンドはない
- 変更方法:上書き, 削除して新しく設定する
git tagの設定方法
現在のコミットにタグを設定
git tag <タグ名>
#タグ名v1.0を設定 $git tag v1.0 #タグが設定されたか確認 $ git reflog 3915358 (HEAD -> master, tag: v1.0) HEAD@{0}: checkout: moving from ft1 to master指定したコミットにタグを設定
git tag <タグ名> <コミット>
コミットの指定は、ハッシュ値(SHA)、HEAD、ブランチ名で指定することが可能。
▼実例
以下のようなログの各コミットにタグを設定する場合
ログ設定前$ git reflog 3915358 (HEAD -> master) HEAD@{0}: checkout: moving from ft1 to master ac23875 (ft1) HEAD@{1}: commit: add main.js 4af9f09 HEAD@{2}: checkout: moving from master to ft1 3915358 (HEAD -> master) HEAD@{3}: commit: add h5 77f9b17 (origin/master2) HEAD@{4}: checkout: moving from ft1 to master 4af9f09 HEAD@{5}: checkout: moving from master to ft1タグの設定#ハッシュ値で指定 $ git tag 2020-9-15 77f9b17 #HEADで指定 $ git tag v2.0 HEAD^^^ $ git tag A-B-C HEAD@{2} #ブランチ名で指定 $ git tag v3.0 ft1$ git reflog 3915358 (HEAD -> master) HEAD@{0}: checkout: moving from ft1 to master ac23875 (tag: v3.0, ft1) HEAD@{1}: commit: add main.js 3915358 (HEAD -> master, tag: v2.0) HEAD@{2}: checkout: moving from master to ft1 3915358 (HEAD -> master) HEAD@{3}: commit: add h5 77f9b17 (tag: 2020-9-15, origin/master2) HEAD@{4}: checkout: moving from ft1 to master 4af9f09 (tag: A-B-C) HEAD@{5}: checkout: moving from master to ft1過去のコミットに遡ってタグを設定することができた。
注釈付きタグの設定(-a)
git tagのオプション「-a」を使うと注釈を設定することができる。
-aは--annotateの省略形。annotateは「注釈をつける」の意味。
・
git tag -a <タグ名>
┗ オプションで「-m」を指定しない場合、エディタが立ち上がる・
git tag -a <タグ名> -m "注釈の内容"
┗ 「-m」を使うと、コマンドラインで注釈を入力できる・
git tag -am "注釈の内容" <タグ名>
┗「-am」=「-a」+「-m」
┗ 注釈の内容を先に記述するタグ設定するコミットを指定する場合は、コマンド末尾で<コミット>を指定する。
#-a -mでタグ名(v1.0)と注釈を設定 $ git tag -a v1.0 -m "this is first commit" 5eeac88 # -amでタグ名(v1.1)と注釈を設定 $ git tag -am "2nd commit" v1.1 @@{12} #設定したタグを確認 $ git reflog 494777f (tag: v1.1) HEAD@{12}: commit: second ci 5eeac88 (tag: v1.0) HEAD@{13}: commit (initial): first ci #タグ名と注釈を確認 $ git tag -n v1.0 this is first commit v1.1 2nd commit
設定したタグの参照
タグの参照方法はいくつかある。
・
git tag
タグの一覧を表示する。the シンプル。
$ git tag 2020-9-15 A-B-C v1.0 v1.1 v2.0 v3.0・
git tag --column
1行で表示。bashの幅を取らない。
$ git tag --column 2020-9-15 A-B-C v1.0 v1.1 v2.0 v3.0・
git tag -l "パターン"
指定した書式に合致するタグのみを表示する。
$ git tag -l "v*" v1.0 v1.1 v2.0 v3.0パターンを指定しない場合(git tag -l)はgit tagと同じ。
・
git tag -n
注釈も表示。注釈が設定されていない場合は、コミットメッセージを表示する。
$ git tag -n 2020-9-15 create style.css A-B-C add h3 v1.0 this is first commit v1.1 2nd commit v2.0 add h5 v3.0 add main.js・
git tag -n "パターン"
指定したパターンに合致するタグ名と注釈を表示
$ git tag -n "v*" v1.0 this is first commit v1.1 2nd commit v2.0 add h5 v3.0 add main.js
タグの削除
git tag -d <タグ名>
「-d」(--delete) オプションを設定すればタグを削除できる。
複数のタグを削除することも可能。$ git tag -d v2.0 v3.0 Deleted tag 'v2.0' (was 3915358) Deleted tag 'v3.0' (was ac23875)
タグの変更
- タグ名を変更する(コミットはそのまま)
- タグを別のコミットに付け替える
タグ名を変更する(コミットはそのまま)
タグ名を変更する場合は、既存タグを削除してから新たに設定する必要がある。
git tag -d <旧タグ名>
git tag <新タグ名> <コミット>
既存タグを削除しないと、別名のタグが更についてしまう。(タグの複数設定が可能なため)
#変更前 ac23875 (tag: A-B-C, ft1) HEAD@{1}: commit: add main.js #タグ名を変更 ##タグを削除 $ git tag -d A-B-C Deleted tag 'A-B-C' (was ac23875) ##新しいタグを設定 $ git tag D-E-F ac23875 #タグの確認 $ git reflog ac23875 (tag: D-E-F, ft1) HEAD@{1}: commit: add main.js
タグを別のコミットに付け替える
タグ名の強制上書きを使う。
git tag -f <タグ名> <コミット>
#変更前 ac23875 (ft1) HEAD@{1}: commit: add main.js 4af9f09 (tag: A-B-C) HEAD@{2}: checkout: moving from master to ft1 #別のコミットに付け替え $ git tag -f A-B-C ft1 Updated tag 'A-B-C' (was 4af9f09) #変更後 ac23875 (tag: A-B-C, ft1) HEAD@{1}: commit: add main.js 4af9f09 HEAD@{2}: checkout: moving from master to ft1「-f」(--force)がない場合、重複するタグ名は書き込めない。
「-f」をつけた場合、元のタグを削除(-d)し、新たにタグを設定する処理となる。
以下2つの処理とイコール。
git tag -d <タグ名>
git tag <タグ名> <コミット>
タグ、ハッシュ値、ブランチ、HEADについて
補足ではあるが、タグ、ハッシュ値、ブランチ、HEADのいずれも、特定のコミットを指すポインタである。
つまり、タグ=ハッシュ値=ブランチ=HEADなので、git showやgit diffなどで指定する場合はどれで指定してもいい。
例ac23875 (tag: A-B-C, ft1) HEAD@{1}: commit: add main.js上記の場合、下記はいずれも同じコミットを指すポインタ。
・ハッシュ値: ac23875
・タグ名: A-B-C
・ブランチ名: ft1
・HEAD: HEAD@{1}ac23875 = A-B-C = ft1 = HEAD@{1} となる。
- 投稿日:2020-09-16T11:18:50+09:00
【Git】ローカルのブランチを削除しようとしたら「Cannot delete branch 'ブランチ名' checked out at...」とエラーが出た。
自分用のメモとして残します。
ブランチを削除しようとしたら、下記のようなエラーが表示された。
$ git branch -D hogeブランチ error: Cannot delete branch 'hogeブランチ' checked out at '作業フォルダパス'結論としては、削除しようとしているブランチが現在チェックアウトされており、自分自身が削除予定ブランチにいるため、エラーが表示された。
■やり方
1.とりあえず、マスターブランチに移動。
削除したいブランチ以外であればどこでもOK
git checkout master2.ブランチを削除
git branch -D 削除するブランチ #git branch --delete 削除するブランチ
- 投稿日:2020-09-16T00:10:53+09:00