あいつの日誌β

働きながら旅しています。

git: Git入門ドリル

あらすじ

svn から git 移行が叫ばれる今日この頃ですので git に慣れるためのドリルを用意しました。

準備

適当なディレクトリを用意して git init する。

% mkdir git-practice
% cd git-practice
% git init
% touch content.txt
% git add content.txt
% git commit -m 'initial commit.'

ドリル開始

develop branch を作成

% git branch develop 
% git checkout develop

develop から分岐する feature branch A,B を作成

% git branch feature/A
% git branch feature/B

最初は feature/B branch で作業を開始する

% git checkout feature/B
% echo 'function B1 () {}' >> content.txt
% git add content.txt
% git commit -m 'added function B1'
% echo 'function B2 () {}' >> content.txt
% git add content.txt
% git commit -m 'added function B2'

ログ確認

% git log --graph --oneline --decorate --all
* 01da252 (HEAD, feature/B) added function B2
* 21b4a79 added function B1
* d2182af (master, feature/A, develop) initial commit.

次に feature/A branch で作業を行う

% git checkout feature/A
% echo 'function A1 () {}' >> content.txt
% git add content.txt
% git commit -m 'added function A1'
% echo 'function A2 () {}' >> content.txt
% git add content.txt
% git commit -m 'added function A2'

ログを確認。feature/B の commit object が下のほうに表示されている事を確認します。

% git log --graph --oneline --decorate --all                                    * 3cb7221 (HEAD, feature/A) added function A2
* 3c51dba added function A1
| * 01da252 (feature/B) added function B2
| * 21b4a79 added function B1
|/  
* d2182af (master, develop) initial commit.

develop branch に戻り feature/A branch の作業内容をdevelop に merge します。

% git checkout develop
% git merge --no-ff feature/A

ログを確認します。feature/A の commit object が develop に合流しました。 feature/B の commit object はまだ分岐したままです。 この分岐地点は feature/A が merge する前である事を確認して下さい。

% git log --graph --oneline --decorate --all
*   13771ac (HEAD, develop) Merge branch 'feature/A' into develop
|\  
| * 06f48ec (feature/A) added function A2
| * a99e8ff added function A1
|/  
| * 472a044 (feature/B) added function BB
| * b12ad43 added function B
|/  
* d32a167 (origin/master, master) first commit

feature/B branch に戻り、 develop の変更に追従します。 以下のコマンドを実行して下さい。feature branch の作業が衝突します。

% git checkout feature/B
% git rebase develop

衝突した箇所を以下のように修正します。

before

% cat content.txt
<<<<<< HEAD
function A1 () {}
function A2 () {}
=======
function B () {}
>>>>>>> added function B

after

% cat content.txt
function A1 () {}
function A2 () {}
function B () {}

修正した事を通知して rebase を続行する。

% git add content.txt 
% git rebase --continue

この作業によってfeature/1はdevelop の最新の修正に追従していることをログで確認する。よく見ると feature/B の commit object の hash 値が異なっています。

これは rebase を行った事によって commit object が新しく作り直されているからです。

% git log --graph --oneline --decorate --all
* 9267bb5 (HEAD, feature/B) added function BB
* 19ef8c9 added function B
*   13771ac (develop) Merge branch 'feature/A' into develop
|\  
| * 06f48ec (feature/A) added function A2
| * a99e8ff added function A1
|/  
* d32a167 (origin/master, master) first commit

最後にdevelopに戻ります。

% git checkout develop
% git log --graph --oneline --decorate --all
* 56e322f (feature/B) added function B2
* 1d0d668 added function B1
*   d9b47b7 (HEAD, develop) Merge branch 'feature/A' into develop
|\
| * 3cb7221 (feature/A) added function A2
| * 3c51dba added function A1
|/
* d2182af (master) initial commit.

feature/B をmergeします。

% git merge --no-ff feature/B
% git log --graph --oneline --decorate --all                                    *   c5b7ca9 (HEAD, develop) Merge branch 'feature/B' into develop
|\  
| * 56e322f (feature/B) added function B2
| * 1d0d668 added function B1
|/  
*   d9b47b7 Merge branch 'feature/A' into develop
|\  
| * 3cb7221 (feature/A) added function A2
| * 3c51dba added function A1
|/  
* d2182af (master) initial commit.

これで feature branch は不要になるので削除する。

% git branch -d feature/A feature/B

振り出しに戻る

上記の作業が終わったら以下のコマンドで振り出しに戻れます。

% git checkout master
% git branch -D develop

merge する時に --no-ff をはずすと log の表示がどのように変わるかなどを試してみると理解が深まると思います。

まとめ

実はこの記事ではあえて remote repository の事を考えていません。ドリルを極力短くする事によって git を使ってうれしい事をできるだけ体感できるようにしたかったからです。

新しい技術を使うにはどうしても反復作業が必要です。このドリルにでてくるコマンドを実際に使って git の雰囲気に少しでも慣れて頂ければと思います。