Windows 環境での git(バージョン管理システム/VCS)の使い方等に関する個人的なメモ(自分の学習のためのまとめ)。
公式サイト:http://git-scm.com/
参考にさせていただいたサイト
目次
以下のサイトを参考にさせていただきました。
Git の仕組み/こせきの技術日記
【翻訳】Gitをボトムアップから理解する
以下のサイト(Git for Windows)からダウンロードして、インストール
インストールされた Git Bash を使用
git config ツールで設定する。
個人の識別情報の設定:名前とメールアドレスを設定(必須)
git config --global user.name "James Brown" git config --global user.email "james@brown.com"
メッセージを色分けして表示する設定(オプション)
git config --global color.ui true
git config ツールで設定された値は以下のファイルに保存される。
設定の確認 / 設定の一覧表示
git config -l #または git config --list
$ git help <verb> #または $ git <verb> --help
<verb> はサブコマンド。
git config のヘルプの表示
git config --help
全ての git コマンドの表示。
git --help -a usage: git [--version] [--help] [-C <path>] [-c name=value] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p|--paginate|--no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>] <command> [<args>] available git commands in 'C:\Program Files (x86)\Git/libexec/git-core' add get-tar-commit-id receive-pack add--interactive grep reflog am gui relink annotate gui--askpass remote apply gui--askyesno remote-ext ・・・省略・・・
参考元:ヘルプを見る/Pro Git
Git プロジェクトを取得するには、既存のディレクトリでリポジトリの初期化をするか、既存の Git リポジトリを別のサーバーからクローンする方法の2通りがある。
プロジェクトを git で使用(管理)するには、そのプロジェクトのディレクトリに移動して「git init」で初期化(空のリポジトリの作成、または既存のリポジトリの初期化)する。
git init
$ git init Initialized empty Git repository in C:/xampp/htdocs/git_test/.git/
上記を実行すると .git という名前の新しいサブディレクトリ(隠しフォルダー)が作られ、リポジトリに必要なすべてのファイル (Git リポジトリのスケルトン) がその中に格納される。この時点では、まだプロジェクト内のファイルは一切管理対象になっていない。
既存の Git リポジトリのコピーを取得したい場合には、git clone コマンドを使用する。
リポジトリをクローンするには git clone [url] とする。
Ruby の Git ライブラリである Grit をクローンする例。
$ git clone git://github.com/schacon/grit.git
これは、まず grit というディレクトリを作成してその中で .git ディレクトリを初期化し、リポジトリのすべてのデータを引き出し、そして最新バージョンの作業コピーをチェックアウトする。新しくできた grit ディレクトリには、プロジェクトのファイルが入っている。
grit ではない別の名前のディレクトリにクローンしたいのなら、コマンドラインオプションでディレクトリ名を指定。
$ git clone git://github.com/schacon/grit.git mygrit
このコマンドは先ほどと同じ処理を行うが、ディレクトリ名は mygrit になる。
「ディレクトリでのリポジトリの初期化」または「既存のリポジトリのクローン」により、Git リポジトリを準備して、そのプロジェクト内のファイルの作業コピーを取得することができる。
「MyProject01」という空のディレクトリ(C:\xampp\htdocs\MyProject01)を作成した場合の例。
Git Bash を起動して、「MyProject01」ディレクトリへ移動。
git init を実行
$ cd ../../xampp/htdocs/MyProject01 $ git init Initialized empty Git repository in c:/xampp/htdocs/MyProject01/.git/
index.html というファイルを「MyProject01」ディレクトリに作成し、その後ファイルの状態を「git status」で確認すると以下のように表示される。
$ git status On branch master Initial commit Untracked files: (use "git add <file>..." to include in what will be committed) index.html nothing added to commit but untracked files present (use "git add" to track)
今度は「MyProject02」というディレクトリ(C:\xampp\htdocs\MyProject02)を作成し、その中にindex.html というファイルを作成し、 git init を実行後、「git status」で確認すると以下のように表示される。
$ cd ../MyProject02 $ git init Initialized empty Git repository in c:/xampp/htdocs/MyProject02/.git/ $ git status On branch master Initial commit Untracked files: (use "git add <file>..." to include in what will be committed) index.html nothing added to commit but untracked files present (use "git add" to track)
この時点ではいずれの場合も、index.html は「Untracked files」として表示されている。
これは、Git が「前回のスナップショット (コミット) にはこのファイルが存在しなかった」とみなしたということで、明示的に指示しない限り、Git はコミット時にこのファイルを含めることはない。
次は、そのコピーに対して何らかの変更を行い、適当な時点で変更内容のスナップショットをリポジトリにコミットする。
作業コピー内の各ファイルには 追跡されている(tracked) ものと 追跡されてない(untracked) ものの二通りがある。
また、最初にプロジェクトをクローンした時点では、すべてのファイルは「追跡されている」かつ「変更されていない」状態となる。(チェックアウトしただけで何も編集していない状態のため)
新しいファイルの追跡を開始するには git add コマンドを使用して新しいファイルをプロジェクト(ステージング・エリア)に追加する。
git add index.html
その後、「git status」で確認すると以下のように表示され、ファイルが追跡対象となり、ステージされていることがわかる。
$ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: index.html
“Changes to be committed” 欄に表示されているので、ステージされていると判断できる。
ここでコミットを行うと、git add した時点の状態のファイルがスナップショットとして履歴に書き込まれる。
git add コマンドには色々な意味合いがあり、以下のような場合などに使用する。
すでに追跡対象となっているファイル index.html を変更して status コマンドを実行すると、結果は以下のようになる。
$ 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: index.html no changes added to commit (use "git add" and/or "git commit -a")
index.html ファイルは “Changes not staged for commit” という欄に表示されている。これは、追跡対象のファイルが作業ディレクトリ内で変更されたけれどもまだステージされていないという意味。
ステージするには git add コマンドを実行する。
その後再度 git status を実行すると、結果は以下のようになる。
$ git add index.html $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: index.html
コミットする前に更にここで、index.html ファイルに変更を加えて、再度 git status を実行すると、結果は以下のようになる。
$ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: index.html 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: index.html
index.html ファイルは“Changes to be committed” 欄と “Changes not staged for commit” 欄の両方に表示されている。
これは、Git は git add コマンドを実行した時点の状態のファイルをステージするということ。
ここでコミットをすると、実際にコミットされるのは git add を実行した時点の index.html であり、git commit した時点の作業ディレクトリにある内容とは違うものになる。
git add した後にファイルを変更した場合に、最新版のファイルをステージしなおすにはもう一度 git add を実行する必要がある。
ワイルドカード
複数のファイルを一度にステージする場合、ワイルドカード(*)が使える。
以下は、全ての html ファイルをステージする例。この場合、クオートで囲む必要がある。
$ git add '*.html'
全てのファイルをステージする例。(ドットのみ)
$ git add .
Git に自動的に追加してほしくない場合や「Untracked files: 追跡されていない」と表示されないようにするには、.gitignore というファイルを作成し、無視させたいファイルのパターンを記述する。
(例)git status を実行すると以下のように表示され、ignoreThis.txt というファイルと log というディレクトリを無視したい場合。
$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) ignoreThis.txt log/ nothing added to commit but untracked files present (use "git add" to track)
vim で .gitignore ファイルを作成
$ vim .gitignore
無視させたいファイルのパターンを記述
.gitignore
#comment コメント ignoreThis.txt log/
git status で確認すると、ignoreThis.txt というファイルと log というディレクトリは無視されている。
$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) .gitignore nothing added to commit but untracked files present (use "git add" to track)
.gitignore ファイルに記述するパターンの規則
変更したけれどもまだステージしていない内容を見るには、引数なしで git diff を実行。このコマンドは、作業ディレクトリの内容とステージングエリアの内容を比較する。
$ git diff diff --git a/index.html b/index.html index 8c1daee..134dcf7 100644 --- a/index.html #変更前 +++ b/index.html #変更後 @@ -5,6 +5,6 @@ <title>My Project01</title> </head> <body> -<p>my test project</p> #ステージングエリアの内容 +<p>my test projectX</p>^M #作業ディレクトリの内容 </body> </html>
次のコミットに含めるステージされた内容を知りたい場合は、git diff –staged(または git diff –cached)を使用。このコマンドは、ステージされている変更と直近(前回)のコミットの内容を比較する。
$ git diff --staged diff --git a/index.html b/index.html index e1ff4aa..8c1daee 100644 --- a/index.html #変更前 +++ b/index.html #変更後 @@ -5,6 +5,6 @@ <title>My Project01</title> </head> <body> -<p>test</p> #直近(前回)のコミットの内容 +<p>my test project</p>^M #ステージされている変更 </body> </html>
ステージングエリアの準備ができたら、変更内容をコミットすることができる。
コミットの対象となるのはステージされたものだけ、つまり追加したり変更したりしただけでまだ git add を実行していないファイルはコミットされず、そういったファイルは、変更されたままの状態でディスク上に残る。
コミットするには git commit を実行する。
$ git commit
git commit を実行すると、デフォルトのエディタ(vim)が立ち上がる。
(git config –global core.editor コマンドで好みのエディタを指定することも可能)
エディタには次のようなテキストが表示される (これは Vim の画面の例)。
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Changes to be committed: # modified: index.html # ~ ~ ~ <\xampp\htdocs\MyProject-1\.git\COMMIT_EDITMSG [unix] (18:27 14/03/2015)1,0-1 All [/code] 「i」キーを押して、インサートモードにして、変更履歴等の情報(メッセージ)を入力後、「Esc」キーを押してコマンドモードに戻り、「:wq」で保存してエディタを終了。(メッセージを入力せず、「:q」で終了するとコミットは行われない。) 何を変更したのかをより明確に知りたい場合は、git commit に -v オプションを指定。そうすると、diff の内容がエディタに表示されるので何を行ったのかが正確にわかる。エディタを終了させると、Git はそのメッセージつきのコミットを作成する(コメントおよび diff は削除される)。 <a class="mpg" href="https://www.webdesignleaves.com/wp/wp-content/uploads/2015/03/git_04.png"><img src="https://www.webdesignleaves.com/wp/wp-content/uploads/2015/03/git_04.png" alt="git_04" width="660" height="394" class="alignnone size-full wp-image-1433" /></a> または、コミットメッセージをインラインで記述することも可能。その場合は、commit コマンドの後で -m フラグに続けてメッセージを記述する。$ git commit -m "commit message test" [master 8744870] commit message test 1 file changed, 1 insertion(+), 1 deletion(-)
git commit を実行すると、「どのブランチにコミットしたのか (master)」「そのコミットの SHA-1 チェックサム (8744870)」「変更されたファイルの数」「そのコミットで追加されたり削除されたりした行数」といった情報が表示される。
ステージングエリアを省略したい場合には、git commit コマンドに -a オプションを指定すると、追跡対象となっているファイルを自動的にステージしてからコミットを行うので、git add を省略できる。
$ 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: index.html no changes added to commit (use "git add" and/or "git commit -a") $ git commit -a -m "added new line" [master 68d7d05] added new line 1 file changed, 1 insertion(+)
プロジェクトに追加されているファイルを Git から削除するには、追跡対象から外し(ステージングエリアから削除し)、そしてコミットする。git rm コマンドは、この作業を行い、そして作業ディレクトリからファイルを削除する。
単に作業ディレクトリからファイルを削除しただけの場合は、git status の出力の中では “Changes not staged for commit” (ステージされていない) 欄に表示される。
$ rm test01.txt #単に作業ディレクトリからファイルを削除 $ git status #“Changes not staged for commit” 欄に表示される On branch master Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: test01.txt no changes added to commit (use "git add" and/or "git commit -a")
git rm コマンドでファイルを追跡対象から外す。(ステージングエリアから削除)。
次にコミットするときにファイルが削除され、追跡対象外となる。
$ git rm test01.txt rm 'test01.txt' $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: test01.txt $ git commit [master 3e99c63] remove test01.txt 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test01.txt $ git status On branch master nothing to commit, working directory clean
変更したファイルをすでにステージしている場合は、-f オプションで強制的に削除しなければならない。
ハードディスク上にはファイルを残しておきたいけれど、もう Git では追跡させたくないというような場合は --cached オプションを使用する。
$ git rm --cached test01.txt rm 'test01.txt' $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: test01.txt Untracked files: (use "git add <file>..." to include in what will be committed) test01.txt $ git commit [master 3031417] removed 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test01.txt $ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) test01.txt nothing added to commit but untracked files present (use "git add" to track)
Git には mv コマンドがあり、Git の中でファイル名を変更したい場合は次のようなコマンドを実行する。
$ git mv file_from file_to
test01.txt を sample01.txt という名前に変更する例。(git status は確認のために実行)
$ git mv test01.txt sample01.txt $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) renamed: test01.txt -> sample01.txt $ git commit -m "change name" [master b3cb6ba] change name 1 file changed, 0 insertions(+), 0 deletions(-) rename test01.txt => sample01.txt (100%) $ git status On branch master nothing to commit, working directory clean
git mv test01.txt sample01.txt は実際には以下を実行したのと同じこと。
$ mv test01.txt sample01.txt $ git rm test01.txt $ git add sample01.txt
コミット履歴を表示させるには git log コマンドを実行する。
$ git log commit c3fe70a5097a09f4f4564de1dd48c60c521ab08f #SHA-1 チェックサム(IDのようなもの) Author: Web Design Leaves <xxxx@webdesignleaves.com> Date: Sun Mar 8 17:48:46 2015 -0400 My initial test commit 2 #コミットの際に入力したメッセージ
デフォルトで引数を何も指定しなければ、そのリポジトリでのコミットを新しい順に表示する。
このコマンドは各コミットについて SHA-1 チェックサム、作者の名前とメールアドレス、コミット日時、コミットメッセージを一覧表示する。
履歴が増えてくるなどして見ずらくなった場合に1行で表示せるには「--oneline」オプションを指定することができる。
$ git log --oneline eee4a99 add more lines d7a8a6d change text and add line e4b5e69 add some text b3cb6ba change name 3031417 removed 3e99c63 remove test01.txt 09dc320 deleted c9ce494 added f01dc07 test 68d7d05 added new line 8744870 commit message test
-p オプションを指定すると、各コミットの diff を表示する。また -3 は、直近の 3 エントリだけを出力する。
$ git log -p -3 commit e4b5e695ebc988a5ed1b03a3bb10adf2803c22f9 Author: Web Design Leaves <xxxx@webdesignleaves.com> Date: Sun Mar 15 11:59:36 2015 -0400 add some text diff --git a/sample01.txt b/sample01.txt index e69de29..2be1882 100644 --- a/sample01.txt +++ b/sample01.txt @@ -0,0 +1 @@ +add some text \ No newline at end of file commit b3cb6bac523485c8ed30cf89fbdf05112f6ab485 Author: Web Design Leaves <xxxx@webdesignleaves.com> Date: Sun Mar 15 11:23:29 2015 -0400 change name diff --git a/sample01.txt b/sample01.txt new file mode 100644 index 0000000..e69de29 diff --git a/test01.txt b/test01.txt deleted file mode 100644 index e69de29..0000000 commit 5bd80b7aadad643e49ae2956c30d90d90256cf21 Author: Web Design Leaves <xxxx@webdesignleaves.com> Date: Sun Mar 15 10:55:24 2015 -0400 test commit diff --git a/test01.txt b/test01.txt new file mode 100644 index 0000000..e69de29
git log -p コマンドのオプション --word-diff を使えば、通常の行単位diffではなく、単語単位のdiffを表示させることが可能。
追加された単語は {+ +} で、削除された単語は [- -] で囲まれて表示される。
$ git log -p --word-diff -2 commit eee4a998718230270878e81789d60b8d2929eb6c Author: Web Design Leaves <xxxx@webdesignleaves.com> Date: Sun Mar 15 12:15:08 2015 -0400 add more lines diff --git a/sample01.txt b/sample01.txt index 781846a..934ae51 100644 --- a/sample01.txt +++ b/sample01.txt @@ -1,2 +1,4 @@ add some words add new line {+more lines^M+} {+more words+} commit d7a8a6dd1e1907cbcbaf99a5b4f8b28ccb36c0f5 Author: Web Design Leaves <xxxx@webdesignleaves.com> Date: Sun Mar 15 12:11:09 2015 -0400 change text and add line diff --git a/sample01.txt b/sample01.txt index 2be1882..781846a 100644 --- a/sample01.txt +++ b/sample01.txt @@ -1 +1,2 @@ add some [-text-]{+words^M+} {+add new line+}
各コミットの変更のあったファイルの統計情報を見たい場合は --stat オプションを指定する。
$ git log --stat -3 commit eee4a998718230270878e81789d60b8d2929eb6c Author: Web Design Leaves <xxxx@webdesignleaves.com> Date: Sun Mar 15 12:15:08 2015 -0400 add more lines sample01.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit d7a8a6dd1e1907cbcbaf99a5b4f8b28ccb36c0f5 Author: Web Design Leaves <xxxx@webdesignleaves.com> Date: Sun Mar 15 12:11:09 2015 -0400 change text and add line sample01.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit e4b5e695ebc988a5ed1b03a3bb10adf2803c22f9 Author: Web Design Leaves <xxxx@webdesignleaves.com> Date: Sun Mar 15 11:59:36 2015 -0400 add some text sample01.txt | 1 + 1 file changed, 1 insertion(+)
コミットの一部だけを表示する以下のようなオプションがある。
オプション | 説明 |
---|---|
-(n) | 直近の n 件のコミットのみを表示 |
- -since, - -after | 指定した日付/時刻以降のCommitDateのコミットのみに制限 |
- -until, - -before | 指定した日付/時刻以前のCommitDateのコミットのみに制限する |
過去二週間のコミットの一覧を取得
$ git log --since=2.weeks
2015/3/15 12:00 ~ 2015/3/15 13:00 のコミットの一覧を取得
$ git log --after="2015-03-15 12:00:00" --before="2015-03-15 13:00:00"
この他にもいろいろなオプションがある。
グラフィカルなツールでコミットの履歴を見たい場合は、Tcl/Tk のプログラムである gitk を使える。
プロジェクトのコマンドラインで gitk と打ち込むと、以下のような画面が表示される。
ウィンドウの上半分に、コミットの履歴が表示され、ウィンドウの下半分には diff ビューアがあり、任意のコミットをクリックしてその変更内容を確認することができる。
「直前のコミットで、追加すべきファイルを忘れてしまいファイルを後から追加する」場合や「直前のコミットのコメントを修正する」場合は、--amend オプションをつけてもう一度コミットする。
$ git commit --amend
このコマンドは、ステージングエリアの内容をコミットに使用。直近のコミット以降に何も変更をしていない場合、スナップショットの内容は同じでありコミットメッセージを変更することになる。
コミットメッセージのエディタが立ち上がり、既に前回のコミット時のメッセージが書き込まれた状態になっているので、編集する。
また、コミットした後、何かのファイルをステージするのを忘れていたのに気づいた場合は次のようにする。
$ git commit -m 'コミットメッセージ' $ git add ステージするのを忘れていたファイル $ git commit --amend
2番目のコミットが、最初のコミットの結果を上書きする。
2つのファイルを変更し、それぞれを別のコミットとするつもりだったが git add . と打ち込んでしまったため両方のファイルステージされてしまった場合、いずれかのファイルのステージを解除したい場合、git status コマンドを実行してみる。
$ git add . $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: index.html modified: sample01.txt
「use "git reset HEAD
index.html を解除するには以下のようにする。
$ git reset HEAD index.html Unstaged changes after reset: M index.html $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: sample01.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: index.html
ファイルに加えた変更を取り消す (直近のコミット時点の状態に戻す) には、git checkout --
git status の出力結果で、ステージされていないファイル一覧の部分に「use "git checkout --
但し、これは危険なコマンドでファイルに加えた変更はすべて消えてしまうので、そのファイルが不要であることが確実な場合のみ、このコマンドを使用するようにする。
$ git checkout -- index.html
参考元:作業のやり直し/Pro Git
タグ機能を使うと、重要なポイントに印をつけることができる。通常この機能は (v 1.0 など) リリースポイントとして使われることが多い。
既存のタグの一覧を表示するには、単に git tag と打つだけ。
(タグをアルファベット順に表示)
$ git tag
パターンを指定してタグを検索することも可能。例えば、 1.4.1 系のタグのみを見たい場合は、以下のようにする。
$ git tag -l 'v1.4.1.*' v1.4.1.1 v1.4.1.2
Git のタグには、軽量 (lightweight) 版と注釈付き (annotated) 版の二通りがある。軽量版のタグは、変更のないブランチのようなものです。特定のコミットに対する単なるポインタでしかありません。しかし注釈付きのタグは、Git データベース内に完全なオブジェクトとして格納されます。チェックサムが付き、タグを作成した人の名前・メールアドレス・作成日時・タグ付け時のメッセージなども含まれます。また、署名をつけて GNU Privacy Guard (GPG) で検証することもできます。一般的には、これらの情報を含められる注釈付きのタグを使うことをおすすめします。しかし、一時的に使うだけのタグである場合や何らかの理由で情報を含めたくない場合は、軽量版のタグも使用可能です。
簡単な方法は、tag コマンドの実行時に -a を指定する。
-m で、タグ付け時のメッセージを指定。注釈付きタグの作成時に -m を省略すると、エディタが立ち上がるのでそこでメッセージをする。
$ git tag -a v0.1 -m "my version 0.1"
タグのデータとそれに関連づけられたコミットを見るには git show コマンドを使用。
$ git show v0.1 tag v0.1 Tagger: User name <user_email_address> Date: Wed Mar 18 18:46:25 2015 -0400 my version 0.1 commit ffc82242c0cceef2538734747de63347f31b9f2c Author: User name <user_email_address> Date: Wed Mar 18 18:31:26 2015 -0400 add more words diff --git a/sample01.txt b/sample01.txt index 934ae51..d87ed50 100644 --- a/sample01.txt +++ b/sample01.txt @@ -2,3 +2,4 @@ add some words add new line more lines more words +another new line addes \ No newline at end of file
過去にさかのぼってコミットにタグ付けすることも可能。コミットの履歴が次のようなものであった場合、特定のコミットにタグをつけるには、そのコミットのチェックサム (あるいはその一部) をコマンドの最後に指定する。
$ git log --pretty=oneline 22c0c0115f0cb3d6d89831c3e0bcf0ab86502bc0 add h2 tag 34d0ee9bd4ed961f2c081e8be9e22419fcdf9a7c delete some texit and add H1 ffc82242c0cceef2538734747de63347f31b9f2c add more words d80a5041cbfe9c110df7a62e15f388f73754c12d add more lines d7a8a6dd1e1907cbcbaf99a5b4f8b28ccb36c0f5 change text and add line e4b5e695ebc988a5ed1b03a3bb10adf2803c22f9 add some text b3cb6bac523485c8ed30cf89fbdf05112f6ab485 change name 5bd80b7aadad643e49ae2956c30d90d90256cf21 test commit 3e99c63cf3aee5f8d62efeb4e9016d45f5031deb remove test01.txt 09dc3201ad4a1763ca5e501e5a5d2456a7698675 deleted (END)
上記の一番最後のコミットにタグをつける例
$ git tag -a v0.01 -m "my version 0.01" 09dc3201
参考元:タグ/Pro Git
git commit を実行すると、
この時点で、Git リポジトリには以下のオブジェクトが作成されている。
なんらかの変更を終えて再びコミットすると、次のコミットには直近のコミットへのポインタが格納される。
新しいブランチを作成すると、単に新たな移動先を指す新しいポインタが作られる。
新しい test ブランチを作る例。
$ git branch test
これで、新しいポインタが作られるが、現時点ではふたつのポインタ(master, test)は同じ位置を指している。
Git は、今どのブランチで作業しているのか知るために、 HEAD と呼ばれる特別なポインタを利用する。つまり HEAD は現在作業しているローカルブランチへのポインタになる。
上記の場合、git branch コマンドは新たにブランチを作成するだけなので、まだ master ブランチにいる。(git branch コマンドはそのブランチに切り替えるわけではない)
ブランチを切り替えるには git checkout コマンドを実行する。
$ git checkout test
これで、HEAD は test ブランチを指すようになる。
ここで別のコミットをする。
$ vim test.html $ git commit -a -m 'made a change'
HEAD が指すブランチが、コミットによって移動する。
test ブランチはひとつ進んだが master ブランチは変わらない。git checkout でブランチを切り替えたときの状態のまま。
master ブランチに戻ってみる。
$ git checkout master
チェックアウトによって HEAD が別のブランチに移動
前述のコマンドは以下の二つの作業をしている。
この時点以降に行った変更は、これまでのプロジェクトから分岐した状態になり、これは、test ブランチで一時的に行った作業を巻き戻したことになる。
つまり、ここから改めて別の方向に進めるということになる。
ふたたび変更を加えてコミットしてみる。
$ vim test.html $ git commit -a -m 'made other changes'
これで、プロジェクトの履歴が二つに分岐した。新たなブランチ(test)を作成してそちらに切り替え、何らかの作業を行い、メインブランチ(master)に戻って別の作業をした状態。
どちらの変更も、ブランチごとに分離している。ブランチを切り替えつつそれぞれの作業を進め、必要に応じてマージすることが可能。
数回のコミットをした状態のプロジェクトで作業をしている場合の例
作業用に新しいブランチ(chg01)を作成する。
ブランチの作成と新しいブランチへの切り替えを同時に行うには、git checkout コマンドに -b スイッチをつけて実行。
$ git checkout -b chg01 Switched to a new branch 'chg01'
これは、次のコマンドを実行したのと同じ。
$ git branch chg01 $ git checkout chg01
そして何らかの作業をしてコミットすると chg01 ブランチが先に進む。このブランチをチェックアウトしているため、HEAD が chg01 ブランチを指している。
$ git commit -a -m 'changed contents [chg01]' [chg01 a97d282] changed contents [chg01] 1 file changed, 1 insertion(+)
ここで、何らかの問題が発生してそちらの作業を優先しなければならなくなったとする。
この場合、Git を使っていれば、これまでの作業をいったん元に戻してから改めて優先度の高い作業にとりかかるなどという作業も不要。ただ単に、master ブランチに戻るだけ。
但し、注意すべき点がある。
作業ディレクトリやステージングエリアに未コミットの変更が残っている場合、それがもしチェックアウト先のブランチと衝突する内容ならブランチの切り替えはできない。ブランチを切り替える際には、クリーンな状態にしておく必要がある。(これを回避するには、stash およびコミットの amend という処理を行うという方法もある)
この例の場合、変更をコミットし終えているので、master ブランチに戻ることができる。
$ git checkout master Switched to branch 'master'
これにより、作業ディレクトリは新しいブランチ(chg01)での作業前の状態に戻る。
これは Git が作業ディレクトリの状態をリセットし、チェックアウトしたブランチが指すコミットの時と同じ状態にするということで、そのブランチにおける直近のコミットと同じ状態にするため、ファイルの追加・削除・変更を自動的に行う。
次に、優先度の高い作業を行うため、優先度の高い作業用に hotfix ブランチを作成し、作業をそこで進めることにする。
$ git checkout -b hotfix Switched to a new branch 'hotfix'
作業が完了し、変更をコミット。
$ git commit -a -m 'hotfix: fixed layout issue' [hotfix 73eb219] hotfix: fixed layout issue 1 file changed, 1 insertion(+)
修正が問題ないことを確認したら、master ブランチにそれをマージしてリリースする。
この際使用するのが git merge コマンド。
$ git checkout master $ git merge hotfix Updating 35c5302..73eb219 Fast-forward index.html | 1 + 1 file changed, 1 insertion(+)
このマージ処理で "Fast-forward" というフレーズが表示されている。
これはマージ先のブランチ(master)が指すコミットがマージ元(hotfix)のコミットの直接の親であるため、Git がポインタを前に進めたため。
あるコミットに対してコミット履歴上で直接到達できる別のコミットをマージしようとした場合、Git は単にポインタを前に進めるだけで済ませ、この処理のことを "fast forward" と言う。
変更した内容が、これで master ブランチの指すスナップショットに反映されたので変更をリリースできる。
マージした結果、master ブランチの指す先が hotfix ブランチと同じ場所になる。
master ブランチが hotfix ブランチと同じ場所を指しているので、もはや hotfix ブランチは不要なので、 hotfix ブランチを削除しておく。
削除するには git branch で -d オプションを指定します。
$ git branch -d hotfix Deleted branch hotfix (was 73eb219).
先ほどまで作業をしていたブランチ(chg01)に戻り、作業を続ける。
$ git checkout chg01 Switched to branch 'chg01'
作業が完了し、コミット。
$ git commit -a -m 'finished the change [chg01]' [chg01 fabf224] finished the change [chg01] 1 file changed, 1 insertion(+), 1 deletion(-)
ここで、hotfix ブランチ上で行った作業は chg01 ブランチには含まれていないことに注意。
もしそれを取得する必要がある場合、git merge master で master ブランチの内容を chg01 ブランチにマージ(統合)する。
またはそのまま作業を続け、いつか chg01 ブランチの内容を master に適用することになった時点でマージ(統合)する。
ブランチ(chg01)での作業を終えて、master ブランチにマージする準備ができたら、マージ先のブランチに切り替えてから git merge コマンドを実行する
$ git checkout master $ git merge chg01 Merge made by the 'recursive' strategy. text01.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
今回の場合、開発の履歴が過去のとある時点で分岐しているため、先ほどの hotfix のマージとは異なる表示になっている。
(Merge made by the 'recursive' strategy.)
マージ先(master)のコミットがマージ元(chg01)のコミットの直系の先祖ではないため、各ブランチが指すふたつのスナップショットとそれらの共通の先祖との間で三方向のマージを行われたため。
Git が共通の先祖を自動的に見つけ、ブランチのマージに使用する。
単にブランチのポインタを先に進めるのではなく、Git はこの三方向のマージ結果から新たなスナップショットを作成し、それを指す新しいコミットを自動作成する。これはマージコミットと呼ばれ、複数の親を持つ特別なコミットとなる。
これで、今までの作業がマージできたので、chg01 ブランチは不要になり削除することができる。
$ git branch -d chg01
同じファイルを2つのブランチで別々に変更してそれをマージしようとすると、Git はうまくマージする方法を見つけられないのでコンフリクトが発生し、以下のようなメッセージが表示される(マージに失敗しました。コンフリクトを修正(解決)してコミットしてください)。
$ git merge chg01 Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result.
コンフリクトを解決するまで、処理は中断される。
コンフリクトが発生してマージできなかったのがどのファイルなのかを知るには git status を実行。
$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") Unmerged paths: (use "git add <file>..." to mark resolution) both modified: index.html no changes added to commit (use "git add" and/or "git commit -a")
コンフリクトが発生してまだ解決されていないものは Unmerged paths: として表示される。
Git は、標準的なコンフリクトマーカーをファイルに追加するので、ファイルを開いてそれを解決しなければならない。コンフリクトが発生したファイルの中には、以下のような部分が含まれている。
index.html ファイル
<<<<<<< HEAD <p>Fixed the problems</p> ======= <div id="footer">Footer added</div> >>>>>>> chg01
これは、HEAD (merge コマンドを実行したときにチェックアウトしていたブランチなので、ここでは master となる) の内容が上の部分 (======= の上にある内容)、そして chg01 ブランチの内容が下の部分に表示される。
コンフリクトを解決するには、どちらを採用するか等を判断する必要がある。この例では以下のように書き換える。
<p>Fixed the problems</p> <div id="footer">Footer added</div>
このような解決を各部分に対して行い、<<<<<<< や ======= そして >>>>>>> の行をすべて除去する。
その後すべてのコンフリクトを解決したら、各ファイルに対して git add を実行して解決済みであることを通知する。(ファイルをステージすると、Git はコンフリクトが解決されたと見なす。)
git status を実行して、コンフリクトが解決されたこと(All conflicts fixed)を確認して、git commit を実行してマージコミットを完了させる。
$ git add index.html $ git status On branch master All conflicts fixed but you are still merging. (use "git commit" to conclude merge) Changes to be committed: modified: index.html $ git commit [master 55a5053] Merge branch 'chg01'
コンフリクトが解決し作業がマージできたので、chg01 ブランチは不要であれば削除することができる。
$ git branch -d chg01 Deleted branch chg01 (was fabf224).
参考元:Git のブランチ機能 - ブランチとマージの基本/Pro Git
git branch コマンドは、何も引数を渡さずに実行すると、現在のブランチの一覧を表示する。
$ git branch chg03 * master test
現在チェックアウトされているブランチに、* という文字が先頭についている。
各ブランチにおける直近のコミットを調べるには git branch -v を実行。
$ git branch -v chg03 d45dd01 change title [chg03] * master 82b6ad1 Merge branch 'chg02' test c8cffce lines added to test.txt [test]
現在作業中のブランチにマージ済みかそうでないかによる絞り込みができるようになっていて、以下のオプションがある。
現在作業中のブランチにマージ済みのブランチを調べる
$ git branch --merged chg03 * master
この例では、少し前に master に chg03 ブランチをマージしたので、この一覧に表示されている。
このリストにあがっているブランチのうち先頭に * がついていないものは、通常は git branch -d で削除してしまって問題ないブランチ。
まだマージされていない作業を持っているすべてのブランチを調べる
$ git branch --no-merged test
先ほどのブランチとは別のブランチが表示される。(全てのブランチのマージが完了していれば、何も表示されない)
まだマージしていない作業が残っているので、このブランチを git branch -d で削除しようとしてもエラーになり削除できない。
$ git branch -d test error: The branch 'test' is not fully merged. If you are sure you want to delete it, run 'git branch -D test'.
本当にそのブランチを削除してしまってよいなら -D で強制的に消すこともでる。