Git練習帳(ローカルリポジトリ編)

非エンジニア向けGitの使い方」などと簡単にまとめたものの、実際に使うのはまた少し難しいようなので、1歩ずつ説明していきます。
実際にターミナルソフトウェアを立ち上げて、打ち込みながら読んでください。
「vi(vim)の使い方が分からない」という方は、まず「viを終了することができない人のためのviの使い方」からどうぞ。

まずは練習用のリポジトリを作る

お好きな場所にテキトーな名前のディレクトリを作成して、そこに移動します。
[cc lang=”bash”]$ mkdir practice.git
$ cd practice.git/[/cc]
git initでただのディレクトリをgitリポジトリとして初期化します。git initというコマンドを打つと、「空のGitリポジトリができました」というメッセージが出ます。これで、作成したpractice.gitというディレクトリがGitリポジトリになりました。
[cc lang=”bash”]$ git init
Initialized empty Git repository in /users/katty/practice.git/.git/[/cc]

練習用のテキストファイルを作成してGitの管理下に入れる

次に練習用のテキストファイルを作ります。
[cc lang=”bash”]$ vim practice.txt[/cc]
中身は、何でもいいですが、「Hello, Git!」とかと書いておきます。編集したら中身を確認してみます。
[cc lang=”bash”]$ cat practice.txt
Hello, Git![/cc]
ここで、git statusコマンドを使ってみます。このコマンドはGitリポジトリ内の変更があったファイルを書きだしてくれます。
[cc lang=”bash”]$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use “git add …” to include in what will be committed)
#
# practice.txt
nothing added to commit but untracked files present (use “git add” to track)[/cc]
これを読むと、「トラックされていないファイル」としてpractice.txtが扱われています。practice.txtは、まだ作成したばかりで、Gitの管理下に入っていない状態です。
メッセージとして、「管理下に入れるためにはgit addを使え」と書いてあります。素直にgit addします。そして、再びgit statusをしてみます。
git addの後ろには管理下に入れるファイル名を書きますが、面倒くさいので「このディレクトリ以下の全て」という意味で「.」を使ってしまいます。
[cc lang=”bash”]$ git add .
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use “git rm –cached …” to unstage)
#
# new file: practice.txt
#[/cc]
今度は、practice.txtが「コミットされる予定の変更」という扱いになりました。これで、Gitにチェックポイントを作る作業であるコミットをする準備が整いました。

コミットする

早速コミットします。git commitコマンドを使います。
これを打つとすぐにテキストエディタが立ち上がるので、そこに変更内容をコメントとして残します。ここでは、「practice.txtを追加。」といコメントを残しました。
[cc lang=”bash”]$ git commit -a
[master (root-commit) 00fab83] practice.txtを追加。
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 practice.txt[/cc]
git logコマンドを使うと、過去のコミットを列挙することができます。早速やってみましょう。
[cc lang=”bash”]$ git log –graph
* commit 00fab83264d2eb7cb14b355cd7c198eafc6ec15b
Author: xxxx
Date: Thu Jan 12 01:14:54 2012 +0900
practice.txtを追加。[/cc]
当然ですが、まだコミットは1件しかありません。

コミットしたところまでは戻ることができる

先ほどのpractice.txtに変更を加えてみます。たとえば、「HogeHoge」と書き足します。
[cc lang=”bash”]$ vim practice.txt
$ cat practice.txt
Hello, Git!
HogeHoge[/cc]
前のコミットしたところと、現在の状態の差分は、git diffというコマンドで確認することができます。やってみます。
[cc lang=”bash”]$ git diff
diff –git a/practice.txt b/practice.txt
index 670a245..9cc2e76 100644
— a/practice.txt
+++ b/practice.txt
@@ -1 +1,3 @@
Hello, Git!
+
+HogeHoge[/cc]
空白を1行と、「HogeHoge」の行が追加されていることが分かります。
「でも、やっぱりHogeHogeはいらないや」となったら、コマンド一発で前にコミットしたところまで戻ることができます。これにはgit resetというコマンドを使います。
[cc lang=”bash”]$ git reset –hard HEAD
HEAD is now at 00fab83 practice.txtを追加。
$ cat practice.txt
Hello, Git![/cc]
戻っていますね!
リポジトリを操作していて訳わからなくなった時とかは、git reset –hard HEADで前にコミットしたところまで捨てて戻してしまいましょう。

