初心者のGit Vol.1

何の初心者かは分かりませんが。
いいんです。こういうものは、語呂が命ですから。

さて。

今回は、

という内容を、簡単にメモしたいと思います。
『簡単に』なんて前置きをしなくても、簡単じゃないメモなんて僕程度には書けませんが。
ちなみに、ここはGitの説明は行わない、不親切設計となっております。

UbuntuにGit導入

まあ、aptとか使えば一発なんですけどね。
ただまあ、間違っても、

sudo apt-get install git

なんてしてはいけませんが。
正しくは、

sudo apt-get install git-core

です。前者は罠なんです、手の込んだいたずらなのです。
……いや、まあ違いますけどね。
前者で入るのは『GNU Interactive Tools』です。今は、gnuit?なのかな、まあとにかく、ここで扱いたい分散バージョン管理ツールのGitとは無縁の長物です。
紛らわしいので、改めて書き記して置きますが、分散バージョン管理システムのGitをインストールしたければ、Ubuntuでインストールするパッケージはgit-coreです。(ソースからビルドする場合は度外視)

で。

インストールしたら、まずはユーザー設定を行います。

git config --global user.name "hoge foo"
git config --global user.email "hoge@hoge.com"

名前、メールアドレスともに、コミットしたユーザー情報として登録されるものです。

ここで、configのオプションである--globalですが、これはローカル全体の共通設定として登録する際に追加するものです。(ローカル全体と言っても、特定ユーザーにとっての全体で、ローカルシステム全体ではありません)
ローカル全体の共通設定は、ホームディレクトリの.gitconfigファイルに記されています。

後は、お好みですね。僕は大概、以下の設定を加えます。

git config --global color.ui "auto"
git config --global alias.st "status"
git config --global alias.conflis "config --list"
git config --global push.default "matching"

color.uiをautoにすると、git statusなどをしたときに、変更されたものを、ステージされた変更をで表す、と言ったように、見た目にわかりやすく表示してくれるようになるので便利。

aliasはエイリアス。上の例で言えば、たとえばgit stgit statusと同じものになる。リポジトリ単位のエイリアス設定も可能。設定したエイリアスの確認方法は、

の3種類。
まあ、最後の1つがあれば十分だと思う。

push.defaultは、まあリモートでも管理するようになったときに必要になるんじゃないかと思う。以前の経験として、pushしたときにそういう操作をシステムから要求されたことがあるので、保険みたいな気持ちで設定しています。

導入は大体こんな感じです。

ローカルでリポジトリ作成

と言っても、あんまり書くことないんですけどね。
たとえば、testというレポジトリを作るとしましょう。

mkdir test
cd test
git init

これで終了です。もう、Gitが管理してくれるようになっています。
超お手軽ですね!
使いこなすのは難しいけど。

リモートレポジトリ作成

さて、個人の場合でも作業環境があちこちにあって、育てているプロジェクトのバージョン管理が煩雑というのは、よくあることと思います。
一番理想的なのは、まあ、Gitとサーバーの連携なんですけど、それが中々叶わない場合もあるでしょう。

ともあれ。

リモートレポジトリの作成です。
今回は、USBメモリに作ることにしましょう。
※ここに記しているのは、僕がいつもしている方法であり、一般的か否かはわかりません。ご注意を!

ローカルに、既にtestというレポジトリがあるとしましょう。
USBメモリは/mntにマウントされ、アクセスには管理者権限が必要と仮定します。
これらの前提に則って、リモートレポジトリを作るとしたら、

cd /mnt
sudo mkdir test.git
cd test.git
sudo git --bare init (リモートリポジトリの作成)
cd ~/test (ローカルのリポジトリ)
git remote add origin /mnt/test.git
git config branch.master.remote "origin"
git config branch.master.merge "refs/heads/master"
sudo git push origin master

としています。sudoがついているものは、USBメモリの書き込みに管理者権限が必要な場合です。不要である場合は、sudoをつける必要性は当然ながらありません。

