縛りプレイで勉強するGitの基礎
縛りプレイをすることで、Gitの基礎であるハッシュ(sha-1)を意識してみる。
縛りプレイ とは
1. SMプレイのうち亀甲縛りなど縄を使うプレイ(性行為)のこと。昭和から存在する言葉。 2. ゲームをプレイする際、本来ゲーム側からは設定されていない制限(縛り)を自ら科す事によって、より難易度の高いゲームをプレイする事。
記事のタイトルの意味は 2. の方です。
概要
縛りの条件は下記の通り。
つまり、リモート(origin含む)、ブランチ(master含む)、タグの使用禁止です。
関連して、下記のコマンド/操作も使用禁止です。
- git clone (origin が作成されるため)
- git checkout -b (-b オプションはブランチ作られるので禁止、それ以外はOK)
- git pull (動作が複雑なので)
- .git/ の直接編集(邪道なので)
つまり、常にdetached HEADで開発し、sha-1ハッシュをノートにメモしながら開発することになります。
これにより、「Gitの基礎であるハッシュ(sha-1)がどういうものか?」というのが分かります。*1
この記事には、cloneとか、pullみたいな上級者用のコマンドは登場しません。
Gitリポジトリの準備
まずはgitリポジトリを用意する必要があります。
$ mkdir git_proj $ cd git_proj $ git init
masterなんてブランチは不要なので、削除します。ただ、すぐに削除が出来ないため、空のコミットを作成し、その後にmasterブランチを削除します。
$ git commit --allow-empty -m "first commit" $ git log -n 1 (表示されたsha-1の値をノートにメモする) $ git checkout <メモしたsha-1> $ git branch -d master
ファイルの追加/コミットの手順
基本的に普通のadd/commitと同じです。
例
新しいファイルを作成して、追加した場合のコマンドなどを記載してみました。
$ echo "Hello, Git World" > README.md $ git add README.md $ git commit -m "add README"
コミット毎にノートにsha-1の値をメモしておいた方が良いです。(ブランチが使えないので)
$ git log commit 421bcacadf8581e8cc459ea1254ee3990af967af Author: sinsoku <sinsoku.listy@gmail.com> Date: Wed Jul 18 00:07:49 2012 +0900 add README commit 62f92f671d0e83d8a75fabd1dd46f64aa7b36dc6 Author: sinsoku <sinsoku.listy@gmail.com> Date: Tue Jul 17 23:59:08 2012 +0900 first commit sinsoku@sinsoku-vm:~/Projects/sample/git_proj(git:(421bcac...)) $
ファイルを変更したコミットを作ってみる。
markdown形式にREADME.mdを変更してみました。
$ echo "# Hello, Git World" > README.md $ git add README.md $ git commit -m "markdown形式に直した"
ログを確認してみる。
$ git log -n 1 commit 1a8905309eac98743b3b2facd30db992ff0d5b9e Author: sinsoku <sinsoku.listy@gmail.com> Date: Wed Jul 18 00:15:44 2012 +0900 markdown形式に直した
私の環境では、このような出力になりました。
sha-1の値は環境により異なりますが、大体の表示は同じになると思います。
ブランチ関連
branchコマンドを使わなくても、sha-1をcheckoutしてコミットをする事で自然にログが分岐します。
例
まず「add README」のsha-1の値をcheckoutしてみます。
(この値は各人で異なるので、自分の環境の値を使う)
$ git checkout 421bcacadf8581e8cc459ea1254ee3990af967af Warning: you are leaving 3 commits behind, not connected to any of your branches: 1a89053 markdown形式に直した 421bcac add README 62f92f6 first commit If you want to keep them by creating a new branch, this may be a good time to do so with: git branch new_branch_name 1a8905309eac98743b3b2facd30db992ff0d5b9e HEAD is now at 421bcac... add README sinsoku@sinsoku-vm:~/Projects/sample/git_proj(git:(421bcac...)) $
警告が出ていますが、気にせずに作業します。
README.md は作られているので、Licenseのファイルでも作成してみましょう。
$ touch LGPL-2.1 $ git add LGPL-2.1 $ git commit -m "add License"
ログを確認しましょう。
$ git log commit 1aeb413b6d839d85074cc0e3f5fee9f1dfe16252 Author: sinsoku <sinsoku.listy@gmail.com> Date: Wed Jul 18 00:29:18 2012 +0900 add License commit 421bcacadf8581e8cc459ea1254ee3990af967af Author: sinsoku <sinsoku.listy@gmail.com> Date: Wed Jul 18 00:07:49 2012 +0900 add README commit 62f92f671d0e83d8a75fabd1dd46f64aa7b36dc6 Author: sinsoku <sinsoku.listy@gmail.com> Date: Tue Jul 17 23:59:08 2012 +0900 first commit sinsoku@sinsoku-vm:~/Projects/sample/git_proj(git:(1aeb413...)) $
「add License」のコミットは「add README」の次に作成されました。
現在の状態の詳細をlogのオプションを使って表示してみます。
$ git log --oneline --graph --decorate 1a8905309eac98743b3b2facd30db992ff0d5b9e 1aeb413b6d839d85074cc0e3f5fee9f1dfe16252 * 1aeb413 (HEAD) add License | * 1a89053 markdown形式に直した |/ * 421bcac add README * 62f92f6 first commit sinsoku@sinsoku-vm:~/Projects/sample/git_proj(git:(1aeb413...)) $
上記のようにブランチが出来ています。
では、これをマージします。
$ git merge 1a8905309eac98743b3b2facd30db992ff0d5b9e Merge made by the 'recursive' strategy. README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) sinsoku@sinsoku-vm:~/Projects/sample/git_proj(git:(9e97a14...)) $
グラフ表示でログを確認してみます。
$ git log --oneline --graph --decorate * 9e97a14 (HEAD) Merge commit '1a8905309eac98743b3b2facd30db992ff0d5b9e' into HEAD |\ | * 1a89053 markdown形式に直した * | 1aeb413 add License |/ * 421bcac add README * 62f92f6 first commit sinsoku@sinsoku-vm:~/Projects/sample/git_proj(git:(9e97a14...)) $
ちゃんとマージされています。
リモートにブランチをpush
remoteコマンドやbranchコマンドが使えないため、
例
$ git push git@github.com:sinsoku/git_proj.git 9e97a14:refs/heads/develop
これで、リモートリポジトリにdevelopブランチが作成されます。
リモートにタグをpush
これはブランチとほとんど同じです。
例
$ git push git@github.com:sinsoku/git_proj.git 9e97a14:refs/tags/v1.0.0
リモートの変更を取り込む
clone, pullが使えず、branchも使えないため、fetchを使います。
取り込んだ変更個所の指定は常にsha-1を使います。
例
例として、gitのリポジトリの変更を取り込んでみます。
$ mkdir git $ cd git $ git init $ git fetch git://github.com/git/git.git
github上で確認すると、タグ v1.7.11.2 のハッシュタグは 8d141a1d562abb31f27f599dbf6e10a6c06ed73e のようです。
$ git log 8d141a1d562abb31f27f599dbf6e10a6c06ed73e commit 8d141a1d562abb31f27f599dbf6e10a6c06ed73e Author: Junio C Hamano <gitster@pobox.com> Date: Wed Jul 11 12:55:38 2012 -0700 Git 1.7.11.2 Signed-off-by: Junio C Hamano <gitster@pobox.com> commit b700086d840ceaee339f9f031be72b34e237f84f Merge: 2e1e8ef b31272f Author: Junio C Hamano <gitster@pobox.com> Date: Wed Jul 11 12:58:28 2012 -0700 Merge branch 'jc/maint-blame-unique-abbrev' into maint "git blame" did not try to make sure that the abbreviated commit object names in its output are unique. * jc/maint-blame-unique-abbrev: blame: compute abbreviation width that ensures uniqueness
上記のように、ログが表示されています(=変更が取得できています)。
参考書籍
- 作者: 濱野純(Junio C Hamano)
- 出版社/メーカー: 秀和システム
- 発売日: 2009/09/24
- メディア: 単行本
- 購入: 31人 クリック: 736回
- この商品を含むブログ (155件) を見る
- 作者: 岡本隆史,武田健太郎,相良幸範
- 出版社/メーカー: 技術評論社
- 発売日: 2012/07/10
- メディア: 単行本(ソフトカバー)
- 購入: 7人 クリック: 103回
- この商品を含むブログ (26件) を見る
後日談
この記事の話を隣の人に話したら「努力の方向性が間違っている」と言われました(´・ω・)
*1:たぶん