最終更新日

香川研究室でのGitの使い方

このページは、 私が以前に情報処理センター(現: 総合情報センター)のニュースレターに書いた CVS向けの記事や、 三嶋くんの調べてくれた資料を元に、 香川研究室ローカルの事情も加味して再構成したものです。

このページはまだ間違いがあるかも知れません。みつけたら知らせて下さい。

はじめに

Gitはファイルのバージョンを管理し、コマンドひとつで必要なファイル のコピーを行なってくれるプログラムです。 Gitを利用すれば、以前のバージョンが記録されているので、 間違った更新をしてしまったときや記憶装置の障害があったときなどにも、 以前のバージョンを取り戻すことができます。 また、複数のコンピュータで作業をするときのファイルのコピーにも便利です。 同じようなバージョン管理システムと呼ばれているソフトウェアに CVSや Subversionといったものがあります。

一般に、バージョン管理システムは、数人で共同でプログラムを作成するときに、 更新の衝突が起こらないようにするために開発されたものです。 しかし、一人で使っても便利なプログラムです。 衝突とは、ある人が更新した部分を他の人が(誤って)古いバージョンのものに戻してしまう、 といった現象を指します。

バージョン管理システムはリポジトリ(repository・倉庫)と呼ばれる場所に、 以前のバージョンの情報を含めたすべてのファイルの情報を貯蔵します。 バージョン管理システムのなかでも Gitは分散バージョン管理システムと呼ばれます。 ネットワークに接続していない環境でも、 各コンピュータがリポジトリを持っているため、 バージョン管理システムの機能を利用できるという特徴があります。

Gitのインストール

研究室のサーバ ymir (ymir.eng.kagawa-u.ac.jp)には既にGitがインストールされています。 ここでは、Gitの Windows環境でのインストール方法を説明します。

Cygwinを使う場合

Windowsでは、Cygwinに入っている Gitを使いましょう。Cygwinとは Windows環境に移植されたUNIXのソフトウェアを集めたパッケージです。 (msysGitという Cygwinに基づかないバージョンもあるようですが、ここでは取り上げません。)

Cygwinはhttp://www.cygwin.com/ からダウンロードできます。「Install Cygwin now」というアイコンを クリックするとダウンロードが始まります。ダウンロードした setup.exe というプログラムを実行するとインストールが始まります。 途中 “Choose A Download Site” というところで追加のファイルを ダウンロードするサイトを選ぶ必要があります。 適当な日本のサイトを選んでおけば良いでしょう。 (ただし、どうも途中でフリーズするサイトがあるようなので、 そのばあいは一旦キャンセルして、他のサイトでやり直しましょう。)

インストールは基本的に「次へ」を押して行くだけです。途中、 “Select Packages”というところで、 「Devel」のなかの「git」をクリックして、 チェックの入っている状態にしておく必要があります。 また同じところで「Net」のなかの「openssh」もチェックしておきます (すると「openssl」なども同時にチェックの入った状態になるはずです)。

インストールが終了するとデスクトップやスタートメニューの中に、 Cygwinというアイコンができています。これをダブルクリックすると、 GitやSSHのコマンドが実行可能なシェル(Windowsでいうところのコマンドプロンプト)が現れます。

Cygwinの環境では、パスの区切りは Windows流の「¥」ではなく UNIXと同じ「/」であり、 アルファベットの大文字と小文字は区別されることに注意する必要があります。 また、Cygwinの環境ではWindowsのあるフォルダ(既定値では C:¥cygwin¥)をルート(/)としてみなして、 基本的にはその下にあるファイルしか見えないようになっています。 しかし、実は /cygdrive/c という名前で Windowsの C:¥ が見えるようになっています。 これを利用すれば「ドキュメント」の下のディレクトリを Gitで管理することも可能です。

なお安全のため、Gitで管理するファイル名やディレクトリ名は英数字など キーボードから直接打てる文字に限定しておくようにします。漢字などを使うと、 サーバ (UNIX) とクライアント (Windows)の漢字コードの違いで トラブルになる可能性があります。

