SYNOPSIS
git *
DESCRIPTION
このチュートリアルでは、新しいプロジェクトをGitに取り込み、変更を加え、他の開発者と変更を共有する方法について説明します。
Gitを使用してプロジェクトを取得するのに主な関心がある場合、たとえば、最新バージョンをテストする場合は、 The Git User’s Manual の最初の2つの章から始めることをお勧めします。
注意: まず最初に、 あなたは git log --graph
などのコマンドの文書を以下のようにして入手する事ができます:
$ man git-log
または:
$ git help log
後者では。あなたが選択したマニュアルビューアを使用できます。詳細については git-help(1) を参照してください。
操作を行う前に、名前と公開メールアドレスを使用してあなた自身をGitに紹介する(introduce yourself)ことをお勧めします。これを行う最も簡単な方法は以下のとおりです:
$ git config --global user.name YourName (訳注:ASCII表記がいいと思うたぶん)
$ git config --global user.email you@yourdomain.example.com
Importing a new project
既にtarball project.tar.gz
があると仮定します。あなたは以下のようにして、これをGitリビジョン管理下に置くことができます。
$ tar xzf project.tar.gz
$ cd project
$ git init
Gitは以下のメッセージを返すでしょう
Initialized empty Git repository in .git/
これで作業ディレクトリ(working directory)が初期化されました。あなたは .git
という名前の新しいディレクトリが作成されたのに気付くでしょう。
次に、Gitに、現在のディレクトリ(つまり .
)の下にあるすべてのファイルの内容のスナップショットを git add
で取得するように指示します:
$ git add .
このスナップショットは、Gitが「インデックス」と呼ぶ一時的な足場領域(temporary staging area)に保存されました。あなたは以下のように git commit
を使用して、インデックスの内容をリポジトリに永続的に保存できます:
$ git commit
これにより、コミットメッセージの入力を求められます。 これで、プロジェクトの最初のバージョンがGitに保存されました。
Making changes
いくつかのファイルを変更してから、更新された内容をインデックスに追加します:
$ git add file1 file2 file3
これで、コミットする準備ができました。あなたは --cached
オプションを指定した git diff
を使用して、何がコミットされようとしているのかを確認できます:
$ git diff --cached
(--cached
を指定しない場合、 git diff
は、編集を行ったがまだインデックスに追加されていない変更を表示します。) あなたは git status
を使用して状況の簡単な要約を取得することもできます:
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: file1
modified: file2
modified: file3
さらに調整が必要な場合は、ここで調整してから、新しく変更したコンテンツをインデックスに追加します。 最後に、以下のコマンドであなたの変更をコミットします。
$ git commit
これにより、変更を説明するメッセージの入力を再度求められ、プロジェクトの新しいバージョンが記録されます。
または、事前に git add
を実行する代わりに、以下を使用できます。
$ git commit -a
これにより、変更された(ただし新規ではない)ファイルが自動的に認識され、それらがインデックスに追加され、コミットされます。それらがすべて1つのステップで実行されます。
コミットメッセージに関する注意: 必須ではありませんが、コミットメッセージは、変更を要約した1行の短い(50文字未満)行で始まり、空行が1行あり、その後にさらに詳細な説明が続くようにすることをお勧めします。コミットメッセージの最初の空白行までのテキストはコミットタイトルとして扱われ、そのタイトルはGit全体で使用されます。たとえば、 git-format-patch(1) はコミットを電子メールに変換し、件名としてコミットタイトル、本文として残りのコミットメッセージを使用します。
Git tracks content not files
【Gitはファイルではなくコンテンツを追跡する】多くのリビジョン管理システムは、新しいファイルへの変更の追跡を開始するようにシステムに指示する add
コマンドを提供します。 Gitの add
コマンドは、よりシンプルで強力な機能を実行します。 git add
は、新しいファイルと新しく変更されたファイルの両方に使用されます。どちらの場合も、指定されたファイルのスナップショットを取得し、そのコンテンツをインデックスにステージングして、次のコミットにすぐに含めることができます。
Viewing project history
あなたはいつでも、以下を使用して変更の履歴を表示できます
$ git log
あなたが各ステップで完全な差分も表示したい場合は、以下を使用してください
$ git log -p
多くの場合、以下のような変更の概要は、各ステップの感触をつかむのに役立ちます
$ git log --stat --summary
Managing branches
単一のGitリポジトリで、開発の複数のブランチを維持できます。 experimental
という名前の新しいブランチを作成するには、以下のようにします
$ git branch experimental
そして、以下のようにすることができます
$ git branch
そうすると、既存のすべてのブランチのリストが表示されます。
experimental
* master
experimental
ブランチはあなたが今作成したばかりのブランチであり、 master
ブランチは自動的に作成されたデフォルトのブランチです。 アスタリスク(*
)は現在使用しているブランチを示します。そしてあなたは以下のようにタイプします
$ git switch experimental
すると experimental
ブランチに切り替えます。次に、ファイルを編集し、変更をコミットして、 master
ブランチに戻ります:
(何かしらファイル編集する)
$ git commit -a
$ git switch master
その変更は experimental
ブランチで行われ、 master
ブランチに戻ったため、その変更が表示されなくなったことを確認します。
master
ブランチで別の変更を加えることができます:
(何かしらファイルを編集する)
$ git commit -a
この時点で、2つのブランチは分岐しており、それぞれに異なる変更が加えられています。 experimental
で行った変更を master
にマージ(統合)するには、以下を実行します
$ git merge experimental
変更が競合しない場合は、これで完了です。 競合がある場合、競合を示すマーカーが問題のあるファイルに残されます。
$ git diff
とすると、これを表示します。あなたが競合を解決するためにファイルを編集したら
$ git commit -a
とすると、マージの結果をコミットします。そして最後に、
$ gitk
とすると、結果の履歴のナイスなグラフィック表現が表示されます。
この時点で、以下のコマンドで experimental
ブランチを削除できます
$ git branch -d experimental
このコマンドは、 experimental
ブランチでの変更がすでに現在のブランチにあることを確認します。
あなたが crazy-idea
ブランチで開発し、それを後悔しているなら、あなたはいつでもそのブランチを(マージせずに)削除することができます
$ git branch -D crazy-idea
ブランチのコストは安くて、かつ操作は簡単なので、これは何かを一時的に試す良い方法です。
Using Git for collaboration
アリス(Alice)が /home/alice/project
にGitリポジトリを使用して新しいプロジェクトを開始し、同一マシンにホームディレクトリを持っているボブ(Bob)がそのプロジェクトに貢献したいとします。
ボブは以下のように始めます:
bob$ git clone /home/alice/project myrepo
これにより、アリスのリポジトリのクローンを含む新しいディレクトリ myrepo
が作成されます。クローンは元のプロジェクトと同等の立場にあり、元のプロジェクトの履歴のコピーを所有しています。
次に、ボブはいくつかの変更を加えてコミットします:
(何かしらファイルを編集する)
bob$ git commit -a
(※必要なだけ繰り返す)
準備ができたら、ボブはアリスに /home/bob/myrepo
のリポジトリから変更をプルするように指示します。アリスはこれを以下のように行います:
alice$ cd /home/alice/project
alice$ git pull /home/bob/myrepo master
これにより、ボブの master
ブランチでの変更がアリスの現在のブランチにマージされます。その間にアリスが自分で変更を加えた場合は、競合を手動で修正する必要があります。
つまり pull
コマンドは2つの操作を実行します。リモートブランチから変更を取得(fetch)してから、それらを現在のブランチにマージします。
注意: 一般に、アリスがプルする前に、アリス自身のローカルの変更をコミットすることを望んでいることに注意してください。ボブの作業が、履歴が分岐してからアリスが行ったことと競合する場合、アリスは作業ツリーとインデックスを使用して競合を解決し、既存のアリス自身のローカル変更は競合解決プロセスの障害となります(Gitは引き続きフェッチを実行しますが、マージを拒否します。アリスは、何らかの方法でアリス自身のローカルの変更を取り除き、再度プルする必要があります)。
アリスは、 以下のように、 fetch
コマンドを使用して、マージせずにボブが行ったことを確認できます。 これにより、アリスはボブが何をしたかを特別なシンボル FETCH_HEAD
を使用して検査し、プルする価値があるかどうかを判断できます
alice$ git fetch /home/bob/myrepo master
alice$ git log -p HEAD..FETCH_HEAD
この操作は、アリスがアリス自身のローカルの変更をコミットしていない場合でも安全です。 範囲表記 HEAD..FETCH_HEAD
は、「 FETCH_HEAD
から到達可能なすべてのものを表示し、 HEAD
から到達可能なものはすべて除外する」ことを意味します。 このコマンドで、アリスは、現在の状態( HEAD
)につながるすべてのことをすでに知っているとして、ボブが持っている状態( FETCH_HEAD
)で、かつ、アリスが持っていないモノを確認します。
アリスが、ボブとの履歴が分岐してから何をしたかを視覚化したい場合は、以下のコマンドを実行できます:
$ gitk HEAD..FETCH_HEAD
この2ドット範囲表記は、先程 git log
で見たのと同一です。
アリスは、フォーク後にアリスとボブの双方が何をしたかを見たいと思うかもしれません。その場合、アリスは以下のように2ドット形式の代わりに3ドット形式を使用できます:
$ gitk HEAD...FETCH_HEAD
これは、「どちらか一方から到達可能なものはすべて表示し、両方から到達可能なものはすべて除外する」ことを意味します。
注意: これらの範囲表記は gitk
と git log
のどちらでも使用できます。
ボブが何をしたかを調べた後、火急の件でなければ、アリスはボブからプルせずに作業を続けるかもしれませが、もし、ボブの履歴にアリスがすぐに必要とするものがあるなら、アリスは、まず進行中の作業をstash(隠す)し、プルして、プルした結果の履歴の先頭に、進行中だった作業をunstashすることもできます。
小さな緊密なグループで作業している場合、同じリポジトリを何度も操作することは珍しくありません。リモートリポジトリの省略形を定義すると、作業は以下のように簡単になります:
alice$ git remote add bob /home/bob/myrepo
これでアリスは、自分のブランチにマージすることなく git fetch
コマンドの使用により、 pull
操作の最初の部分を独立して行うことができます:
alice$ git fetch bob
直接書いた形式とは異なり、アリスが git remote
で設定したリモート・リポジトリ省略形を使用してボブから取得(fetch)する場合、取得(fetch)されたものはリモート追跡ブランチ(remote-tracking branch)(この場合は bob/master
)に保存されます。 したがって、以下のようにすると:
alice$ git log -p master..bob/master
これは、 ボブがアリスの master
ブランチから分岐後に行ったすべての変更をリストします。
これらの変更を調べた後、アリスは変更をアリス自身の master
ブランチにマージできます:
alice$ git merge bob/master
この「マージ」は、以下のように「アリス自身のリモート追跡ブランチからプルする」ことによっても実行できます:
alice$ git pull . remotes/bob/master
注意: コマンドラインで他に何が指定されているかに関係なく、 git pull
は常に現在のブランチにマージされることに注意してください。
その後、ボブは以下を使用してアリスの最新の変更でボブのリポジトリを更新できます
bob$ git pull
注意: ボブはアリスのリポジトリへのパスを指定する必要がないことに注意してください。ボブがアリスのリポジトリのクローンを作成したとき、Gitはアリスのリポジトリの場所をリポジトリ構成に保存し、その場所がプルに使用されます。
bob$ git config --get remote.origin.url
/home/alice/project
( git clone
によって作成される完全な構成は、 git config -l
を使用して表示でき、 git-config(1) のマニュアルページにて各オプションの意味を説明しています。)
Gitは、 origin/master
という名前でアリスの master
ブランチの当初の綺麗なコピー(pristine copy)も保持しています:
bob$ git branch -r
origin/master
ボブが後で別のホストから作業することを決定した場合でも、sshプロトコルを使用してクローンとプルを実行できます:
bob$ git clone alice.org:/home/alice/project myrepo
代わりに、Gitのネイティブプロトコルや、httpを使用できます。詳細については、 git-pull(1) を参照してください。
Gitは、さまざまなユーザーが変更をプッシュする中央リポジトリを使用して、CVSのようなモードで使用することもできます。 git-push(1) と gitcvs-migration(7) を参照してください。
Exploring history
Gitの履歴は、相互に関連する一連のコミットとして表されます。 git log
コマンドでこれらのコミットを一覧表示できることはすでに見てきました。 注意: 各 git log
エントリの最初の行には、そのコミットの「名前」もあります:
$ git log
commit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7
Author: Junio C Hamano <junkio@cox.net>
Date: Tue May 16 17:18:22 2006 -0700
merge-base: Clarify the comments on post processing.
このコミットの詳細を見るには、この「名前」を git show
に与えます。
$ git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7
ただし、コミットを参照する方法は他にもあります。あなたはコミットを一意に識別するのに十分な長さであれば「名前」の最初の部分だけを指定できます:
$ git show c82a22c39c # 通常は名前の最初の
# 数文字で十分です
$ git show HEAD # the tip of the current branch
$ git show experimental # the tip of the "experimental" branch
通常、あらゆるコミットには、プロジェクトの以前の状態を指す1つの「親」コミットがあります:
$ git show HEAD^ # HEAD の parent(親)
$ git show HEAD^^ # HEAD の grandparent (親の親)
$ git show HEAD~4 # HEAD の great-great grandparent (親の親の親の親)
注意: マージコミットには複数の親が含まれる場合があることに注意してください:
$ git show HEAD^1 # show the first parent of HEAD (same as HEAD^)
$ git show HEAD^2 # show the second parent of HEAD (訳注:3つ以上親がある事もある)
コミットに独自の名前を付けることもできます。
$ git tag v2.5 1b2e1d63ff
と実行すると、1b2e1d63ff は v2.5
という名前で参照できます。この名前を他の人と共有する場合(たとえば、リリースバージョンを識別するため)、「タグ」オブジェクトを作成し、おそらくそれに署名する必要があります。 詳細については git-tag(1) を参照してください。
コミットを知る必要のあるGitコマンドは、これらの名前のいずれかを指定することができます。 例えば:
$ git diff v2.5 HEAD # compare the current HEAD to v2.5
$ git branch stable v2.5 # start a new branch named "stable" based
# at v2.5
$ git reset --hard HEAD^ # reset your current branch and working
# directory to its state at HEAD^
最後のコマンド(reset)には注意してください。作業ディレクトリの変更が失われるだけでなく、このブランチからそれ以降のすべてのコミットも削除されます。このブランチがそれらのコミットを含む唯一のブランチである場合、それらは失われます。また、他の開発者がプルする公開ブランチで git reset
を使用しないでください。他の開発者に不必要なマージを強制して、履歴をクリーンアップしてしまうためです。プッシュした変更を元に戻す必要がある場合は、代わりに git revert
を使用してください。
git grep
コマンドは、以下のように、あなたプロジェクトの任意のバージョン内の文字列を検索できます
$ git grep "hello" v2.5
これは、 v2.5
にあるすべての「hello」を検索します。
以下のようにコミット名を省略すると、 git grep
は現在のディレクトリで管理しているファイルを検索します
$ git grep "hello"
これは、Gitによって追跡されているファイルだけですばやく検索する方法です。
多くのGitコマンドは、さまざまな方法で指定できる一連のコミットも指定できます。 git log
の例を以下に示します:
$ git log v2.5..v2.6 # commits between v2.5 and v2.6
$ git log v2.5.. # commits since v2.5
$ git log --since="2 weeks ago" # commits from the last 2 weeks
$ git log v2.5.. Makefile # commits since v2.5 which modify
# Makefile
git log
には、1番目に指定したコミットが2番目に指定したコミットの祖先であるとは限らないコミット「範囲」を指定することもできます。たとえば、ブランチの stable
と master
の先端(tips)が、しばらく前に共通のコミットから分岐した場合、以下のようにすると、
$ git log stable..master
とすると、 master
ブランチで行われたコミットはリストされますが、 stable
ブランチで行われたコミットはリストされません。
$ git log master..stable
とすると、 stable
ブランチで行われたコミットのリストが表示されますが、 master
ブランチで行われたコミットのリストは表示されません。
git log
コマンドには弱点があります。コミットを一覧として表示する必要があることです。履歴に分岐してからマージされた開発ラインがある場合、 git log
がそれらのコミットを表示する順序は無意味な順序になります。
(LinuxカーネルやGit自身など、)複数の貢献者を持つほとんどのプロジェクトでは、頻繁にマージが行われ、 gitk
はそれらの履歴をより適切に視覚化できます。
$ gitk --since="2 weeks ago" drivers/
これは、 drivers
ディレクトリ下のファイルを変更した過去2週間のコミットから任意のコミットを参照できます。 (注: Ctrlキーを押しながら「-」または「+」を押すと、gitkのフォントサイズを調整できます。)
最後に、ファイル名を取得するほとんどのコマンドでは、オプションで、ファイルの特定のバージョンを指定するために、任意のファイル名の前にコミットを付けることができます:
$ git diff v2.5:Makefile HEAD:Makefile.in
git show
を使用して、任意のファイルを表示することもできます:
$ git show v2.5:Makefile
Next Steps
このチュートリアルは、プロジェクトの基本的な分散リビジョン管理を実行するのに十分なはずです。ただし、Gitの奥深さとパワーを完全に理解するには、Gitの基礎となる2つの簡単なアイデアを理解する必要があります:
-
オブジェクトデータベースは、あなたのプロジェクトの履歴(ファイル、ディレクトリ、コミット)を格納するために使用されるかなり洗練されたシステムです。
-
インデックスファイルは、ディレクトリツリーの状態のキャッシュであり、コミットの作成、作業ディレクトリのチェックアウト、およびマージに関係するさまざまなツリーの保持に使用されます。
このチュートリアルのパート2では、オブジェクトデータベース、インデックスファイル、およびGitを最大限に活用するために必要なその他のいくつかのガラクタについて説明します。 linkgit: gittutorial-2[7] をご覧下さい。
すぐにそれを続けたくない場合は、この時点で興味深いかもしれない他のいくつかのより道は以下のとおりです:
-
git-format-patch(1) 、git-am(1): これらは一連のgitコミットを電子メールで送信されたパッチに変換します。その逆も同様です。電子メールで送信されたパッチに大きく依存するLinuxカーネルなどのプロジェクトで役立ちます。
-
git-bisect(1): プロジェクトにデグレがある場合、バグを追跡する1つの方法は、履歴を検索して、原因となる正確なコミットを見つけることです。
git bisect
は、そのコミットの二分木検索を実行するのに役立ちます。マージされたブランチが多数ある複雑な非線形履歴の場合でも、最適に近い検索を実行するのに十分賢いです。 -
gitworkflows(7): 推奨される作業の流れの概要を示します。
-
giteveryday(7): 20コマンド程度で綴る日々のGit。
-
gitcvs-migration(7): CVSユーザー向けのGit。
SEE ALSO
GIT
Part of the git(1) suite