✨ … 最初にここは読んで下さい。あとは必要に応じて読んで下さい。
Git はファイルのバージョンを管理し、 コマンドひとつで必要なファイルのコピーを行なってくれるプログラムです。 Git を利用すれば、以前のバージョンが記録されているので、 間違った更新をしてしまったときや記憶装置の障害があったときなどにも、 以前のバージョンを取り戻すことができます。 また、複数のコンピュータで作業をするときのファイルのコピーにも便利です。
次のようなトラブルを未然に防ぐのに有効です。
PC が故障して、プログラム・データがすべて消えてしまった。
プログラムを改良しようとしてかえって動かなくなってしまった。 以前のバージョンは上書きしてしまい、動作可能なプログラムがなくなってしまった。
バックアップを取ろうとして、 逆に新しいファイルを古いファイルで上書きしてしまった。
同じようなバージョン管理システムと呼ばれているソフトウェアに CVS や Subversion, mercurial (hg), darcs といったものがあります。
一般に、バージョン管理システムは、数人で共同でプログラムを作成するときに、 更新の衝突が起こらないようにするために開発されたものです。 衝突とは、ある人が更新した部分を他の人が(誤って)古いバージョンのものに戻してしまう、 といった現象を指します。 しかし、一人で使っても便利なプログラムです。
バージョン管理システムはリポジトリー(repository・倉庫)と呼ばれる場所に、 以前のバージョンの情報を含めたすべてのファイルの情報を貯蔵します。 バージョン管理システムのなかでも Git は分散バージョン管理システムと呼ばれます。 ネットワークに接続していない環境でも、 各コンピュータがリポジトリーを持っているため、 バージョン管理システムの機能を利用できるという特徴があります。
コースのサーバーの gin (gin.eng.kagawa-u.ac.jp) や stfile (stfile.eng.kagawa-u.ac.jp) には既に Git がインストールされています。ここでは、Git の Windows 環境でのインストール方法を説明します。
Windows の Git クライアントはいくつかありますが、
単に git
コマンドを使うだけならば、Git for Windows が手軽です。
GUI も使いたい場合は SourceTree がお勧めです。
Cygwin を既に使っている人ならば、Cygwin に git を追加インストールするのも良いでしょう。
このページから、 インストーラーをダウンロードして実行してください。Git for Windows は Git のコマンドラインのクライアントです。
インストールが終了するとデスクトップやスタートメニューの中に、 「Git Bash」というアイコンができています。これをダブルクリックすると、 Git のコマンドが実行可能なシェル(Windows でいうところのコマンドプロンプト)が現れます。
Git の GUI をもつクライアントとしては SourceTree をおすすめします。このページから、インストーラーをダウンロードして実行してください。
また、SourceTree から「ターミナル」ボタンをクリックすると、 Git コマンドが使えるコマンドプロンプトを起動できます。
リモートリポジトリーとして GitHub を使う場合は、GitHub Desktop も人気のようです。
(ただし、今のところ、メニューは日本語化できません。)
このページから、インストーラーをダウンロードして実行してください。
Eclipse や IntelliJ IDEA, Visual Studio Code などの統合開発環境にも SourceTree や Git for Windows と同じようなインターフェースで Git を操作する機能が備わっているのが普通です。
コマンドラインのクライアントを使用する場合、 Windows では、Cygwin に入っている Git を使うこともできます。Cygwin とは Windows 環境に移植された UNIX のソフトウェアを集めたパッケージです。
Cygwin は http://www.cygwin.com/
からダウンロードできます。「Install Cygwin」というリンクをクリックして、
setup-x86_64.exe
(64 bit 版の場合)というリンクをクリックすると、
クリックするとダウンロードが始まります。ダウンロードした
setup-x86_64.exe
というプログラムを実行するとインストールが始まります。
途中 “Choose A Download Site” というところで、追加のファイルを
ダウンロードするサイトを選ぶ必要があります。
適当な日本のサイトを選んでおけば良いでしょう。
(ただし、どうも途中でフリーズするサイトがあるようなので、
その場合は一旦キャンセルして、他のサイトでやり直しましょう。)
インストールは基本的に「次へ」を押して行くだけです。ただし途中、 “Select Packages” というところで、 「Devel」のなかの「git」をクリックして、 チェックの入っている状態にしておく必要があります。 また同じところで「Net」のなかの「openssh」もチェックしておきます (すると「openssl」なども同時にチェックの入った状態になるはずです)。
インストールが終了するとデスクトップやスタートメニューの中に、 「Cygwin 〜」というアイコンができています。これをダブルクリックすると、 Git や SSH のコマンドが実行可能なシェル(Windows でいうところのコマンドプロンプト)が現れます。
SourceTree のターミナル、Git Bash や Cygwin の環境では、パスの区切りは
Windows 流の「¥
」ではなく UNIX と同じ「/
」であり、
アルファベットの大文字と小文字は区別されることに注意する必要があります。
また、Cygwin の環境では Windows のあるフォルダ(既定値では
C:¥cygwin64¥
)をルート(/
)としてみなして、
基本的にはその下にあるファイルしか見えないようになっています。
しかし、実は /cygdrive/c
という名前で Windows の
C:¥
が見えるようになっています。
これを利用すれば「ドキュメント」の下のディレクトリーを
Cygwin の Git で管理することも可能です。
なお、最近は(文字コードが UTF-8 に統一されてきているため)ほとんど心配ないと思いますが、 Git で管理するファイル名やディレクトリー名に日本語などを使うと、サーバー (UNIX) とクライアント (通常 Windows) の文字コードの違いで文字化けする可能性があります。はじめは安全のため、Git で管理するファイル名やディレクトリー名は英数字など、キーボードから直接打てる文字に限定し、 まずはあまり重要でないファイルで、日本語の入ったファイル名で問題ないか、確認してください。
ここでは、Git を最初に使う時にしておかなければならない事柄を説明します。
以下では、自分の PC(Git Bash または cygwin)での作業のプロンプトは
mypc$
で、
stfile(などの遠隔のコンピューター)での作業のプロンプトは
stfile$
で表します。
SourceTree などの GUI クライアントを使う場合でも、 コマンドラインとボタンとの対応はすぐにわかると思いますので、 以下ではコマンドラインでの使用法を説明します。 (SourceTree でも「ターミナル」をクリックすると、コマンドを使用できます。)
誰かが作ってくれた既存のリポジトリー(あるいは自分が以前作ったリポジトリー)から始める場合は git clone
コマンドを使います。
yourpc$ git clone some-url
リポジトリーの URL (some-url
) は、作った人に聞くか、
プロジェクトのホームページなどを探すなどして入手します。
自分でリポジトリーを新規作成する場合も、実は先にリモートリポジトリーを作って、(その空のリボジトリーを)clone するほうが楽です。 リモートリポジトリーを作っておくと、あるコンピュータで作業をしてリポジトリーを更新し、 別のコンピュータに最新版を取り出して作業を再開する、 といったことが容易になるので、その点でも便利です。
リモートリポジトリーとしては GitHub や Bitbucket など、 Git のリモートリポジトリーの Web ベースのホスティングサービスを利用することができます。 また、 GitLab, GitBucket, などの GitHub クローンを研究室や自前のサーバーにインストールすることも可能です。
現時点では GitHub か Bitbucket をお薦めします。
GitHub や Bitbucket 上にリポジトリーを新規作成する方法やそれをローカルにクローンする方法は、 それぞれの Web ページに行けばわかるので、ここでは説明を省略します。
リポジトリーをクローンしたあとの最初の設定として、以下のようなコマンドを、リポジトリーを作成したときに実行しておくことを推奨します。
mypc$ git config core.filemode false mypc$ git config core.autocrlf input
前者はファイルモード (rwx) の変更を git が無視するように設定します。 後者は、Windows からファイルをコミットするときだけ、改行コードを変換します。
以下の例では、(あまり使わないかもしれませんが)まず自分の PC にローカルリポジトリーを作成し、その後サーバー
(stfile.eng.kagawa-u.ac.jp)に、gennai
という
ユーザーでリポジトリーのクローンを作成する方法を説明します。
(複数人でリポジトリーを共有する場合、stfile に置く方法は、 ファイルやディレクトリーのパーミッションの設定が必要になるので面倒です。 Bitbucket や GitHub にベアリポジトリーを作成することをお勧めします。)
何よりも前にローカルリポジトリーを初期化する必要があります。
初期化は、リポジトリーを作成したいディレクトリーに移動して
init
というコマンドを用います。
例えば、myproject
というフォルダでリポジトリーを作成したいときは、
次のようにします。
mypc$ cd myproject mypc$ git init
実はこのとき、作業ディレクトリーにリポジトリーの実体の .git
と
いうディレクトリーができています。リポジトリーはまだ空です。つまり、
履歴を管理しているファイルはまだありません。後で紹介する add や commit などの
コマンドを使って履歴を管理するファイルを増やしていくことができます。
しかしローカルリポジトリーだけだと、1つのコンピュータで作業をしているので、 ファイルを誤って書き換えてしまった、という場合には対処できますが、 ハードディスクがふっ飛んでしまったという場合には対処できません。 サーバーにリポジトリーのクローンをとっておきましょう。
ここではサーバー stfile
(stfile.eng.kagawa-u.ac.jp) に
リモートリポジトリーを作成します。以下の例では、gennai
というユーザーが、リポジトリーをホームディレクトリーの下の
gitrepos
という(すでに作成済みの)ディレクトリーの下に作るものとします。
stfile
にログインして、以下のコマンドを実行します。
stfile$ cd ~/gitrepos stfile$ mkdir myproject.git stfile$ cd myproject.git stfile$ git init --bare
ここで、--bare
はベアリポジトリー
(つまり作業用ファイルが置かれていない裸のリポジトリー)
を作成するオプションです。
ベアリポジトリーには .git
という拡張子をつける慣習があるようです。
この時点では、stfile 上のリポジトリーは空です。
リモートリポジトリーを作成したら、
ローカルPC(mypc
)の Git Bash または Cygwin に戻って作業します。
myproject
フォルダに移動し、以下のコマンドを実行してリモートリポジトリーの URL を登録します。
mypc$ git remote add origin gennai@stfile.eng.kagawa-u.ac.jp:gitrepos/myproject.git
※または、次の書式も使えます。
mypc$ git remote add origin ssh://gennai@stfile.eng.kagawa-u.ac.jp:22/home/st20XX/gennai/gitrepos/myproject.git
なお GitHub や Bitbucket にリモートリポジトリーを作成したときは、 サーバーリポジトリーの URL が Web ページのどこかに表示されるはずなのでそれを使用します。
このあとで、下に述べる pushをすると、ローカルリポジトリーの中身がリモートにも送られます。
リモートリポジトリーにローカルリポジトリーの最初の内容を転送するには push -u します。 (最初にリモートリポジトリーを作成して、clone した場合は push -u をする必要はありません。)
mypc$ git push -u origin master
これで、これまでローカルに作成していたリポジトリーが、 サーバーにも送られました。
サーバー (stfile.eng.kagawa-u.ac.jp や Bitbucket)に置いたリモートリポジトリーをさらに別の
PC (yourpc
) にクローンしましょう。
yourpc$ git clone gennai@stfile.eng.kagawa-u.ac.jp:gitrepos/myproject.git
これで、yourpc
にリポジトリーと作業ファイルがクローンされ、
この PCで作業を再開することができます。
作業用ディレクトリーに新しいファイルを作成しても自動的にはリポジトリーに
登録されません。
ファイルをリポジトリーに登録するためには、
add
というコマンドを使います。
ディレクトリーを追加する場合は、
ディレクトリーの中にあるファイルを add する必要があります。
例えば、myproject
というフォルダとその中の
memo.txt
, image.png
,
photo.jpg
を追加する場合は、myproject
フォルダに移動して、
次のようなコマンドを入力します。
mypc$ git add memo.txt image.png photo.jpg
なお、実際に新しいファイルがリポジトリーに登録されるのは、この後に
git commit
を行なう時です。
ファイルを新しく追加したり、ファイルを編集した結果、 作業用ディレクトリーのファイルの方がリポジトリーのファイルより新しくなったとき、 リポジトリーに最新版を登録することをコミットといいます。
mypc$ git commit -a
というコマンドで、更新されたファイルを自動的に検索し、 リポジトリーに登録することができます。 コミットする前にコメントの入力を促すためにエディターが起動されますが、 これが面倒な時は、
mypc$ git commit -a -m "Comment Here"
のように、-m
オプションのあとにコメントを指定します。
ちなみにこのコメント中に日本語を使用する場合、文字コードが UTF-8
になっていることを確認してください。それが確認できない場合は、
文字化けの可能性があるため、日本語を使うことはお勧めしません。
(cygwin の場合、echo $LANGとして、
ja_JP.UTF-8
と表示されれば OK です。また、SourceTree からコミットすると、UTF-8 になるようです。)
.gitignore
C 言語などでプログラムを作成するときの .obj
,
.exe
という拡張子のファイルや、
ΤΕΧで論文を作成するときの
.dvi
, .aux
.log
ファイルなどは、
それぞれ .c
や .tex
といった拡張子を持つファイルから生成されるので、
リポジトリーに追加する必要のないファイルです。
これらのファイルが存在すると
「リポジトリーに追加されていないファイルがありますよ」
というメッセージがいちいち出力されるので、
少しうっとうしいことがあります。
そこで、そのフォルダ(今の実行例では myproject
フォルダ)に
.gitignore
というファイルを作成して、
これらのファイルを無視するようにできます。ファイル名の指定には、
下の例のように *
を使ったワイルドカードを用いることができます。
.gitignore
ファイルの例
*.dvi *.aux *.log *.class *.obj *.exe
.gitignore
は再帰的に適用されます。つまり、
トップディレクトリーに上のような記述をしておくと、
サブディレクトリーの hoge.exe
なども無視されます。
余計なファイルをリポジトリーに追加してしまったとき、
ファイルの削除は rm
というコマンドを用います。
mypc$ git rm ファイル名
もちろんファイルを削除した後は、その変更を commit しておきます。
git の管理対象からは外したいけれど、ファイルを残しておきたいときは、
--cached
オプションを使います。
mypc$ git rm --cached ファイル名
ファイル名の変更や移動は mv
というコマンドを用います。
mypc$ git mv memo.txt data.txt
もちろんファイルを移動した後は、その変更を commit しておきます。
リポジトリーの状況を確認するためには、status
というコマンドを用います。
mypc$ git status
どのファイルが add されていないか、commit されていないか、 などがわかるように表示されます。
ログ(過去の履歴を見るには log
コマンドを使います。
次のような形式で、commit したときのメッセージと日時、ハッシュ値が表示されます。
mypc$ git log commit ad653f345115e12d2645eec1e4a85910d97e7e47 Author: XXXX YYYY Date: Fri Dec 16 00:17:12 2016 +0900 debug XXX commit e0f42d5eb270214ddbcf4a194fde017400556286 Author: XXXX YYYY Date: Fri Dec 9 23:50:40 2016 +0900 code cleaning commit aaaed38c2e3711df09610fc4c912e8d163135c11 Author: XXXX YYYY …
ハッシュ値というのは上記の ad653f345115e12d2645eec1e4a85910d97e7e47
,
e0f42d5eb270214ddbcf4a194fde017400556286
などで、各 commit
に固有の整数値です。
過去のバージョンのファイルを取り出すためには、 checkout
というコマンドを用います。
mypc$ git checkout ハッシュ値
ハッシュ値は git log
コマンドで得られる、各コミット
に固有の整数値です。
ハッシュ値をフルに指定する必要はありません。ハッシュ値の上位の桁の、
他のハッシュ値と区別できるだけの長さを与えれば十分です。
なお、git checkout
を用いて、過去のバージョンに戻したとき、
そこから、commit
, add
などの操作をしないようにします。
ファイルの中身を調べる、ファイルを編集してテストする(ただし、commit
しない)、リポジトリー外にファイルのコピーをとる、などに留めてください。
(git のさらに深い知識がないと元の状態に戻せなくなります。)
(重要) 過去のバージョンから、最新のバージョンにまた戻すときは、 次のコマンドを用います。
mypc$ git checkout master
過去のバージョンを一時的に取り出すのではなく、直前のコミットを打ち消して、
一つ前のバージョンに戻したいときは revert
というコマンドを用います。
mypc$ git revert ハッシュ値
ハッシュ値は git log
コマンドで得られる、直前のコミットの値です。
revert
は直前のコミットをなかったことにするわけではなく、
逆向きの編集をした、という新しいコミットを追加します。
コミットを完全になかったことにして、履歴まで消してしまうコマンド(reset
)もあるにはあるのですが、
危険度が高いのでここでは紹介しません。
Todo: amend
というコマンドを用います。
ハッシュ値は覚えにくいので、tag コマンドで別名をつけておくことができます。
mypc$ git tag ver0.1
このタグを checkout コマンドなどのハッシュ値の代わりに用いることができます。
ローカルにあるファイルが古く、リモートリポジトリーに最新版がある場合、 リモートリポジトリーから最新版を取ってくる必要があります。 例えば、家の PC で作業して push した結果を大学の PC で取出す場合などです。 この操作を pull と言います。
yourpc$ git pull
というコマンドで、 ローカル PC のリポジトリーと作業用ファイルを最新のものにすることができます。
逆に、ローカルリポジトリーで作業をし、最新版を commit した場合、 その変更をリモートリポジトリーに送る必要があります。 これをするのは、先ほどリモートリポジトリーを作成するときに使用した push コマンドです。
yourpc$ git push
これ以降は、mypc でも yourpc でも
anypc$ git push
で、ローカルリポジトリーに commit した変更をサーバーにも転送し、
anypc$ git pull
で、サーバーのリモートリポジトリーにある変更をローカルリポジトリーにマージすることになります。
このように複数の場所で編集を行なう場合、編集を行なう前に必ず pull をしておきます。また編集をし終ったら必ず commit して push します。 (ただし、中途半端な状態—例えばプログラムに明らかなバグがある状態—で push するのは良くないので、後述するブランチを使います。) もし、編集作業後の commit, push を忘れると、 2つの場所にあるファイルのどちらが最新版かわからなくなってしまいます。
例えば thesis.tex
というファイルを mypc で編集し、
commit, push を忘れていたとします。
そのあと yourpc で別の編集して commit し、再び mypc に戻って
commit, push しようとすると、Git は次のようなエラーを報告し、
サーバーに push できなくなります。
mypc$ git push
cvs commit: Examining .
To gennai@stfile.eng.kagawa-u.ac.jp:gitbase/myproject.git
! [rejected] master -> master (non-fast forward)
error: failed to push some refs to 'gennai@stfile.eng.kagawa-u.ac.jp:gitbase/myproject.git'
このような時は先に pull します。
mypc$ git pull
gennai@stfile.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 する必要があります。
履歴を枝分かれさせることができます。 安定しているバージョンをメンテナンスしつつ、 変更を行なう場合などに使用します。 “枝”のことをブランチ (branch) と言います。
複数人でプロジェクトを編集するとき、各個人はブランチを作成して、 そのブランチに対してファイルの編集を行います。そして、修正がまとまってから (例えば、ある機能が完成して、デバッグも一通り終えてから) “幹”にマージします。このやり方で、 他の人に中途半端な状態を見せないようにすることができます。
最初にもともとできているブランチには master という名前がついています。 (なお、GitHub では 2020 年 10 月から最初のブランチの名前は main に変更されています。 しかし、このページでは最初のブランチの名前は master という前提で説明します。)
次のコマンドで現在のブランチを確認できます。
mypc$ git branch
mypc$ git checkout -b ブランチ名
これで新しいブランチを作成すると同時にそのブランチに移動します。
ブランチを移動するには、以下のコマンドを使います。
mypc$ git checkout ブランチ名
最初だけは、リモートリポジトリーの名前 (origin
)
とブランチ名を指定する必要があります。
mypc$ git push origin ブランチ名
これでリモートリポジトリーにも新しいブランチが作成されます。
2回目以降は単に、git push
で構いません。
mypc$ git push
pull
ではなくて、checkout
を使うことに注意してください。
まず fetch
コマンドを用いて、リモートリポジトリーの内容をローカルに持って来ます。
yourpc$ git fetch
次に、通常の checkout
コマンドで新しく取ってきたブランチに移動します。
yourpc$ git checkout ブランチ名
ブランチでの修正がまとまったら、“幹” にマージします。
merge
というコマンドを使用します。以下の例は、master
ブランチにマージする場合です。
mypc$ git checkout master mypc$ git merge ブランチ名
Eclipse のプロジェクトを Git リポジトリーに入れるときは、以下のような理由から、
リポジトリーのルートディレクトリーそのものを
プロジェクトディレクトリーにするのではなく、
リポジトリーのルートディレクトリーの子ディレクトリーとして
プロジェクトディレクトリーを作るほうが良いです。
(つまり、.git
というディレクトリーと同じ階層に、
プロジェクトディレクトリーがあり、その下に .project
というファイルができる。)
.git
の下を読みに行って、プロジェクトのオープンに時間がかかる。リポジトリーのルートディレクトリーそのものをプロジェクトディレクトリーにしてしまった場合は、
新しくサブディレクトリーとして、プロジェクトディレクトリーを作成し、
git mv
コマンドを使って、リポジトリーのルートディレクトリーの直下の .git
以外の各ファイルを新しく作成したサブディレクトリーの下に移動します。
もともと別々のリポジトリーとして管理していたファイルを一つにまとめたくなるときもあります。 ここでは、あるリポジトリー A のサブディレクトリー dir に、別のリポジトリー B の内容をまるまる持って来ることにします。
(まず、必要ならば、まとめ先のリポジトリー A のディレクトリー構成を変更しておきます。)
次のコマンドでサブディレクトリー subdir に、リポジトリー B の master の内容がコピーされます。
git subtree add --prefix=subdir the_path_or_url_of_B_repository master
このあとで、また必要に応じてディレクトリー構成を整えます。
ここで説明した事柄で Git の利用法の 95% は説明できていると思います。しかし、 いざというときにはもっと高度な使い方が必要になります。 こういう使い方を知りたい場合は、以下のリンクや書籍などを参考にしてください。
以下の話題については、状況が整いしだい内容を追加する予定です。
コミットログを入力するときに文字コードを統一しないと文字化けします。UTF-8 に統一しましょう。 やり方がわからないときはコミットログは英語にしておきましょう。