もう一度コミット

さっきは編集を捨ててしまったけど、今度はちゃんとコミットします。
さっきはテキトーに「HogeHoge」とか書きましたが、今度は「I am Katty.」と書きます。
[cc lang=”bash”]$ vim practice.txt
$ cat practice.txt
Hello, Git!
I am Katty.
$ git commit -a
[master 4efd7fc] I am Kattyを追加。
1 files changed, 2 insertions(+), 0 deletions(-)
$ git log –graph
* commit 4efd7fc0139793631c4d6559cb1437c2854e1c25
| Author: xxx
| Date: Thu Jan 12 01:16:49 2012 +0900
|
| I am Kattyを追加。
|
* commit 00fab83264d2eb7cb14b355cd7c198eafc6ec15b
Author: xxx
Date: Thu Jan 12 01:14:54 2012 +0900
practice.txtを追加。[/cc]
git logを見ると、コミットが追加されているのが分かります。こうやって変更してはコミットしてを繰り替えていきます。

ブランチをきる

git branchというコマンドを使うことで、ブランチを作成することができます。
今あるソースコードを完全に残した状態で、ブランチというコピーを作成します。ブランチのコードを編集しても、元のコードは完全な状態で残るので、ブランチでは挑戦的で刺激的なプログラミングができます。
ブランチの作成コマンドは、git branchの後にブランチ名です。
[cc lang=”bash”]$ git branch branch1
$ git branch
branch1
* master[/cc]
これで、branch1というブランチができます。
ブランチ名を書かないgit branchコマンドは現在あるブランチの一覧を表示してくれます。ここでmasterの前にアスタリスク(*)が付いています。これは、現在編集しているソースコードがmasterのソースコードであるということを意味しています。
これから、branch1のソースコードを編集したいので、これを切り替えます。ブランチの切り替えには、git checkoutコマンドを使います。
[cc lang=”bash”]$ git checkout branch1
Switched to branch ‘branch1’
$ cat practice.txt
Hello, Git!
I am Katty.[/cc]
見ての通り、ブランチを切り替えるとソースコードがコピーされています。同じファイルだから切り替えっている気がしませんが・・・。

ブランチでソースコードが二つに分岐していることを見る

試しに、branch1ブランチの中のpractice.txtを変更します。最後に「This is branch1」とか追加してみました。
[cc lang=”bash”]$ vim practice.txt
$ git diff
diff –git a/practice.txt b/practice.txt
index 603192c..5f48a64 100644
— a/practice.txt
+++ b/practice.txt
@@ -1,3 +1,5 @@
Hello, Git!
I am Katty.
+
+This is branch1.[/cc]
コミットします。もう慣れたもんですね。
[cc lang=”bash”]$ git commit -a
[branch1 7592b84] This is branch1を追加。
1 files changed, 2 insertions(+), 0 deletions(-)
$ git log –graph
* commit 7592b8437ff8f76b849e7d472bdd13dc7a209a94
| Author: xxx
| Date: Thu Jan 12 01:18:34 2012 +0900
|
| This is branch1を追加。
|
* commit 4efd7fc0139793631c4d6559cb1437c2854e1c25
| Author: xxx
| Date: Thu Jan 12 01:16:49 2012 +0900
|
| I am Kattyを追加。
|
* commit 00fab83264d2eb7cb14b355cd7c198eafc6ec15b
Author: xxx
Date: Thu Jan 12 01:14:54 2012 +0900
practice.txtを追加。[/cc]
コミットが3件になっていることを確認します。
そして、git checkoutコマンドでmasterブランチに戻ります。
[cc lang=”bash”]$ git checkout master
Switched to branch ‘master’
$ git log –graph
* commit 4efd7fc0139793631c4d6559cb1437c2854e1c25
| Author: xxx
| Date: Thu Jan 12 01:16:49 2012 +0900
|
| I am Kattyを追加。
|
* commit 00fab83264d2eb7cb14b355cd7c198eafc6ec15b
Author: xxx
Date: Thu Jan 12 01:14:54 2012 +0900
practice.txtを追加。[/cc]
こちらはコミットが2件しかありません。ブランチを作成することはソースコードのコピーを作成することです。branch1ブランチでの編集と、masterブランチでの編集は別ものです。したがって、masterブランチは、「This is branch1.」を追加する前の状態のままです。