追記(2011/04/20)

USBメモリなどへのアクセスに管理者権限な必要な場合の補足です。

始めてsudo git pushする際、.git/logs/refs/remotes/origin/masterというファイルが作成されます。
ただし、sudoつけてやると、このファイルは、

-rw-r--r-- 1 root root 560 2011-04-20 11:08 master

みたいな感じで作成され、git pullにまでsudoが必要になってしまいます。

そこで、該当ファイルの所有者を変えて使います。

% cd $(REPOSITORY_PATH)/.git/logs/refs/remotes/origin
% sudo chown <user-name>:<user-group> master

まあ、-Rオプションで一括で片付けてもいいのでしょうけれども。
以上、追記、失礼しました。


git remote addで、ここではUSBメモリ上に作っているのでこうなりますが、サーバーなら、たとえば、

git remote add origin ssh://hoge@foo.org/git/test.git

などとします。

2つのconfigは、これもおまじないみたいなものですね。以前の経験から習慣になっているんですが、果たして何で必要だったかは忘れてしまいました……すみません。

最後のpushですが、origin masterの部分は、最初の一回だけです。ブランチ分けたり、機能を十全に使いこなすほどでもなければ、以降はgit pushだけで十分です。

まとめ

今回は、ほとんど導入だけを記しました。

今後、ブランチの切り分けなど、まともに使えるようになった際には、またこうしてメモを書くかと思います。

それでは、この場はお開きということで。

おまけ

Gitを使ってリポジトリをたくさん作っていたら、それらのリポジトリの状態を一斉に知る手段が欲しくなりました。

んで。

作ったシェルスクリプトが、以下になります。

#!/bin/sh

case `uname` in
    FreeBSD)
        ECHO="echo -e"
        ;;
    *)
        ECHO="/bin/echo -e"
        ;;
esacgit pullにまでsudoが必要になってしまいます。

status_check(){
    case `$ECHO $1|cut -d " " -f3,4|sed "s/ //"` in
        Permissiondenied)
            ;;
        *)
            if test -d $1 ;
            then
                cd $1
                if test -e .git ;
                then
                    $ECHO "\033[01;35m$1: git status\033[m"
                    git status
                    cd -
                else
                    :
                fi
            else
                :
            fi
            ;;
    esac
}

$ECHO "\033[01;31m\c"

for i in `find .|grep -F ".git/config"|sed "s/\.git[\/a-zA-Z]*//"` ;
do
    $ECHO "\033[m"
    status_check $i ;
done

これを、GitStatusCheckなどと名づけて、僕は使っています。

機能は、カレントディレクトリ以下に存在するGitリポジトリを、.git/configの有無によって捜索・判定し、Gitリポジトリであるならばgit statusを順次実行するというものです。

たとえば、hogeというユーザーが/home/hogeでこのスクリプトを実行すると、ホームディレクトリ以下にあるリポジトリを捜索し、その状態を吐き出すというものです。

ですから、下手に/(ルートディレクトリ)なんかで実行すると酷い目に合います。用法・用量は正しくお使いください、です。

訂正(2011/04/12)

おまけのシェルスクリプトに関して、

for i in `find .|grep -F ".git/config"|sed "s/.git[\/a-zA-Z]*//"` ;

を、

for i in `find .|grep -F ".git/config"|sed "s/\.git[\/a-zA-Z]*//"` ;

に訂正しました。

以前のものだと、たとえば、git/local-repositoryみたいにしていた場合、再帰的な処理に引っ掛かりません。バックスラッシュ一個の違いは、甚だ大きい、略して甚大です。

また、

case `uname` in
    FreeBSD)
        ECHO="echo -e"
        ;;
    *)
        ECHO="/bin/echo -e"
        ;;
esac

の部分は、お使いのシェルなどの環境による挙動の違いが大きいので、適宜変更する必要があります。
自分の環境でしか試していないので、環境によってどのような影響があるか把握しきれていないことを、ご了承願いたいと思います。

失礼しました。