git について
プログラミングに限らずファイルを更新していくとき、過去ファイルとの変更点比較や、以前の状態に復活させたいときのために最新のファイルを維持しつつ、ファイルを更新していくことがよくある。
そのとき、よくやるのが、ファイル名+日付(yymmdd_file.txt)とか、ファイル名+番号(001_file.txt)とか。
ファイルをリネームして上書きしないようにバックアップしておいて、本ファイルを更新していく感じ。
当然、手間がかかるし、「昔の対応に戻したい」というときや、「この対応はいつ入れたのか思い出したい」と言うときに、更新したものが常に管理された状態であればまだましだが、管理されて無ければ調べるだけでもかなり労力が必要となるし、そのあとの対応での間違いも起こりやすい。さらに複数人で作業しているとなるとリスクが跳ね上がる。
こういう場合に解決をしてくれるのがバージョン管理システム。
git は分散型バージョン管理システム。
対して、SVN、subversion などは集中型バージョン管理システム。
リポジトリ(変更を管理する情報が入った倉庫、管理サーバー)が1箇所にあり、そこにユーザーそれぞれがアクセスし、情報の取得・更新を行う方式。
git のような分散型は、複数人で共有するリポジトリ(リモートリポジトリ)と、ユーザー1人1人に作業用リポジトリ(ローカルリポジトリ)があり、普段の作業はユーザーがそれぞれのローカルリポジトリ上で変更を管理する。
他へ公開しても良い状態になれば、リモートリポジトリに対してアップする。
逆にリモートリポジトリからは更新が必要となれば、各ユーザーのタイミングでローカルリポジトリへ反映することができる。
集中型であれば、リポジトリはネットワークを介して接続する場面が多いが、ローカルリポジトリであればユーザー自身のPC上に管理サーバーあるのと同じなので、PCがネットワークに接続されていなくてもファイル管理状態を更新することができ、安心して作業ができる。また、他者へ公開する前にローカルで変更管理を行いながら、しっかり対応内容を確認してからリモートリポジトリへ公開すればいいので、焦って中途半端な状態で、他者へ公開する必要もない。
インストール
端末で実行する。
$ sudo apt-get install git
確認してみる。
$ git --version git version 2.7.4 |
gitの設定
まず初めに設定するのは、変更をコミットするときに表示される自分の名前と、変更を加えた内容に他者が問い合わせる時に使えるメールアドレスを設定する。
$ git config --global user.name "hoge hogehoge"
$ git config --global user.email "hogehoge@email.com"
確認してみる。
$ git config --global --list user.name=hoge hogehoge user.email=hoge@email.com |
変更したければ、再度コマンドを実行して上書きすればいい。
もうひとつ、gitをターミナルで見るときの出力をカラー表示にする設定をしておく。
$ git config --global color.ui "auto"
config情報(ユーザ全体 global)の設定は、以下のファイル。
~/.gitconfig |
エディタで開けば、直接編集できる。
以降、話を簡単にするために、
1人だけで作業していて、リモートリポジトリを使う必要が無いとしよう。
リポジトリの設定
管理したいディレクトリへ移動する。
既存の管理したいファイルがあるディレクトリか、または、これからファイルを作成していくディレクトリを新規作成し、そのディレクトリへ移動する。
(このディレクトリを "作業ツリー" と呼ぶ)
移動したら、そのディレクトリで実行する。
$ git init
Initialized empty Git repository in <ディレクトリ>/.git/ |
".git" というディレクトリが作られ、リポジトリに必要なすべてのファイルが格納され、管理する準備ができた。
次に管理対象とするファイルは、ディレクトリに存在するとしよう。
管理対象を git に登録する。
更新内容を登録する
登録は2段階で行う。
まず、更新対象とするファイルを選択する。
"add" コマンドを使う。管理対象とするファイル名(ex:index.html)を直接指定する。
$ git add index.html
他にも "*.txt" といったワイルドカードでの指定も可能。
"." を指定すると、サブディレクトリ内も含めた全てのファイルを追加することができる。
次に、先ほど選択したファイルを更新(コミット)することで登録が完了する。
"-m" オプションを付けると、コミットメッセージを指定してコミットすることができる。
$ git commit -m "add new file."
コミットすることで、リポジトリに格納される1つ1つの履歴となる。
履歴を確認してみる。
$ git log commit 9f03003ccb339e39eca4362750b7a8ac45641897 Author: hoge hogehoge <hoge@email.com> Date: Sat Jun 17 15:00:00 2017 +0900 add new file. |
更新の追跡
日々の作業としてファイルを更新していく。
ファイルを更新すると、git はファイルが変化したことを認識している。
変更されたファイルの一覧を表示して、確認してみる。
$ git status On branch master Changes not staged for commit: (use "git add (use "git checkout -- modified: index.html no changes added to commit (use "git add" and/or "git commit -a") |
コミットするためには、変更したファイルを一旦ステージングエリア(インデックスとも呼ぶ)に移動させてからではないとコミットすることができない。
上記では、"Changes not staged for commit"とあり、
「変更されているが、ステージされていない」と教えてくれている。
コミットするために、ステージングエリアに移動させる。
ここでも、"add" コマンドを使えば良い。
$ git add index.html
確認してみる。
$ git status On branch master Changes to be committed: (use "git reset HEAD modified: index.html |
ステージしたら、コミットする。"-m" オプションは複数つけられる。
git commit -m " add <h1>Tag " -m "Hello world"
コミットできたので、確認してみる。
$ git status On branch master nothing to commit, working directory clean |
管理下から変更されたファイルが無くなった。
ログを確認してみる。
オプションの "-1" はコミットの履歴の出力数。最新1個の履歴を表示する。
$ git log -1 commit e81c8d53a2c3006cbd21ca615d70b53d46cf3952 Author: hoge hogehoge Date: Sun Jun 18 10:00:00 2017 +0900 add <h1>Tag Hello world |
普段の作業は、この繰り返しでファイルの変更管理を行う。
ちなみに、コミット時に "-m" オプションを付けなければ、
コミットメッセージを編集するエディタが立ち上がるので、存分にコメントを編集すればよい。
$ git commit

差分の確認
ファイル変更後にステージし、コミットせず、再度ファイルを変更した。
状態を確認してみる。
$ git status On branch master Changes to be committed: (use "git reset HEAD modified: index.html Changes not staged for commit: (use "git add (use "git checkout -- modified: index.html |
同じファイルに対する変更だが、作業ツリーとステージングエリアの2箇所での変更点が出力された。
差分を確認する。
"diff" コマンドを使う。
$ git diff
diff --git a/index.html b/index.html index a1fbdc5..03f5f85 100644 --- a/index.html +++ b/index.html @@ -7,5 +7,6 @@ <body> <h1>Hello world!</h1> <p>こんにちは。</p> + <p>git install 確認</p> </body> </html> |
"diff" コマンドをパラメータ無しで使うと、作業ツリーでの変更差分のみが出力される。
作業ツリーとステージングエリアと比較結果が出力されている。
ステージングエリアとリポジトリとの変更点もあるはずなので、
次に、ステージングエリアとリポジトリとの差分を確認する。
"--cached" パラメータをつける。
$ git diff --cached
diff --git a/index.html b/index.html index 97f1d8a..a1fbdc5 100644 --- a/index.html +++ b/index.html @@ -6,5 +6,6 @@ </head> <body> <h1>Hello world!</h1> + <p>こんにちは。</p> </body> </html> |
作業ツリー・ステージングエリアのすべてと、リポジトリとの差分を確認する。
"HEAD" をつける。"HEAD"は直近のコミットを示す。
$ git diff HEAD
iff --git a/index.html b/index.html index 97f1d8a..03f5f85 100644 --- a/index.html +++ b/index.html @@ -6,5 +6,7 @@  </head>  <body> <h1>Hello world!</h1> + <p>こんにちは。</p> + <p>git install 確認</p>  </body> </html> |
以前のコミット状態に戻す
git resetコマンドを使う。
が、きちんと動きを理解して使わないと、現在の作業内容を消えてしまったりして泣くことになるので、ここでは触れない。改めて git についてまとめたい。
まとめ
ブランチの使い方、リモートリポジトリなど、git の便利な使い方はまだまだある。
ファイル管理が簡単にできるので、とても役立つのだが、
逆に理解せずに安易にコマンドを使うと、せっかく作業したものが消えてしまうので、
ファイルの履歴をさかのぼる方向への更新は気をつけないといけない。
git については理解した部分からまとめて、自分なりの活用マニュアルを作っていきたい。
git ブランチについて
git 変更を一時的に退避 stash
git ブランチを合流するマージ
git ブランチを付け替える
git コミット履歴を変更する
gitサーバーのセットアップ
git コミットを取り消す
git 変更をリセットする
git リモートでの操作
git ファイルの追跡
git リリース準備
git リモートブランチを追加
git チェックアウトをもっと便利に使う
git プロジェクトの構成
git 変更をpatchファイルにする
git コンフリクトに対処する
git 失敗したときの復元