他のブランチで編集したものを持ってくる

branch1ブランチに追加した「This is branch1.」を、masterブランチにもってきたくなりました。こういう時は、mergeコマンドを使います。
[cc lang=”bash”]$ git merge branch1
Updating 4efd7fc..7592b84
Fast-forward
practice.txt | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)[/cc]
コマンド一発。マージ完了です。ログを見てみましょう。
[cc lang=”bash”]$ git log –graph
* commit 7592b8437ff8f76b849e7d472bdd13dc7a209a94
| Author: xxx
| Date: Thu Jan 12 01:18:34 2012 +0900
|
| This is branch1を追加。
|
* commit 4efd7fc0139793631c4d6559cb1437c2854e1c25
| Author: xxx
| Date: Thu Jan 12 01:16:49 2012 +0900
|
| I am Kattyを追加。
|
* commit 00fab83264d2eb7cb14b355cd7c198eafc6ec15b
Author: xxx
Date: Thu Jan 12 01:14:54 2012 +0900
practice.txtを追加。[/cc]
mergeによってbranch1で行ったコミットがmasterにも追加されました。
[cc lang=”bash”]$ cat practice.txt
Hello, Git!
I am Katty.
This is branch1.[/cc]
もちろんファイルも変更されています。

わざとコンフリクトさせる準備をする

先ほどは、新しい行を追加しただけだったので、Gitが空気を読んで自動でマージしてくれました。では、「This is branch1.」の行を二つのブランチで別々に編集したらどうなるでしょうか。
「This is branch1.」を「This is master branch.」に変更します。
[cc lang=”bash”]$ vim practice.txt
$ cat practice.txt
Hello, Git!
I am Katty.
This is master branch.[/cc]
git diffで変更を見てみると、「1行削除して1行追加する」という変更が加えられたとみなされているようです。
[cc lang=”bash”]$ git diff
diff –git a/practice.txt b/practice.txt
index 5f48a64..7c07146 100644
— a/practice.txt
+++ b/practice.txt
@@ -2,4 +2,4 @@ Hello, Git!
I am Katty.
-This is branch1.
+This is master branch.[/cc]
これをmasterブランチにコミットします。コミットのコメントは、「master branchを追加。」とでもしておきます。
[cc lang=”bash”]$ git add .
$ git commit -a
[master 2f832f4] master branchを追加。
1 files changed, 1 insertions(+), 1 deletions(-)[/cc]
そして、branch1ブランチに切り替えます。
[cc lang=”bash”]$ git checkout branch1
Switched to branch ‘branch1′[/cc]
そして、いじわるに、branch1ブランチでも、masterブランチと同じ行を書き換えてしまいます・・・!
こちらは、「This is branch1.」を「This is branch1 branch.」にしました。
[cc lang=”bash”]$ vim practice.txt
$ git diff
diff –git a/practice.txt b/practice.txt
index 5f48a64..6d6b735 100644
— a/practice.txt
+++ b/practice.txt
@@ -2,4 +2,4 @@ Hello, Git!
I am Katty.
-This is branch1.
+This is branch1 branch.[/cc]
そして、これもコミットします。
[cc lang=”bash”]$ git add .
$ git commit -a
[branch1 568d206] branch1をbranch1 branchに変更。
1 files changed, 1 insertions(+), 1 deletions(-)[/cc]
これは何をしているかというと、msaterブランチもbranch1ブランチも「This is branch1.」だった行を、それぞれのブランチで別々に、つまり好き勝手に編集を加えてしまった状態を作り出しています。
チーム開発をする場合も同様に二人の人が同じ場所をスタート地点として、別々に、つまり好き勝手に編集を加えてしまう場合があります。それを模倣していると思ってください。

コンフリクトを解消してみる

