Gitは分散型のバージョン管理システムになります。GitはSubversionのような集中型のバージョン管理システムと異なり、ファイルのすべての変更履歴をそれぞれのマシンが持ちます。そのため、リポジトリを管理しているサーバーにアクセスできなくても、プロジェクトの履歴を確認することができます。
目次
Gitのインストール
Linuxの場合はパッケージ管理ツールを利用するのが簡単です。
例えば、apt-getを利用する場合は以下のコマンドでインストールを行うことができます。
sudo apt-get install git-all
または、Gitの基本的な機能のみをインストールする場合、
sudo apt-get install git
sudo apt-get install git-daemon-sysvinit
また、Windowsの場合はGitの公式サイトよりインストーラをダウンロードすることができます。
Gitの初期設定
Gitのコンフィグファイルについて、Linuxの場合、全てのユーザに対して、/etc/gitconfigで設定できます。コマンドを用いて設定する場合、例えば、
sudo git config --system <設定したい項目>
で設定を行うことができます。
個人のユーザに対しては ~/.gitconfig または ~/.config/git/config で設定できます。コマンドを用いて設定する場合、例えば、
git config --global <設定したい項目>
で設定を行うことができます。
単一のリポジトリの場合に対しては .git/config で設定できます。コマンドを用いて設定する場合、例えば、
git config <設定したい項目>
または
git config --local <設定したい項目>
で設定を行うことができます。
ユーザ名とメールアドレスを設定
Gitを使用する際の初期設定として、ユーザ名とメールアドレスを設定します。ユーザ名やメールアドレスは誰がリポジトリに書き込んだかの情報としてよく見る事になるでしょう。
ここでは以下の設定を使用します。
1 2 |
git config --global user.name 'LcnLinux' git config --global user.email '[email protected]' |
上の設定は、設定例としてのユーザ名と架空のメールアドレスを使用しています。
実際に使用する場合は、自分のユーザ名とメールアドレスを設定してください。
また、設定の内容を確認する場合は以下のコマンドが利用できます。
1 2 3 |
プロンプト文字を設定
bashでは環境変数PS1を変更することでプロンプトの文字を変更することができます。
Gitをインストールした場合、__git_ps1関数が設定されます。
__git_ps1関数を用いてプロンプトの文字を設定するとGitを使用するときに現在のブランチを表示できます。
git-prompt.shの設定例として、
1 |
PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' |
があります。これを設定すると以下のようにユーザ名、ホスト名、カレントディレクトリ名、現在のブランチが表示されます。
1 2 |
$ PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' [[email protected] test_git (master)]$ |
以降のコマンド例では、PS1の設定を
1 2 |
$ PS1='$(__git_ps1 "[%s]")\$ ' [master]$ |
にし、Gitのリポジトリがあるディレクトリのときに、プロンプトの文字にブランチ名のみを表示します。また、ディレクトリにGitのリポジトリがない場合は、$の記号のみがプロンプトの文字として表示されます。
Gitの簡単な操作
Gitには多くのサブコマンドがあります。Gitの操作はサブコマンドを利用し操作できます。ここでは、Gitの簡単な操作としてリポジトリの作成、リポジトリのクローン、Gitでの簡単なファイル管理の方法を確認します。
リポジトリの作成
Gitでファイルを管理するにはリポジトリを作成しなければなりません。リポジトリを作成する方法は、大きく2つあります。
1つ目は空のリポジトリを作成する方法です。
2つ目は既存のリポジトリから複製して、ローカル環境にリポジトリをコピーする方法になります。
空のリポジトリの作成
(git init)
空のリポジトリを作成するには、git initコマンドを利用することで空のリポジトリ(.gitディレクトリ)を作成することができます。
.gitディレクトリにはGitで保存したファイルのデータの実体、ブランチや特定のバージョンへの参照等のメタ情報が管理されています。
git initの簡単な構文は以下のようになります。
git init [option]... [directory]
directoryを省略した場合、基本的にカレントディレクトリに.gitディレクトリを作成します。もし、環境変数GIT_DIRが設定されている場合は環境変数GIT_DIRのパスのディレクトリを作成し、その中に.gitディレクトリを作成します。
directoryを指定した場合、そのディレクトリを作成し、その中に.gitディレクトリを作成します。
コマンド例と実行結果(directoryを省略)
1 2 3 4 |
$ git init Initialized empty Git repository in /home/ubuntu/test_git/.git/ [master]$ ls -A1 .git |
コマンド例と実行結果(directoryを指定)
1 2 3 4 5 6 7 |
$ git init test Initialized empty Git repository in /home/ubuntu/test_git/test/.git/ $ ls -1 test $ cd test/ [master]$ ls -A1 .git |
gitディレクトリの内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[master]$ find .git | file -N -F$'\t:' -f- .git : directory .git/hooks : directory .git/hooks/prepare-commit-msg.sample : POSIX shell script, ASCII text executable .git/hooks/pre-applypatch.sample : POSIX shell script, ASCII text executable .git/hooks/commit-msg.sample : POSIX shell script, ASCII text executable .git/hooks/pre-push.sample : POSIX shell script, ASCII text executable .git/hooks/applypatch-msg.sample : POSIX shell script, ASCII text executable .git/hooks/pre-commit.sample : POSIX shell script, ASCII text executable .git/hooks/pre-rebase.sample : POSIX shell script, ASCII text executable .git/hooks/post-update.sample : POSIX shell script, ASCII text executable .git/hooks/update.sample : POSIX shell script, ASCII text executable .git/HEAD : ASCII text .git/config : ASCII text .git/objects : directory .git/objects/pack : directory .git/objects/info : directory .git/refs : directory .git/refs/heads : directory .git/refs/tags : directory .git/info : directory .git/info/exclude : ASCII text .git/description : ASCII text .git/branches : directory |
.gitディレクトリの内容について簡単な解説を行うと、
.git/hooksは特定の名前のファイルがあると、gitの特定の操作に対してそのファイルを実行するようなファイルが入ります。
.git/HEADはGitでよく使うHEADの参照が記述されています。
.git/configはGitでのリポジトリへの設定が記述されています。
.git/objectsはGitで保存するファイルのデータの実体が入ります。
.git/refsはリポジトリでのブランチやタグやリモートサーバ等の参照情報が入ります。
.git/info/excludeはGit操作で無視したいファイルパターンを記述できます。
.git/descriptionはGitWebを使用するときのリポジトリの説明を記述できます。
manページを参照する場合、.gitディレクトリの内容についての情報はgitrepository-layout(5)にまとめられています。
コマンド例
1 |
man 5 gitrepository-layout |
リポジトリのクローン
(git clone)
既存のリポジトリが存在する場合、git cloneコマンドを用いることで既存のリポジトリを複製し、ローカル環境に新しいディレクトリとしてリポジトリを作成することができます。
既存のリポジトリが存在する場所は、リモート環境、ローカル環境のどちらでも指定できます。
git cloneの簡単な構文は以下のようになります
git clone [option]... <repository> [directory]
repositoryは既存のリポジトリの場所を指定します。
リモート環境の場合は、https://example.com/repo.gitやgit://example.com/repo.gitのようなURLを指定できます。
ローカル環境の場合は、ファイルパスまたはfile://のようなURLを指定できます。
directoryは作成されるディレクトリの名前を指定できます。省略されている場合は、複製されるリポジトリからhttps://example.com/repo.gitならばrepoの部分が、/gitrepo/project_name/.gitならばproject_nameの部分が作成されるディレクトリの名前として使用されます。
コマンド例と実行結果
1 2 3 4 5 6 7 8 |
$ ls test $ git clone test/.git clone_test Cloning into 'clone_test'... warning: You appear to have cloned an empty repository. done. $ ls clone_test test |
空ではないリポジトリにするためにfile.txtをリポジトリに保存し、git cloneを行うと以下のようにwarningは表示されません。
コマンド例と実行結果
1 2 3 4 5 6 7 8 9 10 11 |
$ ls test $ git clone test/.git clone_test Cloning into 'clone_test'... done. $ ls clone_test test $ cd clone_test/ [master]$ ls -A1 .git file.txt |
ファイルをGitで管理
git statusコマンドはGitでのファイル管理の状態を確認することができます。例えば初期化した状態のリポジトリの内容を確認すると
1 2 3 4 5 6 |
[master]$ git status On branch master Initial commit nothing to commit (create/copy files and use "git add" to track) |
のように表示されます。まだ何もファイルのバージョンを管理していない(ファイルをコミットしていない)ため、Initial commitのような文字が表示されています。
カレントディレクトリにfile.txtという名前のファイルを作成して、もう一度確認を行うと、
1 2 3 4 5 6 7 8 9 10 11 12 |
[master]$ touch file.txt [master]$ git status On branch master Initial commit Untracked files: (use "git add <file>..." to include in what will be committed) file.txt nothing added to commit but untracked files present (use "git add" to track) |
Untracked filesの場所にfile.txtが表示されます。これはGitがfile.txtは追跡していない(管理していない)という意味になります。
管理していないファイルは、git addコマンドを用いることで、Gitはファイルを管理できます。
1 2 3 4 5 6 7 8 9 10 |
[master]$ git add file.txt [master]$ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: file.txt |
Gitでファイルを管理するのを始めたてのときは、管理に追加したいファイルが多くありますかもしれません。その場合は、.を用いて、カレントディレクトリを指定することでカレントディレクトリ内のサブディレクトリまで一気にファイルを追加することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
[master]$ touch file{1..3}.txt [master]$ mkdir dir [master]$ touch dir/dirfile{1..3}.txt [master]$ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: file.txt Untracked files: (use "git add <file>..." to include in what will be committed) dir/ file1.txt file2.txt file3.txt [master]$ git add . [master]$ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: dir/dirfile1.txt new file: dir/dirfile2.txt new file: dir/dirfile3.txt new file: file.txt new file: file1.txt new file: file2.txt new file: file3.txt |
git addコマンドではファイルを追加した時点でのファイルのデータが一時的に保存されます。git addコマンドをした後にファイルを修正した場合は、git addコマンドをやり直さなければなりません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
[master]$ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: dir/dirfile1.txt new file: dir/dirfile2.txt new file: dir/dirfile3.txt new file: file.txt new file: file1.txt new file: file2.txt new file: file3.txt Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: file.txt [master]$ git add file.txt [master]$ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: dir/dirfile1.txt new file: dir/dirfile2.txt new file: dir/dirfile3.txt new file: file.txt new file: file1.txt new file: file2.txt new file: file3.txt |
しかし、まだリポジトリに保存されていません。
データは一時的に保存がされている状態(ステージングエリアにある状態)で、リポジトリに保存するための前段階になります。ステージングエリアがあることでどのファイルから順番にリポジトリに保存するかを選択できます。リポジトリの歴史の管理方法によっては、どのように修正内容の見ていくかによって変わります。
ステージングエリアにあるファイルを実際にリポジトリに保存するには、git commitコマンドを用います。単純にgit commitコマンドを用いるとエディタが開きます。
エディタの変更は以下のようなコマンドで変更できます。ここではviに変更してます。
1 |
git config --global core.editor vi |
また、環境変数GIT_EDITORを用いることで上の設定より優先して指定したエディタを用いることができます。Bashでは、環境変数の代入をコマンドの最初に付けることで、その環境変数を一時的に利用できます。そのため、エディタを変更するために、
1 |
GIT_EDITOR=vi git commit |
のようにして、git commitコマンドを利用すると指定したエディタを開くことができます。
git commitコマンドでメッセージを書き、そのメッセージを保存して終了したら、リポジトリにファイルを保存できます。
リポジトリにファイルを保存した後はgit logコマンドで、リポジトリに保存した内容を確認できます。
1 2 3 4 5 6 7 8 |
[master]$ git log commit b9a85b85b0a35715908171ba37a6e775080329fc Author: LcnLinux <[email protected]> Date: Sat Mar 24 01:25:37 2018 +0900 add first commit test Add 7 empty files. |
commitの右にあるアルファベットと数字の羅列はハッシュ値になり、gitは、このハッシュ値でファイルのデータやコミット情報などのオブジェクトを管理しています。
より簡潔なログを確認するにはgit logコマンドの--onelineオプションが便利になります。
1 2 |
[master]$ git log --oneline b9a85b8 add first commit test |
また、Gitで管理しているファイルを今後修正した場合、git addコマンドを使ってステージングエリアに登録しなくても、git commitコマンドの-aオプションを用いることで、修正したファイルすべてを自動的にステージングエリアに登録してリポジトリに保存することができます。
また、git commitコマンドの-mオプションを用いると一行でのコメントを記述することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[master]$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: file.txt no changes added to commit (use "git add" and/or "git commit -a") [master]$ git commit -am 'second commit' [master 32f1784] second commit 1 file changed, 1 insertion(+) [master]$ git log --oneline 32f1784 second commit b9a85b8 add first commit test |
また、ファイルを削除し、Gitの管理からもそのファイルを取り除きたい場合は、git rmコマンドが利用できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[master]$ git rm file.txt rm 'file.txt' [master]$ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: file.txt [master]$ ls dir file1.txt file2.txt file3.txt [master]$ git commit -m 'delete file.txt' [master d7e4bf3] delete file.txt 1 file changed, 2 deletions(-) delete mode 100644 file.txt |
git cloneコマンドを用いたファイルのダウンロードについて
git cloneコマンドはファイルをダウンロードするのにもよく利用されます。ファイルのみをダウンロードしたい場合は、--depthオプションを利用すると便利です。
Gitは分散型のバージョン管理システムと呼ばれ、それは個々のマシンがバージョン管理のすべての歴史をコピーするためです。
しかし、ファイルのダウンロードのみしたい場合はそのようなバージョン管理のすべての歴史はいらないので、--depthオプションでどこまでの歴史がほしいかを指定するとファイルのダウンロード時間を短縮できます。
git clone --depth 1 <repository>
例えば、Gitを使用して、Gnu Coreutilsのソースコードのダウンロード時間を見てみます。
コマンド例と実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
$ time git clone --depth 1 https://git.savannah.gnu.org/git/coreutils.git Cloning into 'coreutils'... remote: Counting objects: 1157, done. remote: Compressing objects: 100% (1074/1074), done. remote: Total 1157 (delta 419), reused 281 (delta 73) Receiving objects: 100% (1157/1157), 1.80 MiB | 588.00 KiB/s, done. Resolving deltas: 100% (419/419), done. Checking connectivity... done. real 0m8.065s user 0m0.510s sys 0m0.264s $ rm -rf coreutils $ time git clone https://git.savannah.gnu.org/git/coreutils.git Cloning into 'coreutils'... remote: Counting objects: 172514, done. remote: Compressing objects: 100% (40253/40253), done. remote: Total 172514 (delta 131931), reused 172483 (delta 131914) Receiving objects: 100% (172514/172514), 32.30 MiB | 659.00 KiB/s, done. Resolving deltas: 100% (131931/131931), done. Checking connectivity... done. real 1m7.690s user 0m20.372s sys 0m4.072s |
最初は--depthオプションで1を指定して最新の歴史のみをダウンロードした場合で、ダウンロード時間は約8秒になりました。
次は、--depthオプションを使用せずに全ての歴史をダウンロードした場合で、ダウンロード時間は約68秒になりました。
git cloneコマンドでファイルのみをダウンロードしたい場合は、--depthオプション使用して最新の歴史のみをダウンロードするとダウンロード時間を大幅に短縮できる可能性があるので覚えておくと役立ちます。
コメント