リポジトリの作成

ここでは、Gitを最初に使う時にしておかなければならない事柄を説明します。 以下の例では、まず自分のPCにGitリポジトリを作成し、その後研究室のサーバ ymir (ymir.eng.kagawa-u.ac.jp)に、gennaiという ユーザでリポジトリのクローンを作成しようとしていると仮定します。

以下では、自分のPC(cygwin)での作業のプロンプトは host1$で、 ymirでの作業のプロンプトは ymir$で表します。

リポジトリの作成

Gitを使うためには何よりも前にリポジトリを初期化する必要があります。 初期化は、リポジトリを作成したいディレクトリに移動して、 initというコマンドを用います。 例えば、mythesisというフォルダでリポジトリを作成したいときは、 次のようにします。

host1$ cd mythesis
host1$ git init  

実はこのとき、作業ディレクトリに リポジトリの実体の .git と いうディレクトリができています。リポジトリはまだ空です。つまり、 履歴を管理しているファイルはまだありません。

その他に以下のようなコマンドの実行を推奨します。

Todo: メッセージのUTF-8化
host1$ git config core.filemode false
host1$ git config core.autocrlf input

Gitの日常的使用

ファイルの追加

作業用ディレクトリに新しいファイルを作成しても自動的にはリポジトリに 登録されません。 ファイルをリポジトリに登録するためには、 addというコマンドを使います。 ディレクトリを追加する場合は、まずディレクトリ自身をaddしてから、 ディレクトリの中にあるファイルをaddする必要があります。

例えば、mythesisというフォルダとその中の thesis.tex, memo.txt, image.png, photo.jpgを追加する場合は、mythesisフォルダに移動して、 次のようなコマンドを入力します。

host1$ git add .
host1$ git add thesis.tex memo.txt image.png photo.jpg
…

なお、実際に新しいファイルがリポジトリに登録されるのは、この後に git commitを行なう時です。

ファイルのコミット

ファイルを新しく追加したり、ファイルを編集した結果、 作業用ディレクトリのファイルの方がリポジトリのファイルより新しくなったとき、 リポジトリに最新版を登録することをコミットといいます。

host1$ git commit -a

というコマンドで、更新されたファイルを自動的に検索し、 リポジトリに登録することができます。 コミットする前にコメントの入力を促すためにエディタが起動されますが、 これが面倒な時は、

host1$ git commit -a -m "Comment Here" 
のように、-m オプションのあとにコメントを指定します。 ちなみにこのコメント中に日本語を使用することはお勧めしません。

.gitignore

C言語などでプログラムを作成するときの.obj, .exeという拡張子のファイルや、 ΤΕΧで論文を作成するときの .dvi, .aux .logファイルなどは、 それぞれ.c.texといった拡張子を持つファイルから生成されるので、 リポジトリに追加する必要のないファイルです。 これらのファイルが存在すると 「リポジトリに追加されていないファイルがありますよ」 というメッセージがいちいち出力されるので、 少しうっとうしいことがあります。 そこで、そのフォルダ(今の実行例では mythesis フォルダ)に .gitignoreというファイルを作成して、 これらのファイルを無視するようにできます。ファイル名の指定には、 下の例のように*を使ったワイルドカードを用いることができます。

.gitignoreファイルの例
*.dvi
*.aux
*.log
*.class
*.obj
*.exe

.gitignoreは再帰的に適用されます。つまり、 トップディレクトリに上のような記述をしておくと、 サブディレクトリの hoge.exe なども無視されます。

ファイルの削除

ファイルの削除は rm というコマンドを用います。

host1$ git rm ファイル名  

もちろんファイルを削除した後は、その変更を commit しておきます。

ファイルを残したいけれど、git の管理対象からは外したいときは、 --cached オプションを使います。

host1$ git rm --cached ファイル名  

