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

これは、「どちらか一方から到達可能なものはすべて表示し、両方から到達可能なものはすべて除外する」ことを意味します。

注意: これらの範囲表記は gitkgit 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番目に指定したコミットの祖先であるとは限らないコミット「範囲」を指定することもできます。たとえば、ブランチの stablemaster の先端(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