- 投稿日:2020-09-07T23:03:56+09:00
.gitignoreに指定した対象はコミットできないのか?
git add .
で追加しても追加されない。
git add
した場合には追加できなとメッセージが表示される。% git add sample.html The following paths are ignored by one of your .gitignore files: sample.html Use -f if you really want to add them.ただし
-f
オプションを使うと追加できるようだ。
.gitignoreに指定したファイルを-f(--force)で追加するのは、追加してはいけないと設定しているのに、でも強制的に追加します!みたいな感じなので、かなりの割合でやらないほうが良いです。
git rm
は可能で、特に警告も出ません。
追加してはいけない設定にしたファイルを消すのは特に不自然ではなからでしょうね。% git rm sample2.html
- 投稿日:2020-09-07T22:38:54+09:00
バージョン管理のすゝめ
0.1. はじめに ver.0.1
元々は学内団体向けの記事として作成しましたが、入門者向けに幅広く使えそうなので公開します。
ゲーム制作でバックアップ撮らずに作業してたら、突然HDD死んでプロジェクトデータ消えた…みたいなことがありませんでしたか?
(僕は昔USBでやらかしました… 死にたくなりました)
このような悲劇的な事故を起こさないためにも日頃からバックアップをとる習慣をつけましょう。1. はじめに ver.1.0
じゃあバックアップはどうやって取ろうか?
一定時間ごとにプロジェクトフォルダ圧縮して、ファイル名変えて…こんなことやってるともれなくファイル名が悲惨なことになるのでやめましょう。
- Backup
- HogeProject20200904_01
- HogeProject20200904_02
- HogeProject20200906_Final
- HogeProject20200906_Final_02
- HogeProject20200906_Final_Final
- HogeProject20200906_Final_Final_Fin
- HogeProject20200906_Final_Final_Fin_02
キリがなくなるのでやめます…
今までこういう命名して苦労してきたって人も少なくないと思います。
このような無駄な労力を避けるためにも、次に説明するバージョン管理ツールを採用するようにしましょう。2. バージョン管理ツールとは
バージョン管理ツール
(version control system, 以下vcs)とはファイル群の変更履歴を管理するためのツールです。
当たり前のように聞こえるかもしれませんが、大事なのは変更履歴を差分を取って管理するということです。
算数あるいは数学で学んだ樹形図のように変更履歴を記録してくれます。
ある段階まで遡ったり、パラレルワールドのように用途に合わせて分岐させることも可能です(詳細は後程)。
またはじめに
で書いたダメな例のようにバックアップを取るたびにすべてコピーしていては、容量が大変なことになりますよね?
vcsを導入することでバックアップ時の容量削減にも繋がります。ここまでvcsのメリットについて紹介してきました。次は具体的なツールの説明をしていきます。
3. Git
おそらく今世の中で最も主流のvcsです。次に説明するSubversionなどと比較して
分散型
と位置付けられています(最初は覚えなくていいです)。3.1. 下準備
使用にはPCにGitを導入する必要があります。
Windowsの人はGit for Windowsのリンクに飛んでダウンロードしましょう。
Macの人は元々入っているので何もしなくて大丈夫です。以下Windowsを基準に説明していきます。Macの場合の相違点は適宜説明していきます。
Gitはコマンドを実行することで操作していきます。
最初はよくわからない文字列ばかりで難しく思うかもしれませんが、実際覚えることは少ないので安心してくださいね。
なお今回はUnityを想定して説明していきます。ここからの作業はWindowsなら
Git CMD
、Macならターミナル
を開いて作業してください(以下ターミナルと呼びます)。
まずターミナルでAssetsフォルダがある階層を開きます。
例えば写真のプロジェクトはG:/Develop/Unity/GitSampleにあるので、次のコマンドで移動できます。
cd/d G:/Develop/Unity/GitSample
3.2. バージョン管理しないリスト (.gitignore)
Unityプロジェクトを構成するファイル一覧が掲載されています。
このうち全てをバージョン管理する必要はないので、バージョン管理しないファイルリストを作成します。
.gitignoreというファイルを作成し、その中に記述します。ここでは一般的なUnityプロジェクトで使用されるものを掲載しておきます。
導入する外部ツールなどに応じて適宜変更してください。
.gitignore (例)
/[Ll]ibrary/ /[Tt]emp/ /[Oo]bj/ /[Bb]uild/ /[Bb]uilds/ /Assets/AssetStoreTools* # Visual Studio cache directory .vs/ # vscode .vscode/ # Autogenerated VS/MD solution and project files ExportedObj/ *.csproj *.unityproj *.sln *.suo *.tmp *.user *.userprefs *.pidb *.booproj *.svd *.pdb *.opendb # Unity3D generated meta files *.pidb.meta *.pdb.meta # Unity3D Generated File On Crash Reports sysinfo.txt # Builds *.apk *.unitypackage # OS generated .DS_Store .DS_Store? ._* .Spotlight-V100 .Trashes Icon? ehthumbs.db Thumbs.db #log files, for some plugins *.log #python bytecode cache, for some plugins. *.pyc
3.3. リポジトリ初期化 (git init)
次にこの階層(以下ディレクトリと呼びます)をGitで管理するために
初期化
します。git initAssetsフォルダがあるディレクトリまで移動し、上のコマンドを実行しましょう。
このコマンドによりディレクトリがGitのために初期化されます。
Gitが使える状態のディレクトリをGitリポジトリと呼びます。3.4. Git管理下に追加 (git add)
これでGitを使う準備ができました。次に管理する
ファイルを登録
します。git add .
このコマンドを実行することで、.gitignoreに記載されていないすべてのファイルがGitの管理下に追加されます。
3.5. コミット (git commit)
次はいよいよ変更履歴を記録していきます。
git commit -m "<commit message>"
<commit message>
にはコミットの理由やファイルの状態などを書き残しておきます (<>は不要です)。
後々見返したときにわかりやすくするためです。
このコマンドを実行すると現段階での変更情報が保存されます。3.6. リモートリポジトリの追加 (git remote add)
ここまでを実行することで、自分のPC上には変更履歴が記録されるようになっています。
Gitでは外部サーバー上にリモートリポジトリ
を追加し、変更履歴を共有することができます。
外部サービスにはいろいろな種類がありますが、今回はGitHub
を利用します。
New
を押して上の写真のように設定します。
Create repository
を押し、リポジトリを作成します。続いてターミナルでの作業に戻ります。
リモートリポジトリをローカル上のリポジトリで追加するには以下のコマンドを実行します。git remote add origin <URL>URLには上の写真に記載されているURLを使用します (<>は不要です)。
3.7. リモートに反映 (git push)
続いて今追加したリモートリポジトリにローカルリポジトリの変更を共有します。
git push origin masterこのコマンドを実行することでリモートリポジトリにコミットが反映されます。
3.8. 複数人での共有
GitHubには
Collaborator
という機能があり、これを利用することで複数人で一つのリポジトリにpushすることができます。
リポジトリのSettings -> Manage Accessからユーザーを追加できます。詳細は実演で説明します。
リモートリポジトリを自分のPCに複製するにはクローンします。git clone <URL>URLには上のリモートリポジトリの追加で使用したものと同じものです。
3.9. 他人の変更をローカルに反映 (git pull)
他人がpushしたリポジトリへの変更を取り入れるには以下のコマンドを使います。
git pull origin master3.10. クライアントソフトの利用
ここまでコマンドによる操作でGitを使用してきました。
コマンド操作と同様の行程をGUIで可能にしたソフトがクライアントソフトです。
以下いくらかツールを紹介します。
GitHub Desktop
- GitHubの公式クライアントソフトです。
Source Tree
- GitHubだけでなくBitBucketやGitLabなどにも対応しています。
3.11. [発展] ブランチ (branch)
ブランチとは木の枝という意味ですが、Gitではコミットしたポイントから複数のラインで並行して編集ラインを立てることができます。
またそれらを任意のタイミングで統合(マージ)することも可能です。
正しく使うと機能ごとやリリースごとにブランチを切ることで強力な効果を発揮しますが、適当にやっても無駄に面倒になるだけなので使う前には勉強しておくことをお勧めします。
興味がある人はGit-flow
などで検索してみてもいいかもしれません。3.12. [発展] バイナリファイルに注意
最初に説明した通り、差分を取って管理することで時間や容量を抑えています。
ここで注意が必要で、テキストファイルは差分が取れますがバイナリファイルは差分が取れません。
よってバイナリファイルは変更が入るたびに丸ごと管理するようになっています。
このためバイナリファイルの数や容量によってはプッシュやプルに時間がかかる
ことも出てきます。
あまりに時間がかかるようであれば、バイナリファイルはGit以外で管理するのがいいかもしれません。4. Subversion
SubversionもGitと同様、バージョン管理ツールの一つです。
Gitと比較して集中型
と位置付けられています。
Subversionもコマンドで扱うことができますが、こちらはクライアントソフトを利用していきたいと思います。
Windowsの人はTortoise SVN、Macの人はSnail SVNがおすすめです。
Gitと比較した際に特徴的な相違点はリポジトリがリモート一つ
のみであることです。
GitもSubversionもローカルにコピーして作業した後リモートに反映するという流れは同じです。
ただしGitはローカルにコミットした後リモートにプッシュするのに対し、Subversionにはローカルリポジトリはただのコピーであり、直接リモートリポジトリにコミット
するようになっています。基本的な使い方はGitと変わらないので、ここでは相違点を中心に説明します。
4.1. コミット&リモートへ反映 (commit)
前述のとおりSubversionではリモートリポジトリに直接コミットするようになっています。
ですのでGitのようにコミットしてからプッシュするのではなく、コミットするだけでリモートに反映
することができます。4.2. リポジトリをローカルにコピー (checkout)
Gitではリモートリポジトリからローカルリポジトリを作成する際cloneしていました。
Subversionではcheckout
となっています。尤もgit cloneはローカルにもオリジナルのリポジトリを作成しているのに対し、Subversionではあくまでコピーなので正確には全く同じではないです。
4.3. リモートの変更を反映 (update)
Gitでpullでしたが、Subversionでは
update
になっています。
力尽きたのでこの辺にしておきます。
Subversion編、要望あれば追記するかもです。
- 投稿日:2020-09-07T22:24:51+09:00
クジラとネコの親子プログラミング - Docker for Windowsを使ってScratch3.0のオリジナル拡張機能を試してみよう。
親子プログラミングはGitとNode.jsが使えることが前提になっている?
小学校でのプログラミング教育の必須化に伴って、子供たちがScratch 3.0に触れる機会も増えるかと思います。そんな中、ブロックをくっつけるだけのお遊びツールだとあなどっていると、次のような連載が始まりました。
「親子でできる!Scratch と AWS を使った "ものづくり" 体験 - 1. 準備 〜 疎通確認編」
2020-09-01
How to be a Developer
金澤 圭この連載の「2. 作業の前提について」で、衝撃的な次の一文があります。
PC に Git と Node.js がインストールされている必要があります。
保護者の方も、GitやNode.jsを当たり前のようにインストールしなければいけない時代になりましたね。でも、安心してください。Dockerという便利なツールがありますので、簡単に開発環境を整えることができます。
本記事では、Webベースの統合開発環境である
code-server
とScratch 3.0 拡張機能の開発と実行に必要なソースコード(scratch-vm/scratch-gui
)を詰め合わせたDockerコンテナ(jprad/s3coder
)を使って、Windowsパソコン上で、Scratch 3.0 GUI
サーバーを起動できるようにします。
後半では、「Scratch 3.0の拡張機能を作ってみよう」を参考にして、拡張機能を追加します。拡張機能を追加して、Scratch 3.0 GUIでコーディング
必要なもの
- Windows 10 パソコン
- Docker Desktop on Windows または Docker Desktop on Windows Home
Windows 10 パソコンにDockerをインストールしてください。Dockerのインストール方法は、リンク先や各種記事を参照してください。
セットアップと起動
Dockerイメージ(
jprad/s3coder
)を元にDockerコンテナを起動し、Scratch 3.0 GUI
サーバーをWindowパソコンで実行できるようにします。1. 共有フォルダの作成とDockerコンテナの初回起動
Windows 10 で、コマンドプロンプトを起動し、次の一連のコマンドを入力します。
コマンドプロンプト.cmdcd c:\ mkdir scratch-ws docker run --name s3coder -d -p 8080:8080 -p 8601:8601 ^ -v C:/scratch-ws:/home/coder/s3/scratch-ws -e PASSWORD=password ^ jprad/s3coder /home/coder/s3 REM docker run ... のコマンドが長いので「^(キャレット)」で改行しています。
C\scratch-ws
フォルダは、Dockerコンテナにマウントされる共有フォルダです(/home/coder/s3/scratch-ws)。
docker run
コマンドを開始すると、必要なDockerイメージ(合計:844.17 MB)のダウンロードが始まり、Dockerコンテナが起動されます(コンテナ名:s3coder
)。Dockerコンテナの初回起動時に、共有フォルダへのアクセスを許可するかどうかの確認通知が表示されますので、
[Share it]
で許可します。2.code-severへのログインとScratch 3.0 GUIの起動
Dockerコンテナの起動完了後、
code-server
( http://localhost:8080 ) へアクセスし、ログインします(パスワードは、password
です)。統合開発環境が開きますので、Dockerイメージに同梱されているscratch-gui
を起動します。起動方法が構成ファイル(./s3/.vscode/launch.json)に設定されていますので、クリック操作のみで起動できます。scratch-gui
の起動完了後、Scratch 3.0 GUI
( http://localhost:8601 ) へアクセスすると、公式ページとは少しばかり異なっていますが、使い慣れたScratch 3.0
でのコーディングが行えます。手順
1.code-server
( http://localhost:8080 ) へアクセスする。
2. パスワードにpassword
と入力し、[SUBMIT]
ボタンをクリックし、ログインする。
3.[Run (Ctrl + Shift + D)]
アイコンをクリックする。
4. ドロップダウンリストで'Run Scratch 3.0 GUI'
(既定)を選択する。
5.[Start Debuging]
アイコンをクリックする。
6.[TERMINAL]
タブをクリックし、ビルド完了後の'Compiled successfully'
が表示されるのを待つ。
7.Scratch 3.0 GUI
( http://localhost:8601 ) へアクセスする。3.停止・再開
scratch-guiの再開・停止
scratch-guiを停止せずに再開するには、coder-serverの[Restart (Ctrl+Shift+F5)]
アイコンをクリックします。
scratch-guiを停止するには、code-serverの[Stop (Shift+F5)]
アイコンをクリックします。scratch-guiの開始
[Run (Ctrl + Shift + D)]
アイコンをクリックする。- ドロップダウンリストで
'Run Scratch 3.0 GUI'
(既定)を選択する。[Start Debuging]
アイコンをクリックする。[TERMINAL]
タブをクリックし、ビルド完了後の'Compiled successfully'
が表示されるのを待つ。Dockerコンテナの停止
コマンドプロンプトで次のコマンドを実行するとDockerコンテナ(コンテナ名:s3coder
)が停止します。コマンドプロンプト.cmddocker stop s3coderDockerコンテナの再開
コマンドプロンプトで次のコマンドを実行するとDockerコンテナ(コンテナ名:s3coder
)が再開します。コマンドプロンプト.cmddocker start s3coder拡張機能の開発
Scratch 3.0 Extensions の開発に関する情報には、次のようなものがあります。
- 「子供の科学 2020年9月号, p.p.66-69, ジャバスクリプトでスクラッチを拡張しよう」
子供向けの月刊誌の記事です。- 「Scratch を改造しよう」
Strecth3として、Scratch3.0で機械学習をプログラミングできる開発環境を提供する石原 淳也(いしはら じゅんや)氏の有償コンテンツです(一部無料公開あり)。- 「Scratch 3.0 Extensions」
LLK公式の拡張機能に関するページです。- 「Scratch 3.0の拡張機能を作ってみよう」
Scratch 3.0の拡張機能の作り方をその下準備から説明しています。ここでは、「Scratch 3.0の拡張機能を作ってみよう」を参考にログを出力する拡張機能(ブロック)を実装(コピペ)してみます。
拡張機能に必要なファイル
拡張機能(
s3coder_newblocks
)を実装するには、次のファイルを追加・編集します。scratch-vm
# フォルダ ファイル 追加 編集 説明 1 scratch-vm/src/extensions/s3coder_newblocks index.js 〇 拡張機能( newblocks
)の本体です。2 scratch-vm/src/extension-support extension-manager.js 〇 追加した拡張機能( s3coder_newblocks
)をbuiltinExtensions
に追加登録します。scratch-gui
# フォルダ ファイル 追加 編集 説明 1 scratch-gui/src/lib/libraries/extensions/s3coder_newblocks newblocks.png 〇 600x372ピクセルのPNG形式ファイルです。拡張機能の選択時にバナーとして表示されます。 2 scratch-gui/src/lib/libraries/extensions/s3coder_newblocks newblocks-small.png 〇 80x80ピクセルのPNG形式ファイルです。ブロックのアイコンとして表示されます。 3 scratch-gui/src/lib/libraries/extensions index.js 〇 PNG形式ファイルの読込定義と拡張ブロックの定義を設定します。 scratch-vm での実装
scratch-vmで、拡張機能そのものを実装します。
フォルダ作成
拡張機能用のフォルダを次の手順で作成します。
code-server
のEXPLORERで、s3/scratch-vm/src/extensions
フォルダを選択します。- 右クリックで、コンテキストメニューから
New Folder
を選択し、's3coder_newblocks'
フォルダを作成します。index.jsファイルの実装
次の手順で、
index.js
ファイルを実装します。
- 作成した
's3coder_newblocks'
フォルダで右クリックし、New File
を選択し、ファイル名をindex.js
とします。- 「Scratch 3.0の拡張機能を作ってみよう/基本の書式 - 拡張機能の追加」から
index.js
のソースコードをコピー&ペーストします。
index.js
index.jsconst ArgumentType = require('../../extension-support/argument-type'); const BlockType = require('../../extension-support/block-type'); const Cast = require('../../util/cast'); const log = require('../../util/log'); /** * Icon svg to be displayed at the left edge of each extension block, encoded as a data URI. * @type {string} */ // eslint-disable-next-line max-len const blockIconURI = 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgdmlld0JveD0iMCAwIDQwIDQwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48ZyBpZD0iSUQwLjA4NjgyNDQzOTAwMDMzODMyIiB0cmFuc2Zvcm09Im1hdHJpeCgwLjQ5MTU0NjY2MDY2MTY5NzQsIDAsIDAsIDAuNDkxNTQ2NjYwNjYxNjk3NCwgLTY0LjUsIC03Ny4yNSkiPjxwYXRoIGlkPSJJRDAuNTcyMTQ2MjMwMzc3MjU2OSIgZmlsbD0iI0ZGOTQwMCIgc3Ryb2tlPSJub25lIiBkPSJNIDE4OCAxNDEgTCAyNTAgMTQxIEwgMjUwIDIwMyBMIDE4OCAyMDMgTCAxODggMTQxIFogIiB0cmFuc2Zvcm09Im1hdHJpeCgxLjI4NzkwMzMwODg2ODQwODIsIDAsIDAsIDEuMjg3OTAzMzA4ODY4NDA4MiwgLTExMC45LCAtMjQuNCkiLz48cGF0aCBpZD0iSUQwLjYzODMzNjEzNTA3NDQ5NjMiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIGQ9Ik0gMTk2IDIwNCBDIDE5NiAyMDQgMTkyLjcwNiAxOTAuMDU4IDE5MyAxODMgQyAxOTMuMDc0IDE4MS4yMzYgMTk1Ljg4NiAxNzguNDU4IDE5NyAxODAgQyAyMDEuNDU1IDE4Ni4xNjggMjAzLjQ0MyAyMDMuNzU0IDIwNiAyMDEgQyAyMDkuMjExIDE5Ny41NDIgMjEwIDE2NiAyMTAgMTY2ICIgdHJhbnNmb3JtPSJtYXRyaXgoMSwgMCwgMCwgMSwgLTU3LCAxNS44KSIvPjxwYXRoIGlkPSJJRDAuNzU4NzMwMzU2NTgxNTA5MSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgZD0iTSAyMTUgMTY5IEMgMjE1IDE2OSAyMTguMzY3IDE2OS41MzQgMjIwIDE3MCBDIDIyMC43MTYgMTcwLjIwNSAyMjEuMjc4IDE3MC44MTkgMjIyIDE3MSBDIDIyMi42NDYgMTcxLjE2MiAyMjMuMzY4IDE3MC43ODkgMjI0IDE3MSBDIDIyNC40NDcgMTcxLjE0OSAyMjUgMTcyIDIyNSAxNzIgIiB0cmFuc2Zvcm09Im1hdHJpeCgxLCAwLCAwLCAxLCAtNTcsIDE1LjgpIi8+PHBhdGggaWQ9IklEMC4yNDM2NzMwNzMxMjc4NjU4IiBmaWxsPSJub25lIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBkPSJNIDIyNyAxNTQgQyAyMjcgMTU0IDIxOC41NTUgMTQ3Ljg5MCAyMTcgMTUxIEMgMjEyLjM0NSAxNjAuMzEwIDIxMS4yODkgMTcxLjczMyAyMTMgMTgyIEMgMjEzLjYxMiAxODUuNjcyIDIyMyAxODcgMjIzIDE4NyAiIHRyYW5zZm9ybT0ibWF0cml4KDEsIDAsIDAsIDEsIC01NywgMTUuOCkiLz48cGF0aCBpZD0iSUQwLjc5MzkzOTQ4MTk1NTAyMTYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIGQ9Ik0gMTc1IDIwMC41MDAgQyAxNzUgMjAwLjUwMCAxNjkuODA1IDIyMS45MTMgMTcxIDIyMi43NTAgQyAxNzIuMTk1IDIyMy41ODcgMTc4Ljc5NSAyMDUuMjk1IDE4Mi41MDAgMjA1Ljc1MCBDIDE4NS45MjAgMjA2LjE3MCAxODEuODU5IDIyNC41MDAgMTg1LjI1MCAyMjQuNTAwIEMgMTg5LjIxMyAyMjQuNTAwIDE5Ny4yNTAgMjA1Ljc1MCAxOTcuMjUwIDIwNS43NTAgIi8+PC9nPjwvc3ZnPg=='; /** * Icon svg to be displayed in the category menu, encoded as a data URI. * @type {string} */ // eslint-disable-next-line max-len const menuIconURI = 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgdmlld0JveD0iMCAwIDQwIDQwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48ZyBpZD0iSUQwLjA4NjgyNDQzOTAwMDMzODMyIiB0cmFuc2Zvcm09Im1hdHJpeCgwLjQ5MTU0NjY2MDY2MTY5NzQsIDAsIDAsIDAuNDkxNTQ2NjYwNjYxNjk3NCwgLTY0LjUsIC03Ny4yNSkiPjxwYXRoIGlkPSJJRDAuNTcyMTQ2MjMwMzc3MjU2OSIgZmlsbD0iI0ZGOTQwMCIgc3Ryb2tlPSJub25lIiBkPSJNIDE4OCAxNDEgTCAyNTAgMTQxIEwgMjUwIDIwMyBMIDE4OCAyMDMgTCAxODggMTQxIFogIiB0cmFuc2Zvcm09Im1hdHJpeCgxLjI4NzkwMzMwODg2ODQwODIsIDAsIDAsIDEuMjg3OTAzMzA4ODY4NDA4MiwgLTExMC45LCAtMjQuNCkiLz48cGF0aCBpZD0iSUQwLjYzODMzNjEzNTA3NDQ5NjMiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIGQ9Ik0gMTk2IDIwNCBDIDE5NiAyMDQgMTkyLjcwNiAxOTAuMDU4IDE5MyAxODMgQyAxOTMuMDc0IDE4MS4yMzYgMTk1Ljg4NiAxNzguNDU4IDE5NyAxODAgQyAyMDEuNDU1IDE4Ni4xNjggMjAzLjQ0MyAyMDMuNzU0IDIwNiAyMDEgQyAyMDkuMjExIDE5Ny41NDIgMjEwIDE2NiAyMTAgMTY2ICIgdHJhbnNmb3JtPSJtYXRyaXgoMSwgMCwgMCwgMSwgLTU3LCAxNS44KSIvPjxwYXRoIGlkPSJJRDAuNzU4NzMwMzU2NTgxNTA5MSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgZD0iTSAyMTUgMTY5IEMgMjE1IDE2OSAyMTguMzY3IDE2OS41MzQgMjIwIDE3MCBDIDIyMC43MTYgMTcwLjIwNSAyMjEuMjc4IDE3MC44MTkgMjIyIDE3MSBDIDIyMi42NDYgMTcxLjE2MiAyMjMuMzY4IDE3MC43ODkgMjI0IDE3MSBDIDIyNC40NDcgMTcxLjE0OSAyMjUgMTcyIDIyNSAxNzIgIiB0cmFuc2Zvcm09Im1hdHJpeCgxLCAwLCAwLCAxLCAtNTcsIDE1LjgpIi8+PHBhdGggaWQ9IklEMC4yNDM2NzMwNzMxMjc4NjU4IiBmaWxsPSJub25lIiBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBkPSJNIDIyNyAxNTQgQyAyMjcgMTU0IDIxOC41NTUgMTQ3Ljg5MCAyMTcgMTUxIEMgMjEyLjM0NSAxNjAuMzEwIDIxMS4yODkgMTcxLjczMyAyMTMgMTgyIEMgMjEzLjYxMiAxODUuNjcyIDIyMyAxODcgMjIzIDE4NyAiIHRyYW5zZm9ybT0ibWF0cml4KDEsIDAsIDAsIDEsIC01NywgMTUuOCkiLz48cGF0aCBpZD0iSUQwLjc5MzkzOTQ4MTk1NTAyMTYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIGQ9Ik0gMTc1IDIwMC41MDAgQyAxNzUgMjAwLjUwMCAxNjkuODA1IDIyMS45MTMgMTcxIDIyMi43NTAgQyAxNzIuMTk1IDIyMy41ODcgMTc4Ljc5NSAyMDUuMjk1IDE4Mi41MDAgMjA1Ljc1MCBDIDE4NS45MjAgMjA2LjE3MCAxODEuODU5IDIyNC41MDAgMTg1LjI1MCAyMjQuNTAwIEMgMTg5LjIxMyAyMjQuNTAwIDE5Ny4yNTAgMjA1Ljc1MCAxOTcuMjUwIDIwNS43NTAgIi8+PC9nPjwvc3ZnPg=='; /** * Class for the new blocks in Scratch 3.0 * @param {Runtime} runtime - the runtime instantiating this block package. * @constructor */ class Scratch3NewBlocks { constructor (runtime) { /** * The runtime instantiating this block package. * @type {Runtime} */ this.runtime = runtime; //this._onTargetCreated = this._onTargetCreated.bind(this); //this.runtime.on('targetWasCreated', this._onTargetCreated); } /** * @returns {object} metadata for this extension and its blocks. */ getInfo () { return { id: 'newblocks', name: 'New Blocks', menuIconURI: menuIconURI, blockIconURI: blockIconURI, blocks: [ { opcode: 'writeLog', blockType: BlockType.COMMAND, text: 'log [TEXT]', arguments: { TEXT: { type: ArgumentType.STRING, defaultValue: "hello" } } }, { opcode: 'getBrowser', text: 'browser', blockType: BlockType.REPORTER } ], menus: { } }; } /** * Write log. * @param {object} args - the block arguments. * @property {number} TEXT - the text. */ writeLog (args) { const text = Cast.toString(args.TEXT); log.log(text); } /** * Get the browser. * @return {number} - the user agent. */ getBrowser () { return navigator.userAgent; } } module.exports = Scratch3NewBlocks;extension-manager.jsファイルの変更
scratch-vm/src/extension-support
フォルダのextension-manager.js
ファイルを開き、builtinExtensions
に、次のように拡張機能(s3coder_newblocks
)を追加登録します。
※カンマで区切ることを忘れないでください。extension-manager.jsconst builtinExtensions = { ... gdxfor: () => require('../extensions/scratch3_gdx_for'), newblocks: () => require('../extensions/s3coder_newblocks'), };scratch-gui での設定
scratch-guiで、拡張機能を選択できるように設定します。
フォルダ作成
画像保存用のフォルダを次の手順で作成します。
code-server
のEXPLORERで、s3/scratch-gui/src/lib/libraries/extensions
フォルダを選択します。- 右クリックで、コンテキストメニューから
New Folder
を選択し、's3coder_newblocks'
フォルダを作成します。画像ファイル
画像ファイルをダウンロードし、作成したフォルダへ保存します。
- 2つの画像ファイルをダウンロードし、
C:\scratch-ws
フォルダへ保存します。code-server
のEXPLORERで、s3/scratch-ws
フォルダを開き、2つの画像ファイルを選択し、右クリックでコンテキストメニューからCopy
します。s3/scratch-gui/src/lib/libraries/extensions/s3coder_newblocks
フォルダを選択し、右クリックでコンテキストメニューからPaste
します。index.jsファイルの設定
s3/scratch-gui/src/lib/libraries/extensions
フォルダのindex.js
ファイルを開き、次のように拡張機能の設定を行います。これにより、Scratch 3.0 GUI
の拡張機能の追加で、拡張機能を選択できるようになります。index.js... import gdxforConnectionSmallIconURL from './gdxfor/gdxfor-small.svg'; import newblocksImage from './s3coder_newblocks/newblocks.png'; import newblocksInsetImage from './s3coder_newblocks/newblocks-small.png'; export default [ ... ), helpLink: 'https://scratch.mit.edu/vernier' }, { name: ( <FormattedMessage defaultMessage="New Blocks" description="Name for the 'New Blocks' extension" id="gui.extension.newblocks.name" /> ), extensionId: 'newblocks', iconURL: newblocksImage, insetIconURL: newblocksInsetImage, description: ( <FormattedMessage defaultMessage="New extension" description="Description for the 'New Blocks' extension" id="gui.extension.newblocks.description" /> ), featured: true }, ];動作確認
scratch-gui
を開始し、Scratch 3.0 GUI
を開きなおすと、「拡張機能を追加」で、新しい拡張機能を選択できます。
logブロック
を実行すると、ブラウザのConsoleにhello
と出力されます。おわりに
- Dockerイメージ(jprad/s3coder)を使って、Scratch 3.0 Extentionsの開発環境と動作環境を構築しました。
- 「Scratch 3.0の拡張機能を作ってみよう」を参考にして、拡張機能を追加しました。
【メモ】Dockerイメージの作成
dos.cmdcd c:\ mkdir scratch-ws docker run -it -p 8080:8080 -p 8601:8601 -v C:/scratch-ws:/home/coder/s3/scratch-ws -e PASSWORD=password codercom/code-server /home/coder/s3http://localhost:8080/ へアクセス
sudo apt-get update -y sudo apt-get install -y nodejs npm sudo npm install -g npmsudo chown -R coder:coder /home/coder/s3 git clone --depth 1 https://github.com/llk/scratch-vm.git git clone --depth 1 https://github.com/llk/scratch-gui.git cd scratch-vm npm ci sudo npm link cd ../scratch-gui npm ci sudo npm link scratch-vmnpm start --->> [Ctrl]+[C]で中断http://localhost:8601/ へアクセス
- scratch-guiのポート
ENV環境変数で設定可能Dockerfile の記述
docker build -t test-image . docker run --name test-container -it -p 8080:8080 -p 8601:8601 -v C:/scratch-ws:/home/coder/s3/scratch-ws -e PASSWORD=password test-image /home/coder/s3
- 投稿日:2020-09-07T22:13:05+09:00
stdout is not a ttyに叱られる
完全に自分用の健忘録です
Git Bash(ver2.28)で実行しようとした際に、
$ node hogehuga.js stdout is not a ttyと叱られてしまった。悲しい。
原因はMinTTYのアレです。大体winptyを先頭につければ解決すると思ってたけど、今回は解決しなかった。
Gitを再インストールしてもダメ。5分くらい悩んで、拡張子をつけたら動いた。
$ node.exe hogehuga.js以下参考
https://github.com/mintty/mintty/wiki/Tips#inputoutput-interaction-with-alien-programs
- 投稿日:2020-09-07T21:50:16+09:00
【Git】別のブランチにpushしたいとき
- 投稿日:2020-09-07T21:09:26+09:00
【備忘録】はじめてのGit環境構築 #2
前置き
前回の記事では,Gitの環境構築を行った。
今回はGitとGitHubの連携方法について,簡単にまとめていこうと思う。環境
OS:Windows10
Git:2.28.0GitHubアカウントの作成
GitHubを利用するには,まずはアカウントを作成する必要がある。
まずは,GitHubにアクセス。
[Username],[Email],[Password]をそれぞれ入力し,「Sign up for GitHub」をクリック。
その後,表示される画面に従って登録を進める。
(※特に複雑なことを聞かれたりはしないので省略。)リポジトリの作成
登録が完了し,ログインしたら画面の右上付近にある「+」ボタンをクリック。
更にその中にある,「New repository」をクリック。
リポジトリの作成画面に遷移出来たら,「Repository name」に好きなリポジトリ名を入力する。
公開設定について選べるので今回は「Public(公開)」を選択。
「Add a README file」にチェックを入れるとリポジトリ内にREADMEファイルが作成される。
「Create repository」をクリック。
リポジトリが無事作成されると,以下のような画面が表示される。
「Code」をクリックすると,作成したリモートリポジトリのリンクが表示されるのでメモしておく。
※「https:://github.com/ユーザ名/リポジトリ名.git」みたいなリンク
Gitとの連携
Gitで管理するディレクトリを作成していく。
まず,GitBushを起動。
以下コマンドを実行する。
$ mkdir Qiita_test $ cd Qiita_test
そうするとディレクトリが作成される。
作成したディレクトリをGitで管理出来るよう,「init」コマンドを実行する。$ git init「init」出来たら,先程GitHubで作成した,リモートリポジトリのURLをコピーし,以下コマンドを実行する。
$ git remote add origin "https:://github.com/ユーザ名/リポジトリ名.git"プッシュ先の指定が出来たので,ファイルを作成し,コミットする。
$ touch test.py $ git add test.py $ git commit -m "Create test.py" $ git push origin master
すると,上記のように,エラーが発生する場合がある。
どうやら,リモートリポジトリとローカルリポジトリの最新情報が異なっていることが原因らしい。
その場合は,「-f」をプッシュコマンドに付与することで,強制的にプッシュ出来る。
(※:今回はテスト環境なので強引にやってしまったが,実環境では推奨しない...)$ git push -f origin master作成した「test.py」がリモートリポジトリに登録されている!
ちなみに,リモートリポジトリの更新内容をローカルに反映したい時は,
以下コマンドを実行する。$ git pull origin master参考にした記事
・git pushがreject(拒否)されたときの対処法 @Takao_ さん
https://qiita.com/Takao_/items/5e563d5ea61d2829e497今回のまとめ
これにてGit及びGitHubの環境が出来た。
おそらくもっと色々な設定やコマンドがあると思うのでその辺はまた別途記事に起こしていこうかな。
今後は自分で書いたソースコードとかもガンガン上げてアウトプットしていきたいと思う。
- 投稿日:2020-09-07T20:56:42+09:00
よく使うGitコマンド集
はじめに
エンジニア未経験の方が、現場に入ってチーム開発を行うようになるまでに身に付けておいた方が良いと思うGitコマンドを、最低限抽出してまとめてみました。
また今回紹介するGitコマンドは、実際にチーム開発で使用する時の順序で紹介していきます。
よく使うGitコマンド集
git clone
まずはプロジェクトに参画したら、
ソースコードをGitHubなどのリモートリポジトリからローカルに持ってこないといけないですよね。その際に使うのは、cloneです。
このコマンドでリモートリポジトリのソースコードをローカルに引っ張ってこれます。git clone リモートリポジトリURLgit pull
ただこれを行うのは最初の一回だけで、
その後リモートリポジトリのコードが更新されるたびに変更内容を引っ張ってくるにはpullを使います。git pull origin ブランチ名git checkout -b
ローカルに持ってこれたら、
今度は作業ブランチをcheckout -bで作成します。
またこのコマンドはブランチを作成したらそのまま作ったブランチへ移動します。git checkout -b 新しいブランチ名git checkout
すでに存在するブランチに移動するだけならcheckoutを使います。
git checkout ブランチ名git merge
今度はpull又はcloneで引っ張ってきたコードを作業ブランチへ反映させるためにmergeを使います。
git merge pull又はcloneで引っ張ってきたブランチ名git branch
git branchを使うと、
ローカルにあるブランチ一覧と、現在どこのブランチにいるのかが確認できます。git branchgit add
mergeしてきたあとは実際に担当箇所の開発を行っていきます。
機能の開発が終わったら、新しく書いたコードを保存します。
そのためにまずaddを使って変更内容をインデックスに追加します。
addの後ろの「 . 」は、変更した部分を対象にするという意味です。git add .git commit
addしたらcommitで変更内容を保存します。
git commit -m "コミットメッセージ"git push
そして最後に、開発した内容をpushを使ってGitHubなどのリモートリポジトリへ送ります。
「head」は現在いるブランチを表しています。git push origin headあとはGitHubなどでpull requestを行う形になります。
最後に
以上が、チーム開発を行う上でのGitの大まかな使い方になります。
実際に使いそうな順番で解説していきましたので、参考になれば幸いです。最後までご覧くださりありがとうございました。
- 投稿日:2020-09-07T20:56:42+09:00
未経験が現場に入るまでに覚えておくと良いGitコマンド集
はじめに
エンジニア未経験の方が、現場に入ってチーム開発を行うようになるまでに身に付けておいた方が良いと思うGitコマンドを、最低限抽出してまとめてみました。
また今回紹介するGitコマンドは、実際にチーム開発で使用する時の順序で紹介していきます。
よく使うGitコマンド集
git clone
まずはプロジェクトに参画したら、
ソースコードをGitHubなどのリモートリポジトリからローカルに持ってこないといけないですよね。その際に使うのは、cloneです。
このコマンドでリモートリポジトリのソースコードをローカルに引っ張ってこれます。git clone リモートリポジトリURLgit pull
ただこれを行うのは最初の一回だけで、
その後リモートリポジトリのコードが更新されるたびに変更内容を引っ張ってくるにはpullを使います。git pull origin ブランチ名git checkout -b
ローカルに持ってこれたら、
今度は作業ブランチをcheckout -bで作成します。
またこのコマンドはブランチを作成したらそのまま作ったブランチへ移動します。git checkout -b 新しいブランチ名git checkout
すでに存在するブランチに移動するだけならcheckoutを使います。
git checkout ブランチ名git merge
今度はpull又はcloneで引っ張ってきたコードを作業ブランチへ反映させるためにmergeを使います。
git merge pull又はcloneで引っ張ってきたブランチ名git branch
git branchを使うと、
ローカルにあるブランチ一覧と、現在どこのブランチにいるのかが確認できます。git branchgit add
mergeしてきたあとは実際に担当箇所の開発を行っていきます。
機能の開発が終わったら、新しく書いたコードを保存します。
そのためにまずaddを使って変更内容をインデックスに追加します。
addの後ろの「 . 」は、変更した部分を対象にするという意味です。git add .git commit
addしたらcommitで変更内容を保存します。
git commit -m "コミットメッセージ"git push
そして最後に、開発した内容をpushを使ってGitHubなどのリモートリポジトリへ送ります。
「head」は現在いるブランチを表しています。git push origin headあとはGitHubなどでpull requestを行う形になります。
最後に
以上が、チーム開発を行う上でのGitの大まかな使い方になります。
実際に使いそうな順番で解説していきましたので、参考になれば幸いです。最後までご覧くださりありがとうございました。
- 投稿日:2020-09-07T20:56:42+09:00
チーム開発でよく使うGitコマンド集
はじめに
エンジニア未経験の方が、現場に入ってチーム開発を行うようになるまでに身に付けておいた方が良いと思うGitコマンドを、最低限抽出してまとめてみました。
また今回紹介するGitコマンドは、実際にチーム開発で使用する時の順序で紹介していきます。
よく使うGitコマンド集
git clone
まずはプロジェクトに参画したら、
ソースコードをGitHubなどのリモートリポジトリからローカルに持ってこないといけないですよね。その際に使うのは、cloneです。
このコマンドでリモートリポジトリのソースコードをローカルに引っ張ってこれます。git clone リモートリポジトリURLgit pull
ただこれを行うのは最初の一回だけで、
その後リモートリポジトリのコードが更新されるたびに変更内容を引っ張ってくるにはpullを使います。git pull origin ブランチ名git checkout -b
ローカルに持ってこれたら、
今度は作業ブランチをcheckout -bで作成します。
またこのコマンドはブランチを作成したらそのまま作ったブランチへ移動します。git checkout -b 新しいブランチ名git checkout
すでに存在するブランチに移動するだけならcheckoutを使います。
git checkout ブランチ名git merge
今度はpull又はcloneで引っ張ってきたコードを作業ブランチへ反映させるためにmergeを使います。
git merge pull又はcloneで引っ張ってきたブランチ名git branch
git branchを使うと、
ローカルにあるブランチ一覧と、現在どこのブランチにいるのかが確認できます。git branchgit add
mergeしてきたあとは実際に担当箇所の開発を行っていきます。
機能の開発が終わったら、新しく書いたコードを保存します。
そのためにまずaddを使って変更内容をインデックスに追加します。
addの後ろの「 . 」は、変更した部分を対象にするという意味です。git add .git commit
addしたらcommitで変更内容を保存します。
git commit -m "コミットメッセージ"git push
そして最後に、開発した内容をpushを使ってGitHubなどのリモートリポジトリへ送ります。
「head」は現在いるブランチを表しています。git push origin headあとはGitHubなどでpull requestを行う形になります。
最後に
以上が、チーム開発を行う上でのGitの大まかな使い方になります。
実際に使いそうな順番で解説していきましたので、参考になれば幸いです。最後までご覧くださりありがとうございました。
- 投稿日:2020-09-07T18:39:10+09:00
Pull Reaquest template 作成手順
PRのテンプレート作成手順
チーム開発をしていて、必ず必要だと思ったので記事にしました。
今までなかった現場もあったので、あるととても良いです。
PRの内容がすっきりして、レビュー時にコミュニケーションコストが省けるし、何をやったのかcloseしてもわるのであるととても便利です。
無いチームは書くことをお勧めします。作り方
$ cd 作りたいディレクトリに移動 $ mkdir .github $ cd .github $ touch pull_request_template.mdテンプレ中身(Markdown)
サンプル
## PRの概要 <!-- このPRの概要を記入してください --> ## レビューして欲しい箇所 <!-- PRで特にレビューして欲しい箇所を記載してください --> ## Draftにした理由(WIPでも良いと思う) <!-- Draftにした理由を記載してください --> ## スクリーンショット <!-- 作業した箇所のスクリーンショットなどあれば貼ってください --> Before | After ------------- | ------------- <image src="" width="320">|<image src="" width="320"> ## その他 <!-- レビュワーへの参考情報(実装上の懸念点や注意点などあれば記載) -->上記の内容をマージすればマージ以降PRの入力欄にこの内容が反映されます。
まとめ
上記意外にもチーム内でいろいろ決めて追加していくと良さそう。これはあくまでも参考程度の内容です。
- 投稿日:2020-09-07T18:12:32+09:00
【Git】エラー、コンフリクトのお悩み解決 - Gitの気持ちになって理解する checkout/merge/pull
よく見るエラーメッセージ
Gitを使っていると頻繁に目にするエラーメッセージ……
例えば次のメッセージが表示されたとき、あなたはどのように対応するでしょうか?error: Your local changes to the following files would be overwritten by checkout: test.txt Please commit your changes or stash them before you switch branches. Aborting
メッセージの意味、その対処法や背景までわかる人は、おそらく先を読む必要はないでしょう。
そうでない人はこの記事を読むことで、いままでより自信をもってgitを使うことができるようになるかもしれません。この記事で説明すること
- チェックアウトするときに、なぜエラーが発生するのか
- マージやリベースするときに、なぜコンフリクトが発生するのか
- チェックアウト時のエラーやコンフリクトを理解するためのgitのキホン
- チェックアウトやマージ、プルが具体的になにをやっているのか
この記事が対象とする人
- 冒頭のエラーメッセージの意味がわからない人
- 冒頭のエラーメッセージへの対処法はわかるけど、その意味がいまいちわかっていない人
- 検索で出たページのコマンドをコピペして、痛い目にあったことのある人
この記事が対象としない人
- 冒頭のエラーメッセージの意味や対処法が完璧にわかる人
- Gitで困ったことのない人
- Gitに触ったことのない人、これから勉強する人
Gitのキホン
Gitの気持ちを理解する上で大切なことは以下の2点です。
- コミットはその時点におけるすべてのファイルのスナップショットである1
- ブランチはコミットを指し示しているだけ
これは本当に大事なので、いまここで目を閉じて復唱してください。
コミットはスナップショット
各コミットは、コミット作成時点でのgitの管理下にあるファイルすべてのスナップショット(その時点でのファイルの状態)を保存しています。
gitの管理下にあるというのは、コミットを作成したときに
git add
コマンドやGUIツールでインデックスに登録されていたファイルのことです。過去(=ツリーの上流)のコミット作成時に登録されていたファイルも含みます。「コミットする」という言葉の意味
注意
この節は飛ばしても構いません。以降を読み進めるにあたって、用語に引っ掛かりを感じたら戻って来てみてください。「ファイルをコミットする」という言葉がよく使われますが、これには二つの動作が含まれています。
- ファイルAをインデックスに登録する
- ファイルAがインデックスに登録された状態で、コミットを作成する
また「コミットされていないファイル」という言葉もよく使われますが、これは以下のような意味です。
- すでにgitの管理下にあるファイルAに(いまのコミットから)なんらかの変更が加えられている
- ファイルAがインデックスに登録されていない、または、インデックスに登録されているが新たなコミットがまだ作成されていない
ブランチはコミットに貼り付けた付箋
masterやorigin/master, developなど色々なブランチを使用したことがあると思います。
ブランチは変更履歴のツリー(コミットの連なり)ではありません。ただ単にひとつのコミットを指し示しているだけの存在です。たとえるなら、区別しやすいようにコミットに付箋を貼り付けているようなものです。
Gitはコミットを作るときに、自動的にいまのブランチ(=付箋)を新しく作ったコミットに移動してくれているのです。
なぜチェックアウト時にエラーが発生するのか?
ここまでのキホン知識があると、チェックアウト時にエラーが発生する理由がわかります。
そもそもチェックアウトとは?
いまいる場所(HEAD)を指定したコミットに移動するコマンドです。
指定先としてブランチ(=付箋)を指定することもできて、その場合はブランチを切り替えるとともに、ブランチが指し示しているコミットに移動します。ターミナルであれば以下のようなコマンドで実行できます。
git checkout 1a104f1 # コミットハッシュを指定して移動 git checkout develop # developブランチに移動コミットを移動するとなにが起こるのか?
思い出してください。コミットはファイルのスナップショットを保存しているのでした。
コミットを移動すると、gitの管理下にあるファイルが、移動先のコミット作成時のスナップショットと同じ状態になります。
言い換えると、ファイルの内容が移動前の状態から移動先のコミット作成時の状態に変更されます。ここにチェックアウト時にエラーが発生する理由があります。
チェックアウト時に発生したエラーをよく読んでみる
冒頭のエラーをもう一度読んでみましょう。
error: Your local changes to the following files would be overwritten by checkout: test.txt Please commit your changes or stash them before you switch branches. Aborting
エラー:以下のファイルのローカルの変更がチェックアウトによって上書きされます。
test.txt
ブランチを切り替える前に、変更をコミットするかスタッシュしてください。
中断されました。メッセージの通り、このエラーはファイルにコミットされていない変更がある場合に発生します。
Gitの気持ちになって考える
ここでgitの気持ちになってみましょう。
Git「お、masterブランチにチェックアウトしろっていう命令がきたよ」
Git「じゃあ、masterブランチが指し示しているこのコミットAに移動しなきゃ!」
Git「管理してるファイルたちをコミットAの状態に変更しないとね。」
Git「……あれ?このtext.txtってファイル、いまのコミット(の状態)から変更されてるよ。」
Git「このtext.txtってファイルはまだコミットされてないんだね。」
Git「でも、コミットAに移動しちゃったら、text.txtはコミットAのときの状態に戻さなきゃ。」
Git「(勝手に戻しちゃったら怒られそう…………どうしたらいいの……?)」
Git「」
Git「」
Git「」
Git「error: Your local changes to the following files would be overwritten by checkout……Aborting」あたなの気持ちにもなってみましょう。
別のブランチをちょっと確認しようと、うっかりチェックアウトしただけで、(コミットするのを忘れていた)1時間かけて編集したファイルの変更がなかったことになったら嫌ですよね?
そんな悲劇を避けるために、gitは丁寧にエラーを返してくれているのです。
チェックアウトができる条件
チェックアウトができる条件は
- Gitの管理下にあるファイルがすべてコミット済みであること2
です。これが満たされていない場合、gitはファイルを移動先のコミットの状態に変更することができない(変更していいかどうかわからない)のでエラーを返します。
Gitの管理下にないファイルが変更されたり新規に作成されている場合は、gitの管理下にあるファイルの状態とは関係ないため、チェックアウト可能です。
チェックアウト時にエラーがでたときの対処法
ここまでの説明でおわかりかと思いますが、エラーが発生した場合は、メッセージに従って、
- コミットされていないファイルをコミットするかスタッシュする
- または、コミットされていないファイルの変更を元に戻す
ことで、チェックアウトができる条件が満たされます。
例外的な状況で発生するエラー - スタッシュが効かない!
Gitの管理下にないファイルが新規作成・変更されていても、チェックアウト可能と書きました。しかし、この状況でも例外的にエラーが発生する場合があります。それは、
- 移動先のコミットで同名のファイルがgitの管理下にある
場合です。このときも、gitは「いまのコミット下では管理下にないファイルA」を、移動先のコミットでの状態に変更していいかどうかわからないため、エラーが発生します。
Gitの管理下にないファイルはスタッシュの対象になりません。そのため、この状況ではスタッシュではチェックアウトできない状況が解消できないので、注意してください。
なぜマージするとコンフリクトが発生するのか?
次はマージすると発生するこのメッセージについて考えていきます。
CONFLICT (content): Merge conflict in test.txt Automatic merge failed; fix conflicts and then commit the result.そもそもマージとは?
二つの変更履歴を合流させるコマンドです。
典型的には「masterブランチにdevelopブランチをマージする」などの使い方ができます。
注:ブランチは変更履歴そのものではなく、コミットを指し示す付箋です。そのため、この言葉遣いは正確ではありません3。しかし、便宜上このような表現のほうが表面的にはわかりやすく、また通じやすいでしょう。
マージは具体的になにをやっているのか?
この節はGitのmergeコマンドのドキュメントからの引用です。
以下のような変更履歴をもつ二つのブランチ(masterとtopic)があるとします。
A---B---C topic # topicブランチはコミットCを指し示している / D---E---F---G master # masterブランチはコミットGを指し示しているこのときに、masterブランチ側からtopicブランチをマージします。ターミナルからなら、次のコマンドです。
git checkout master git merge topicマージコマンドを受け取ると、gitはそれぞれのブランチが指し示すコミット(CとG)の共通の祖先であるコミットEまで遡ります。
そして、masterが指し示すコミットGに対して、コミットEからtopicブランチの指し示すコミットCまでの変更を、以下のように順番に再現していきます。コミットGに対して・・・
- <E → A>の変更を追加する
- <A → B>の変更を追加する
- <B → C>の変更を追加する
これらの変更を追加し終わったあと、コミットHを新しく作成して、マージ完了です(下図)。
A---B---C topic / \ D---E---F---G---H masterマージでコンフリクトが発生する理由
これもgitの気持ちになって考えてみれば、理由がおわかりいただけると思います。
masterブランチにtopicブランチをマージするとき、コミットEからコミットCへと向かう変更を、コミットGに対して順番に適用していきます。
しかし、コミットGそれ自体もコミットEからいくつかの変更を経て出来上がっているわけです。
たとえば、
- <E → A>への変更
- <F → G>への変更
これら2つの変更の両方で、同じ test.txt というファイルが編集されていたらどうでしょう?
マージコマンドが実行されて、コミットGに<E → A>の変更が適用されるとき、1の変更を使うのか2の変更を使うのか、gitには自分で判断することはできません。このためコンフリクトを発生させて、どちらの変更を使うかの選択はユーザーに委ねるのです。
<<<<<<< HEAD <F → G>への変更 ======= <E → A>への変更 >>>>>>> topicこのようなコンフリクトが発生した場合は、いずれか一方の変更を残したり、二つの変更のいいとこ取りをするなりしてファイルを保存します。そして、改めてインデックスに登録したあと、新しいコミットを作成します。
# <E → A>への変更だけを残して、他の部分は削除した <E → A>への変更
プルとは
プルとは主に、リモートリポジトリのブランチをローカル(手元)のリポジトリのブランチにマージするときに使うコマンドです。
このコマンドは、リモートリポジトリのブランチをローカルに取得してくるフェッチ(fetch)コマンドを使ったあとに、対象のブランチをマージする動作を組み合わせたものに過ぎません。
# リモートリポジトリのorigin/masterブランチを手元のmasterにマージするコマンド git pull origin master # フェッチしたあとマージしても同様のことが実現できる git fetch # ローカルのorigin/masterがリモートのorigin/masterと同じ位置に同期される git merge origin/master # origin/masterをmasterにマージするそのため、プルで発生するコンフリクトはマージと同じように扱うことができます。
おすすめのgitの解説サイト
ぼくがgitを使い始めたときは、次のサイトで勉強しました。
それ以降は、少し高度なことをやりたくなったときに、都度検索して調べる方式でやっていますが、業務上gitで困ることはほとんどありません。このサイトで解説されていなくて、いざというときに知っておいた方がいいコマンドとして、
git reflog
があります。このコマンドは、直前のgitでの操作(失敗)をほとんどの場合、取り消すことができます。
ただし、gitの基礎がわかっていないと難しいコマンドなので、Gitをはじめからていねいになどで、基礎的な知識をしっかり固めたあとで挑戦するほうがよいです。次のページは比較的丁寧に解説してくれています。謝辞
この記事の内容や言い回しの多くは、@akio0911さんがアプリ道場サロン(iOSアプリ開発をテーマとしたサロン)内で行った「git講座」を参考に書かせていただきました。
また、サロン内でのgitに関するやりとりを参考に書かせていただいた節もあります。akioさんはもちろんのこと、サロンの皆様にはいつもモチベーションをいただいています。ありがとうございます。
iOSアプリを勉強中で仲間が欲しい人は是非覗いてみてください!この記事がgitで困っている人の助けになれば嬉しいです。
参考
- 投稿日:2020-09-07T18:12:32+09:00
Gitのお悩み解決 - Gitの気持ちになって考える checkout/merge/pull
よく見るエラーメッセージ
Gitを使っていると頻繁に目にするエラーメッセージ……
例えば次のメッセージが表示されたとき、あなたはどのように対応するでしょうか?error: Your local changes to the following files would be overwritten by checkout: test.txt Please commit your changes or stash them before you switch branches. Aborting
メッセージの意味、その対処法や背景までわかる人は、おそらく先を読む必要はないでしょう。
そうでない人はこの記事を読むことで、いままでより自信をもってgitを使うことができるようになるかもしれません。この記事で説明すること
- チェックアウトするときに、なぜエラーが発生するのか
- マージやリベースするときに、なぜコンフリクトが発生するのか
- チェックアウト時のエラーやコンフリクトを理解するためのgitのキホン
- チェックアウトやマージ、プルが具体的になにをやっているのか
この記事が対象とする人
- 冒頭のエラーメッセージの意味がわからない人
- 冒頭のエラーメッセージへの対処法はわかるけど、その意味がいまいちわかっていない人
- 検索で出たページのコマンドをコピペして、痛い目にあったことのある人
この記事が対象としない人
- 冒頭のエラーメッセージの意味や対処法が完璧にわかる人
- Gitで困ったことのない人
- Gitに触ったことのない人、これから勉強する人
Gitのキホン
Gitの気持ちを理解する上で大切なことは以下の2点です。
- コミットはその時点におけるすべてのファイルのスナップショットである1
- ブランチはコミットを指し示しているだけ
これは本当に大事なので、いまここで目を閉じて復唱してください。
コミットはスナップショット
各コミットは、コミット作成時点でのgitの管理下にあるファイルすべてのスナップショット(その時点でのファイルの状態)を保存しています。
gitの管理下にあるというのは、コミットを作成したときに
git add
コマンドやGUIツールでインデックスに登録されていたファイルのことです。過去(=ツリーの上流)のコミット作成時に登録されていたファイルも含みます。「コミットする」という言葉の意味
注意
この節は飛ばしても構いません。以降を読み進めるにあたって、用語に引っ掛かりを感じたら戻って来てみてください。「ファイルをコミットする」という言葉がよく使われますが、これには二つの動作が含まれています。
- ファイルAをインデックスに登録する
- ファイルAがインデックスに登録された状態で、コミットを作成する
また「コミットされていないファイル」という言葉もよく使われますが、これは以下のような意味です。
- すでにgitの管理下にあるファイルAに(いまのコミットから)なんらかの変更が加えられている
- ファイルAがインデックスに登録されていない、または、インデックスに登録されているが新たなコミットがまだ作成されていない
ブランチはコミットに貼り付けた付箋
masterやorigin/master, developなど色々なブランチを使用したことがあると思います。
ブランチは変更履歴のツリー(コミットの連なり)ではありません。ただ単にひとつのコミットを指し示しているだけの存在です。たとえるなら、区別しやすいようにコミットに付箋を貼り付けているようなものです。
Gitはコミットを作るときに、自動的にいまのブランチ(=付箋)を新しく作ったコミットに移動してくれているのです。
なぜチェックアウト時にエラーが発生するのか?
ここまでのキホン知識があると、チェックアウト時にエラーが発生する理由がわかります。
そもそもチェックアウトとは?
いまいる場所(HEAD)を指定したコミットに移動するコマンドです。
指定先としてブランチ(=付箋)を指定することもできて、その場合はブランチを切り替えるとともに、ブランチが指し示しているコミットに移動します。ターミナルであれば以下のようなコマンドで実行できます。
git checkout 1a104f1 # コミットハッシュを指定して移動 git checkout develop # developブランチに移動コミットを移動するとなにが起こるのか?
思い出してください。コミットはファイルのスナップショットを保存しているのでした。
コミットを移動すると、gitの管理下にあるファイルが、移動先のコミット作成時のスナップショットと同じ状態になります。
言い換えると、ファイルの内容が移動前の状態から移動先のコミット作成時の状態に変更されます。ここにチェックアウト時にエラーが発生する理由があります。
チェックアウト時に発生したエラーをよく読んでみる
冒頭のエラーをもう一度読んでみましょう。
error: Your local changes to the following files would be overwritten by checkout: test.txt Please commit your changes or stash them before you switch branches. Aborting
エラー:以下のファイルのローカルの変更がチェックアウトによって上書きされます。
test.txt
ブランチを切り替える前に、変更をコミットするかスタッシュしてください。
中断されました。メッセージの通り、このエラーはファイルにコミットされていない変更がある場合に発生します。
Gitの気持ちになって考える
ここでgitの気持ちになってみましょう。
Git「お、masterブランチにチェックアウトしろっていう命令がきたよ」
Git「じゃあ、masterブランチが指し示しているこのコミットAに移動しなきゃ!」
Git「管理してるファイルたちをコミットAの状態に変更しないとね。」
Git「……あれ?このtext.txtってファイル、いまのコミット(の状態)から変更されてるよ。」
Git「このtext.txtってファイルはまだコミットされてないんだね。」
Git「でも、コミットAに移動しちゃったら、text.txtはコミットAのときの状態に戻さなきゃ。」
Git「(勝手に戻しちゃったら怒られそう…………どうしたらいいの……?)」
Git「」
Git「」
Git「」
Git「error: Your local changes to the following files would be overwritten by checkout……Aborting」あたなの気持ちにもなってみましょう。
別のブランチをちょっと確認しようと、うっかりチェックアウトしただけで、(コミットするのを忘れていた)1時間かけて編集したファイルの変更がなかったことになったら嫌ですよね?
そんな悲劇を避けるために、gitは丁寧にエラーを返してくれているのです。
チェックアウトができる条件
チェックアウトができる条件は
- Gitの管理下にあるファイルがすべてコミット済みであること2
です。これが満たされていない場合、gitはファイルを移動先のコミットの状態に変更することができない(変更していいかどうかわからない)のでエラーを返します。
Gitの管理下にないファイルが変更されたり新規に作成されている場合は、gitの管理下にあるファイルの状態とは関係ないため、チェックアウト可能です。
チェックアウト時にエラーがでたときの対処法
ここまでの説明でおわかりかと思いますが、エラーが発生した場合は、メッセージに従って、
- コミットされていないファイルをコミットするかスタッシュする
- または、コミットされていないファイルの変更を元に戻す
ことで、チェックアウトができる条件が満たされます。
例外的な状況で発生するエラー - スタッシュが効かない!
Gitの管理下にないファイルが新規作成・変更されていても、チェックアウト可能と書きました。しかし、この状況でも例外的にエラーが発生する場合があります。それは、
- 移動先のコミットで同名のファイルがgitの管理下にある
場合です。このときも、gitは「いまのコミット下では管理下にないファイルA」を、移動先のコミットでの状態に変更していいかどうかわからないため、エラーが発生します。
Gitの管理下にないファイルはスタッシュの対象になりません。そのため、この状況ではスタッシュではチェックアウトできない状況が解消できないので、注意してください。
なぜマージするとコンフリクトが発生するのか?
次はマージすると発生するこのメッセージについて考えていきます。
CONFLICT (content): Merge conflict in test.txt Automatic merge failed; fix conflicts and then commit the result.そもそもマージとは?
二つの変更履歴を合流させるコマンドです。
典型的には「ブランチAに別のブランチBをマージする」などの使い方ができます。
注:ブランチは変更履歴そのものではなく、コミットを指し示す付箋です。そのため、この言葉遣いは正確ではありません3。しかし、便宜上このような表現のほうが表面的にはわかりやすく、また通じやすいでしょう。
マージは具体的になにをやっているのか?
この節はGitのmergeコマンドのドキュメントからの引用です。
以下のような変更履歴をもつ二つのブランチ(masterとtopic)があるとします。
A---B---C topic # topicブランチはコミットCを指し示している / D---E---F---G master # masterブランチはコミットGを指し示しているこのときに、masterブランチ側からtopicブランチをマージします。ターミナルからなら、次のコマンドです。
git checkout master git merge topicマージコマンドを受け取ると、gitはそれぞれのブランチが指し示すコミット(CとG)の共通の祖先であるコミットEまで遡ります。
そして、masterが指し示すコミットGに対して、コミットEからtopicブランチの指し示すコミットCまでの変更を、以下のように順番に再現していきます。コミットGに対して・・・
- <E → A>の変更を追加する
- <A → B>の変更を追加する
- <B → C>の変更を追加する
これらの変更を追加し終わったあと、コミットHを新しく作成して、マージ完了です(下図)。
A---B---C topic / \ D---E---F---G---H masterマージでコンフリクトが発生する理由
これもgitの気持ちになって考えてみれば、理由がおわかりいただけると思います。
masterブランチにtopicブランチをマージするとき、コミットEからコミットCへと向かう変更を、コミットGに対して順番に適用していきます。
しかし、コミットGそれ自体もコミットEからいくつかの変更を経て出来上がっているわけです。
たとえば、
- <E → A>への変更
- <F → G>への変更
これら2つの変更の両方で、同じ test.txt というファイルが編集されていたらどうでしょう?
マージコマンドが実行されて、コミットGに<E → A>の変更が適用されるとき、1の変更を使うのか2の変更を使うのか、gitには自分で判断することはできません。このためコンフリクトを発生させて、どちらの変更を使うかの選択はユーザーに委ねるのです。
<<<<<<< HEAD <F → G>への変更 ======= <E → A>への変更 >>>>>>> topicこのようなコンフリクトが発生した場合は、いずれか一方の変更を残したり、二つの変更のいいとこ取りをしてファイルを保存します。そして、改めてインデックスに登録したあと、新しいコミットを作成します。
# <E → A>への変更だけを残して、他の部分は削除した <E → A>への変更
プルとは
プルとは主に、リモートリポジトリのブランチをローカル(手元)のリポジトリのブランチにマージするときに使うコマンドです。
このコマンドは、リモートリポジトリのブランチをローカルに取得してくるフェッチ(fetch)コマンドを使ったあとに、対象のブランチをマージする動作を組み合わせたものに過ぎません。
# リモートリポジトリのorigin/masterブランチを手元のmasterにマージするコマンド git pull origin master # フェッチしたあとマージしても同様のことが実現できる git fetch # ローカルのorigin/masterがリモートのorigin/masterと同じ位置に同期される git merge origin/master # origin/masterをmasterにマージするそのため、プルで発生するコンフリクトはマージと同じように扱うことができます。
おすすめのgitの解説サイト
ぼくがgitを使い始めたときは、次のサイトで勉強しました。
それ以降は、少し高度なことをやりたくなったときに、都度検索して調べる方式でやっていますが、業務上gitで困ることはほとんどありません。このサイトで解説されていなくて、いざというときに知っておいた方がいいコマンドとして、
git reflog
があります。このコマンドは、直前のgitでの操作(失敗)をほとんどの場合、取り消すことができます。
ただし、gitの基礎がわかっていないとけっこう難しいコマンドなので、Gitをはじめからていねいになどで、基礎的な知識をしっかり固めたあとで挑戦するほうがよいです。次のページは比較的丁寧に解説してくれています。謝辞
この記事の内容や言い回しの多くは、@akio0911さんがアプリ道場サロン(iOSアプリ開発をテーマとしたサロン)内で行った「git講座」を参考に書かせていただきました。
また、サロン内でのgitに関するやりとりを参考に書かせていただいた節もあります。akioさんはもちろんのこと、サロンの皆様にはいつもモチベーションをいただいています。
iOSアプリを勉強中で仲間が欲しい人は是非覗いてみてください!この記事がgitで困っている人の助けになれば嬉しいです。
参考
- 投稿日:2020-09-07T18:12:32+09:00
Gitのお悩み解決 - Gitの気持ちになって理解する checkout/merge/pull
よく見るエラーメッセージ
Gitを使っていると頻繁に目にするエラーメッセージ……
例えば次のメッセージが表示されたとき、あなたはどのように対応するでしょうか?error: Your local changes to the following files would be overwritten by checkout: test.txt Please commit your changes or stash them before you switch branches. Aborting
メッセージの意味、その対処法や背景までわかる人は、おそらく先を読む必要はないでしょう。
そうでない人はこの記事を読むことで、いままでより自信をもってgitを使うことができるようになるかもしれません。この記事で説明すること
- チェックアウトするときに、なぜエラーが発生するのか
- マージやリベースするときに、なぜコンフリクトが発生するのか
- チェックアウト時のエラーやコンフリクトを理解するためのgitのキホン
- チェックアウトやマージ、プルが具体的になにをやっているのか
この記事が対象とする人
- 冒頭のエラーメッセージの意味がわからない人
- 冒頭のエラーメッセージへの対処法はわかるけど、その意味がいまいちわかっていない人
- 検索で出たページのコマンドをコピペして、痛い目にあったことのある人
この記事が対象としない人
- 冒頭のエラーメッセージの意味や対処法が完璧にわかる人
- Gitで困ったことのない人
- Gitに触ったことのない人、これから勉強する人
Gitのキホン
Gitの気持ちを理解する上で大切なことは以下の2点です。
- コミットはその時点におけるすべてのファイルのスナップショットである1
- ブランチはコミットを指し示しているだけ
これは本当に大事なので、いまここで目を閉じて復唱してください。
コミットはスナップショット
各コミットは、コミット作成時点でのgitの管理下にあるファイルすべてのスナップショット(その時点でのファイルの状態)を保存しています。
gitの管理下にあるというのは、コミットを作成したときに
git add
コマンドやGUIツールでインデックスに登録されていたファイルのことです。過去(=ツリーの上流)のコミット作成時に登録されていたファイルも含みます。「コミットする」という言葉の意味
注意
この節は飛ばしても構いません。以降を読み進めるにあたって、用語に引っ掛かりを感じたら戻って来てみてください。「ファイルをコミットする」という言葉がよく使われますが、これには二つの動作が含まれています。
- ファイルAをインデックスに登録する
- ファイルAがインデックスに登録された状態で、コミットを作成する
また「コミットされていないファイル」という言葉もよく使われますが、これは以下のような意味です。
- すでにgitの管理下にあるファイルAに(いまのコミットから)なんらかの変更が加えられている
- ファイルAがインデックスに登録されていない、または、インデックスに登録されているが新たなコミットがまだ作成されていない
ブランチはコミットに貼り付けた付箋
masterやorigin/master, developなど色々なブランチを使用したことがあると思います。
ブランチは変更履歴のツリー(コミットの連なり)ではありません。ただ単にひとつのコミットを指し示しているだけの存在です。たとえるなら、区別しやすいようにコミットに付箋を貼り付けているようなものです。
Gitはコミットを作るときに、自動的にいまのブランチ(=付箋)を新しく作ったコミットに移動してくれているのです。
なぜチェックアウト時にエラーが発生するのか?
ここまでのキホン知識があると、チェックアウト時にエラーが発生する理由がわかります。
そもそもチェックアウトとは?
いまいる場所(HEAD)を指定したコミットに移動するコマンドです。
指定先としてブランチ(=付箋)を指定することもできて、その場合はブランチを切り替えるとともに、ブランチが指し示しているコミットに移動します。ターミナルであれば以下のようなコマンドで実行できます。
git checkout 1a104f1 # コミットハッシュを指定して移動 git checkout develop # developブランチに移動コミットを移動するとなにが起こるのか?
思い出してください。コミットはファイルのスナップショットを保存しているのでした。
コミットを移動すると、gitの管理下にあるファイルが、移動先のコミット作成時のスナップショットと同じ状態になります。
言い換えると、ファイルの内容が移動前の状態から移動先のコミット作成時の状態に変更されます。ここにチェックアウト時にエラーが発生する理由があります。
チェックアウト時に発生したエラーをよく読んでみる
冒頭のエラーをもう一度読んでみましょう。
error: Your local changes to the following files would be overwritten by checkout: test.txt Please commit your changes or stash them before you switch branches. Aborting
エラー:以下のファイルのローカルの変更がチェックアウトによって上書きされます。
test.txt
ブランチを切り替える前に、変更をコミットするかスタッシュしてください。
中断されました。メッセージの通り、このエラーはファイルにコミットされていない変更がある場合に発生します。
Gitの気持ちになって考える
ここでgitの気持ちになってみましょう。
Git「お、masterブランチにチェックアウトしろっていう命令がきたよ」
Git「じゃあ、masterブランチが指し示しているこのコミットAに移動しなきゃ!」
Git「管理してるファイルたちをコミットAの状態に変更しないとね。」
Git「……あれ?このtext.txtってファイル、いまのコミット(の状態)から変更されてるよ。」
Git「このtext.txtってファイルはまだコミットされてないんだね。」
Git「でも、コミットAに移動しちゃったら、text.txtはコミットAのときの状態に戻さなきゃ。」
Git「(勝手に戻しちゃったら怒られそう…………どうしたらいいの……?)」
Git「」
Git「」
Git「」
Git「error: Your local changes to the following files would be overwritten by checkout……Aborting」あたなの気持ちにもなってみましょう。
別のブランチをちょっと確認しようと、うっかりチェックアウトしただけで、(コミットするのを忘れていた)1時間かけて編集したファイルの変更がなかったことになったら嫌ですよね?
そんな悲劇を避けるために、gitは丁寧にエラーを返してくれているのです。
チェックアウトができる条件
チェックアウトができる条件は
- Gitの管理下にあるファイルがすべてコミット済みであること2
です。これが満たされていない場合、gitはファイルを移動先のコミットの状態に変更することができない(変更していいかどうかわからない)のでエラーを返します。
Gitの管理下にないファイルが変更されたり新規に作成されている場合は、gitの管理下にあるファイルの状態とは関係ないため、チェックアウト可能です。
チェックアウト時にエラーがでたときの対処法
ここまでの説明でおわかりかと思いますが、エラーが発生した場合は、メッセージに従って、
- コミットされていないファイルをコミットするかスタッシュする
- または、コミットされていないファイルの変更を元に戻す
ことで、チェックアウトができる条件が満たされます。
例外的な状況で発生するエラー - スタッシュが効かない!
Gitの管理下にないファイルが新規作成・変更されていても、チェックアウト可能と書きました。しかし、この状況でも例外的にエラーが発生する場合があります。それは、
- 移動先のコミットで同名のファイルがgitの管理下にある
場合です。このときも、gitは「いまのコミット下では管理下にないファイルA」を、移動先のコミットでの状態に変更していいかどうかわからないため、エラーが発生します。
Gitの管理下にないファイルはスタッシュの対象になりません。そのため、この状況ではスタッシュではチェックアウトできない状況が解消できないので、注意してください。
なぜマージするとコンフリクトが発生するのか?
次はマージすると発生するこのメッセージについて考えていきます。
CONFLICT (content): Merge conflict in test.txt Automatic merge failed; fix conflicts and then commit the result.そもそもマージとは?
二つの変更履歴を合流させるコマンドです。
典型的には「masterブランチにdevelopブランチをマージする」などの使い方ができます。
注:ブランチは変更履歴そのものではなく、コミットを指し示す付箋です。そのため、この言葉遣いは正確ではありません3。しかし、便宜上このような表現のほうが表面的にはわかりやすく、また通じやすいでしょう。
マージは具体的になにをやっているのか?
この節はGitのmergeコマンドのドキュメントからの引用です。
以下のような変更履歴をもつ二つのブランチ(masterとtopic)があるとします。
A---B---C topic # topicブランチはコミットCを指し示している / D---E---F---G master # masterブランチはコミットGを指し示しているこのときに、masterブランチ側からtopicブランチをマージします。ターミナルからなら、次のコマンドです。
git checkout master git merge topicマージコマンドを受け取ると、gitはそれぞれのブランチが指し示すコミット(CとG)の共通の祖先であるコミットEまで遡ります。
そして、masterが指し示すコミットGに対して、コミットEからtopicブランチの指し示すコミットCまでの変更を、以下のように順番に再現していきます。コミットGに対して・・・
- <E → A>の変更を追加する
- <A → B>の変更を追加する
- <B → C>の変更を追加する
これらの変更を追加し終わったあと、コミットHを新しく作成して、マージ完了です(下図)。
A---B---C topic / \ D---E---F---G---H masterマージでコンフリクトが発生する理由
これもgitの気持ちになって考えてみれば、理由がおわかりいただけると思います。
masterブランチにtopicブランチをマージするとき、コミットEからコミットCへと向かう変更を、コミットGに対して順番に適用していきます。
しかし、コミットGそれ自体もコミットEからいくつかの変更を経て出来上がっているわけです。
たとえば、
- <E → A>への変更
- <F → G>への変更
これら2つの変更の両方で、同じ test.txt というファイルが編集されていたらどうでしょう?
マージコマンドが実行されて、コミットGに<E → A>の変更が適用されるとき、1の変更を使うのか2の変更を使うのか、gitには自分で判断することはできません。このためコンフリクトを発生させて、どちらの変更を使うかの選択はユーザーに委ねるのです。
<<<<<<< HEAD <F → G>への変更 ======= <E → A>への変更 >>>>>>> topicこのようなコンフリクトが発生した場合は、いずれか一方の変更を残したり、二つの変更のいいとこ取りをしてファイルを保存します。そして、改めてインデックスに登録したあと、新しいコミットを作成します。
# <E → A>への変更だけを残して、他の部分は削除した <E → A>への変更
プルとは
プルとは主に、リモートリポジトリのブランチをローカル(手元)のリポジトリのブランチにマージするときに使うコマンドです。
このコマンドは、リモートリポジトリのブランチをローカルに取得してくるフェッチ(fetch)コマンドを使ったあとに、対象のブランチをマージする動作を組み合わせたものに過ぎません。
# リモートリポジトリのorigin/masterブランチを手元のmasterにマージするコマンド git pull origin master # フェッチしたあとマージしても同様のことが実現できる git fetch # ローカルのorigin/masterがリモートのorigin/masterと同じ位置に同期される git merge origin/master # origin/masterをmasterにマージするそのため、プルで発生するコンフリクトはマージと同じように扱うことができます。
おすすめのgitの解説サイト
ぼくがgitを使い始めたときは、次のサイトで勉強しました。
それ以降は、少し高度なことをやりたくなったときに、都度検索して調べる方式でやっていますが、業務上gitで困ることはほとんどありません。このサイトで解説されていなくて、いざというときに知っておいた方がいいコマンドとして、
git reflog
があります。このコマンドは、直前のgitでの操作(失敗)をほとんどの場合、取り消すことができます。
ただし、gitの基礎がわかっていないと難しいコマンドなので、Gitをはじめからていねいになどで、基礎的な知識をしっかり固めたあとで挑戦するほうがよいです。次のページは比較的丁寧に解説してくれています。謝辞
この記事の内容や言い回しの多くは、@akio0911さんがアプリ道場サロン(iOSアプリ開発をテーマとしたサロン)内で行った「git講座」を参考に書かせていただきました。
また、サロン内でのgitに関するやりとりを参考に書かせていただいた節もあります。akioさんはもちろんのこと、サロンの皆様にはいつもモチベーションをいただいています。ありがとうございます。
iOSアプリを勉強中で仲間が欲しい人は是非覗いてみてください!この記事がgitで困っている人の助けになれば嬉しいです。
参考
- 投稿日:2020-09-07T14:58:01+09:00
git で 正規表現を使った操作したい
- 投稿日:2020-09-07T14:14:37+09:00
bashプロンプトの表示をNerdfontsで格好良くする
無限人がやってるPowerLineのあのパンくずリスト型の表示が格好いいアレです。
最近は色々なshがあるしプラグイン的な形でサクッと導入できる中、わざわざbashでひいこらやる必要も無いと思うけど、他のshを導入するのは面倒くさいし、それはともかく自分用にカスタマイズしたいなと思ったので頑張りました。
作ってる途中で色々知見を得たので、備忘録的な。
格好いい画像
筆者環境
WindowsTerminal (fontには@tawara_氏のHackGenNerd35 Consoleを利用)
WSL2 (Ubuntu 18.04.5)
bash 4.4.20
これと完全一致じゃなくても別にどうにかなるとは思いますとにかくソースコード
nerdps1.sh#!/bin/bash set -euC # bash option # 色分け用のエスケープ文字 ESC=$(printf '\033') declare -l DSPCOLOR="none" # 次の項目を作る関数 C() { if [ "$DSPCOLOR" = "none" ]; then echo -n "" else echo -n " " fi # > background color case "$1" in "red" ) echo -e -n "${ESC}[41m";; "green" ) echo -e -n "${ESC}[42m";; "yellow" ) echo -e -n "${ESC}[43m";; "blue" ) echo -e -n "${ESC}[44m";; "purple" ) echo -e -n "${ESC}[45m";; "cyan" ) echo -e -n "${ESC}[46m";; "gray" ) echo -e -n "${ESC}[47m";; * ) echo -e -n "${ESC}[49m";; esac if [ "$DSPCOLOR" = "none" ]; then echo -n " " fi # > color local isUsed=true case "$DSPCOLOR" in "red" ) echo -e -n "${ESC}[31m";; "green" ) echo -e -n "${ESC}[32m";; "yellow" ) echo -e -n "${ESC}[33m";; "blue" ) echo -e -n "${ESC}[34m";; "purple" ) echo -e -n "${ESC}[35m";; "cyan" ) echo -e -n "${ESC}[36m";; "gray" ) echo -e -n "${ESC}[37m";; * ) isUsed=false;; esac # > if "${isUsed}"; then echo -n " " # \ue0b0 nf-pl-left_hard_divider パンくずの肝 echo -e -n "${ESC}[30m" fi # 文字色 case "$1" in "red" ) echo -e -n "${ESC}[37m";; "green" ) echo -e -n "${ESC}[37m";; "yellow" ) echo -e -n "${ESC}[30m";; "blue" ) echo -e -n "${ESC}[37m";; "purple" ) echo -e -n "${ESC}[37m";; "cyan" ) echo -e -n "${ESC}[30m";; "gray" ) echo -e -n "${ESC}[30m";; * ) echo -e -n "${ESC}[0m";; esac DSPCOLOR="$1" } export VIRTUAL_ENV_DISABLE_PROMPT=1 # pythonのvenv仮想環境でPS1を書き換えさせない nerdPS1() { local userName="$1" # if userName yourname, use short name # [TODO] Change YOUR-USER-NAME if [[ $userName == "YOUR-USER-NAME" ]]; then userName="?" # terminalによってはカラーフォント絵文字も使える。自分っぽいものに置き換えよう fi local hostName="$2" # if hostName .. # [TODO] Change YOUR-HOST-NAME if [[ $hostName == "YOUR-HOST-NAME" ]]; then hostName="" # \uf878 nf-mdi-monitor 一番ホストっぽかった fi local pwdInfo="$3" # chroot # とりあえず書き足しておいたけどvenvと関係なかった。ここのは動作検証してないので…… if [[ -v debian_chroot ]]; then C "purple" echo -e -n "\uf306 $debian_chroot" # nf-linux-debian fi # (optional) python venv if [[ -v VIRTUAL_ENV ]]; then local PYTHON_VER="$(python -V)" local PYTHON_ENVNAME="$(basename $VIRTUAL_ENV)" C "cyan" # for remove uniquename (pipenv hoge-{uniquename}) echo -e -n "\ue235 ${PYTHON_VER#Python } ${PYTHON_ENVNAME%-*}" # nf-fae-python 一番見やすいPythonロゴ fi # host C "blue" echo -n "$userName@$hostName" # pwd C "gray" echo -e -n "\ue5ff $pwdInfo" # nf-custom-folder フォルダアイコン # (optional) git # [TODO] `source git-prompt.sh` (you have to download or find) if git status --ignore-submodules &>/dev/null; then # You Use Git local gitps1="$(__git_ps1)" if [[ $gitps1 =~ [*+?%] ]]; then C "yellow" else C "green" fi echo -e -n "\ue725 $gitps1" # nf-dev-git_branch 一番見やすかったGitぽいアイコン fi C "reset" # 忘れずに } # 右端に時刻を表示 # コピペ https://orebibou.com/ja/home/201810/20181002_001/ __command_rprompt() { local rprompt=$(date "+%Y/%m/%d %H:%M:%S") local num=$(($COLUMNS - ${#rprompt} - 2)) printf "%${num}s$rprompt\\r" '' } set +e # これが無いと、プロンプトで実行したコマンドにエラーが有った時に動かなくなる PS1='$(nerdPS1 \u \h \w)\n\$ ' PROMPT_COMMAND=__command_rprompt.bashrc# ... if [ -e ~/nerdps1.sh ]; then source ~/nerdps1.sh fi source ~/.git-prompt.sh GIT_PS1_SHOWDIRTYSTATE=true GIT_PS1_SHOWUPSTREAM=true GIT_PS1_SHOWUNTRACKEDFILES=true GIT_PS1_SHOWSTASHSTATE=true GIT_PS1_COMPRESSSPARSESTATE=true # 増えた GIT_PS1_STATESEPARATOR=' ' # ...説明
プロンプトの表示の変更
一般に見えているホスト名とか書いてある部分は環境変数
PS1
で指定されています。この内容は1行実行ごとに解釈して都度都度実行されます。
後述のC
関数を1つのパンくずごとに実行させたかったのですが、これをそのままC
に埋め込むと思うように動かない(同時に処理される?)ので、今回その内容について全て関数に投げています。Nerdfonts
powerline用のフォントを始めとする様々なアイコンフォントが含まれたフォントです。外字領域を利用しているいて、Nerdfontsと他の一般的なfontを合成することもできるため、様々な派生があります。
パンくずの仕組み
そもそもあのパンくずは、Nerdfontsに含まれる
nf-pl-left_hard_divider
という文字を、文字色をそれ以前の背景色にすることで表現しています。
今回DSPCOLOR
という変数で以前の色を管理しC
という変数で、背景色の変更とnf-pl-left_hard_divider
の表示を行っています。
一元管理しているので、好きなようにパンくずを生やしたり消したりできます。
変数名の汚染は少し心配色を変える仕組み
\e[{hoge}m
の形で入力する(制御文字を使うためecho
には-e
オプションが必要)することで、{hoge}
に応じた色変更が行えます。具体的な記入例は詳しい説明がいくらでも他の人の記事にあるので任せます。
\e
と\033
は同じ意味ですが、後者のほうが互換性が良いみたいですユーザ名とホスト名のアイコン化
長ったるいのは嫌だけど非表示にするのも何かあった時アレだな、ということで、普段のものに一致していたら1字に書き換えるようにしておきます。
python venv実行中の表示
pythonにはバージョン管理を司るvenvという機能がありますが、デフォルトだと環境名を
PS1
に埋め込みやがります。埋め込むかどうかは環境変数VIRTUAL_ENV_DISABLE_PROMPT
で指定できるし、仮想環境名はbasename $VIRTUALENV
で取得できます。
pipenvを使う時、環境作成時のユニークな値がこれの後ろに付いてきてしまうので、ハイフン以後を削除する設定しています。git の表示
色々細々した項目について場合分けするのが大変そうですが、公式の
git-prompt.sh
というのがいい感じに処理してくれるので、これを見つけてきて読み込みましょう。ブランチ名と状況を出力してくれる関数__git_ps1
を含んでいます。
これの出力で変更の有る無しを判断しています。
他の記事ではあまり書いてませんでしたが、最近ではGIT_PS1_COMPRESSSPARSESTATE
についても設定する必要があるようです。ただ、WSLにおいて、通常のWindowsのファイルにこれを実行しようとすると明らかに時間がかかるようになってしまいます。
__git_ps1
の仕業です。いつか改善されることを期待して。右端に時刻を表示
bashでPROMPT_COMMANDを利用して右プロンプトを出力させるという記事のものが今回文句なく動いてくれたのでこれをそのまま使用しました。
もうちょっと飾っても良いかもしれない。やらかしたとき
これで遊んでると
.bashrc
にバグを埋め込んで起動できなくなることが有るので、気をつけましょう。
WSLの場合は、cmdなりPowerShellなりからWSL内部のbashをrcを読みこまずに実行することができます。
bash
wsl.exe -e bash --norc
.bashrcでsourceを埋め込む前にとりあえずテストして確認しましょう。(先達の知恵)最後に
パンくず(そういう言い方で良いのか?)再現の記事は多いけど、このスクリプトでは割と楽に好きな色のパンくずを追加できるので、色々各々の状況に応じた形にカスタムしやすいと思います。作ってる内に互換性への意識がおざなりになっちゃったけど……
参考
- Git のための最強 Bashプロンプト!
__git_ps1
も自作したくなったら役立つかも- シェルスクリプトのechoで”問題なく”色をつける(bash他対応) 色について詳しく
- Pythonのvenvのプロンプト表示をカスタマイズする venvの書き換えについて
- bashでPROMPT_COMMANDを利用して右プロンプトを出力させる 右端の時刻表示について
- NERD FONTS チートシートが有るので好きなアイコンを探してみてください。
- Ricty を神フォントだと崇める僕が、フリーライセンスのプログラミングフォント「白源」を作った話 NerdFonts合成バージョンも配布中