ファイルの移動

ファイル名の変更や移動は mv というコマンドを用います。

host1$ git mv memo.txt data.txt

もちろんファイルを移動した後は、その変更を commitしておきます。

リモートリポジトリの作成

ここまでの話だと、1つのコンピュータで作業をしているので、 ファイルを誤って書き換えてしまった、という場合には対処できますが、 ハードディスクがふっ飛んでしまったという場合には対処できません。 サーバにリポジトリのクローンをとっておきましょう。

また、サーバにリポジトリを置いておくと、 あるコンピュータで作業をしてリポジトリを更新し、 別のコンピュータに最新版を取り出して作業を再開する、 といったことが容易になるので、その点でも便利です。

サーバ上のベアリポジトリの作成

ここでは研究室のサーバ ymir (ymir.eng.kagawa-u.ac.jp)に リモートリポジトリを作成します。以下の例では、gennai というユーザが、リポジトリをホームディレクトリの下の gitrepos というディレクトリの下に作るものとします。 ymir にログインして、以下のコマンドを実行します。

ymir$ cd ~/gitrepos
ymir$ mkdir mythesis.git
ymir$ cd mythesis.git
ymir$ git init --bare 

ここで、--bare はベアリポジトリ — つまり作業用ファイルが置かれていない裸のリポジトリ — を作成するオプションです。

ベアリポジトリには .git という拡張子をつける慣習があるようです。

この時点では、ymir上のリポジトリは空です。

ローカルPCでサーバの登録

ローカルPC(host1)の Cygwin に戻って作業します。 mythesisフォルダに移動し、以下のコマンドを実行します。

まず、あとのキー入力を省略するために、 サーバリポジトリのURLなどを設定ファイルに記録しておきます。

host1$ git remote add origin gennai@ymir.eng.kagawa-u.ac.jp:gitrepos/mythesis.git 
host1$ git config branch.master.remote origin
host1$ git config branch.master.merge refs/heads/master

この設定をしたあとで、下に述べる pushをすると、リポジトリがサーバにも送られます。

ファイルのプッシュ(最初)

ymirにリポジトリの最初の内容を転送するには push -u します。

host1$ git push -u origin master

これで、これまでローカルに作成していたリポジトリが、 サーバにも送られました。

別のPCでリポジトリのクローン作成

サーバ (ymir.eng.kagawa-u.ac.jp)に置いたリモートリポジトリをさらに別の PC (host2) にクローンしましょう。

host2$ git clone gennai@ymir.eng.kagawa-u.ac.jp:gitrepos/mythesis.git mythesis 

これで、host2にリポジトリと作業ファイルがクローンされ、 この PCで作業を再開することができます。

リモートリポジトリの日常的使用

ファイルのプルとプッシュ

ローカルにあるファイルが古く、リモートリポジトリに最新版がある場合、 リモートリポジトリから最新版を取ってくる必要があります。 例えば、家のPCで作業して pushした結果を大学のPCで取出す場合などです。

host2$ git pull

というコマンドで、 ローカルPCのリポジトリと作業用ファイルを最新のものにすることができます。

逆に、ローカルリポジトリで作業をし、最新版を commitした場合、 その変更をリモートリポジトリに送る必要があります。 これをするのは、先ほどリモートリポジトリを作成するときに使用した pushコマンドです。

host2$ git push

これ以降は、host1でも host2でも

host?$ git push

で、ローカルリポジトリに commitした変更をサーバにも転送し、

host?$ git pull

で、サーバのリモートリポジトリにある変更をローカルリポジトリにマージすることになります。

競合の修正

このように複数の場所で編集を行なう場合、編集を行なう前に必ず pull をしておきます。また編集をし終ったら必ず commit して push します。 もし、編集作業後の commit, push を忘れると、 2つの場所にあるファイルのどちらが最新版かわからなくなってしまいます。