この状態で、masterブランチをbranch1ブランチにマージしようとするとどうなるでしょうか?
[cc lang=”bash”]$ git merge master
Auto-merging practice.txt
CONFLICT (content): Merge conflict in practice.txt
Automatic merge failed; fix conflicts and then commit the result.[/cc]
「CONFLICT」と出ているのに注目してください!二つのブランチの編集が衝突してしまっているので、Gitはお手上げのようです。こうなってしまったら、手動で直すしかありません。
コンフリクトしてしまったファイルがどうなっているのかを見てみます。
[cc lang=”bash”]$ cat practice.txt
Hello, Git!
I am Katty.
<<<<<<< HEAD This is branch1 branch. ======= This is master branch. >>>>>>> master[/cc]
怪しげな「<<<<<<<」とか「=======」とか「>>>>>>>」が追加されています。
これがプログラムだったら、この行で絶対エラーが出ますね・・・。戻したくなったら、git resetでした。
[cc lang=”bash”]$ git reset –hard HEAD
HEAD is now at 568d206 branch1をbranch1 branchに変更。
$ cat practice.txt
Hello, Git!
I am Katty.
This is branch1 branch.[/cc]
戻りました。
でも、現実から逃げてはいけません。いつかは直さなければならないので、コンフリクトを解消する仕事をします。
再度マージを実行してコンフリクトさせます。
[cc lang=”bash”]$ git merge master
Auto-merging practice.txt
CONFLICT (content): Merge conflict in practice.txt
Automatic merge failed; fix conflicts and then commit the result.
$ cat practice.txt
Hello, Git!
I am Katty.
<<<<<<< HEAD This is branch1 branch. ======= This is master branch. >>>>>>> master[/cc]
この怪しげな「<<<<<<<」とか「=======」とか「>>>>>>>」は何だろう。
擬人化するならば、
Git「ごめんよ、この行は僕の力ではマージできないよ。両方とも書いておくから、自分でマージしてくれよ。」
という感じで、マージしきれない2つのテキストを「<<<<<<<」と「=======」と「>>>>>>>」の間に書いてあるのです。
そういうわけで、これは衝突しているものが両方とも書かれています。これを読んで、片方のみを残すとか、両方から必要な部分を取り出して残すとか、そういう選択をします。これはGitの仕事ではなくて人間の仕事です。
[cc lang=”bash”]$ vim practice.txt [/cc]
ここでは、両方残す編集をしました。すると、git diffはどうなるでしょうか?
[cc lang=”bash”]$ git diff
diff –cc practice.txt
index 6d6b735,7c07146..0000000
— a/practice.txt
+++ b/practice.txt
@@@ -2,4 -2,4 +2,5 @@@ Hello, Git
I am Katty.
+This is branch1 branch.
+ This is master branch.[/cc]
両方追加という変更が加えられるという差分になっています。
これで、怪しげな「<<<<<<<」とか「=======」とか「>>>>>>>」が消えて、コンフリクトが解消されました。
解消されたところで、チェックポイントを作成しておきたいので、コミットします。
[cc lang=”bash”]$ git commit -a
[branch1 119e8a8] Merge branch ‘master’ into branch1[/cc]
これでgit logを表示するとこんな具合になります。branchによって変更が分岐して、mergeでひとつに戻っている様子が見えます。
[cc lang=”bash”]$ git log –graph
* commit 119e8a895694b16cf0f54dae83cae037df2b52c8
|\ Merge: 568d206 2f832f4
| | Author: xxx
| | Date: Thu Jan 12 01:24:12 2012 +0900
| |
| | Merge branch ‘master’ into branch1
| |
| | Conflicts:
| | practice.txt
| |
| * commit 2f832f40f3ebedd45fa4d165a248cd3a4aded9fe
| | Author: xxx
| | Date: Thu Jan 12 01:20:54 2012 +0900
| |
| | master branchを追加。
| |
* | commit 568d20651dbb38f63bbd3335c3855b0efa9b93af
|/ Author: xxx
| Date: Thu Jan 12 01:21:47 2012 +0900
|
| branch1をbranch1 branchに変更。
|
* commit 7592b8437ff8f76b849e7d472bdd13dc7a209a94
| Author: xxx
| Date: Thu Jan 12 01:18:34 2012 +0900
|
| This is branch1を追加。
|
* commit 4efd7fc0139793631c4d6559cb1437c2854e1c25
| Author: xxx
| Date: Thu Jan 12 01:16:49 2012 +0900
|
| I am Kattyを追加。
|
* commit 00fab83264d2eb7cb14b355cd7c198eafc6ec15b
Author: xxx
Date: Thu Jan 12 01:14:54 2012 +0900
practice.txtを追加。[/cc]

おわりに

ここまで読んでいただいた方、お疲れさまでした。
もし読んだだけだったら、ターミナルソフトを立ち上げて実際に打ち込んで試してみてください。触ってみるのが一番です。

コメント

タイトルとURLをコピーしました