例えば thesis.tex というファイルを host1 で編集し、 commit, push を忘れていたとします。 そのあと host2 で別の編集して commit し、再び host1 に戻って commit, push しようとすると、Git は次のようなエラーを報告し、 サーバに push できなくなります。

host1$ git push
cvs commit: Examining .
To gennai@ymir.eng.kagawa-u.ac.jp:gitbase/mythesis.git
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to 'gennai@ymir.eng.kagawa-u.ac.jp:gitbase/mythesis.git'

このような時は先に pullします。

host1$ git pull
gennai@ymir.eng.kagawa-u.ac.jp's password: 
Auto-merging thesis.tex
CONFLICT (content): Merge conflict in thesis.tex
Automatic merge failed; fix conflicts and then commit the result.

すると、上のようにリモートリポジトリと作業ディレクトリにあるファイルに 矛盾があることを報告してくれます。このとき作業ディレクトリにある thesis.texを見ると、食い違いがあった場所は次のように 「<<<<<<<」と「=======」と 「>>>>>>>」に囲まれた形で示されています。

…
<<<<<<< HEAD:thesis.tex
ABCはDEFである。
=======
ZYXはWVUである。
>>>>>>> 4fa914d097bc5f293edb6c9f6c7d8c29403bc6b8:thesis.tex
…

このときは手作業で修正(どちらかを選択するか、マージする)して、 「<<<<<<<」と「=======」と 「>>>>>>>」を消し、 commit, pushする必要があります。

ブランチの使い方

履歴を枝分かれさせることができます。 安定しているバージョンをメンテナンスしつつ、 劇的な変更を行なう場合などに使用します。 “枝”のことをブランチと言います。

ブランチの確認

host1$ git branch

新しいブランチの作成

host1$ git checkout -b ブランチ名

これで新しいブランチを作成すると同時にそのブランチに移動します。

新しいブランチをプッシュ

最初だけは、リモートリポジトリの名前 (origin) とブランチ名を指定する必要があります。

host1$ git push origin ブランチ名

これでリモートリポジトリにも新しいブランチが作成されます。

2回目以降は単に、git pushで構いません。

host1$ git push

ブランチの移動

host1$ git checkout ブランチ名

ブランチのマージ

host1$ git checkout master
host1$ git merge ブランチ名

おわりに

ここで説明した事柄で Gitの利用法の95%は説明できていると思います。しかし、 いざというときには以前のバージョンの取出し方なども必要になります。 こういう使い方を知りたい場合は、以下のリンクや本を参考にしてください。

参考リンク

ToDo

以下の話題については、状況が整いしだい内容を追加する予定です。

Eclipse からの Git の利用法(EGit プラグイン)

Eclipse のプロジェクトを Git リポジトリに入れるときは、以下のような理由から、 プロジェクトディレクトリそのものではなく、プロジェクトディレクトリの親ディレクトリをリポジトリのルートディレクトリにするほうが良いです。

複数のリポジトリを一つにまとめるには

もともと別々のリポジトリとして管理していたファイルを一つにまとめたくなるときもあります。

   (まとめ先のリポジトリのディレクトリで)
   mkdir AAA
   (サブディレクトリとダミーファイルを作る)
   pushd AAA
   echo "dummy" > dummy.txt
   git add dummy.txt
   git commit -m "dummy.txt"
   popd

   git remote add AAA the_path_or_url_of_AAA
   git fetch AAA
   git merge -X subtree=AAA AAA/master
   git commit -a -m "message"

GitHub と GitHub クローン

GitHub は、Git のリモートリポジトリの Web ベースのホスティングサービスです。 オープンソースのプロジェクトならば無料で利用することができます。 オープンソースとして公開することに問題があるならば、 GitLab, GitBucket, などの GitHub クローンを自前のサーバーにインストールするか、 Bitbucket など、プライベートリポジトリを持てるサービスを利用します。 (現時点では Bitbucket をお薦めします。)

Code Review システム

(工事中)


Koji Kagawa