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 "Your Name Comes Here"
$ 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/
これで作業ディレクトリが初期化されました。あなたは ".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:
Your branch is up to date with 'origin/master'.
(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ブランチに戻ります:
(edit file)
$ git commit -a
$ git switch master
その変更はexperimentalブランチで行われ、masterブランチに戻ったため、その変更が表示されなくなったことを確認します。
masterブランチで別の変更を加えることができます:
(edit file)
$ git commit -a
この時点で、2つのブランチは分岐しており、それぞれに異なる変更が加えられています。experimentalで行った変更をmasterにマージするには、以下を実行します
$ git merge experimental
変更が競合しない場合は、これで完了です。 競合がある場合、競合を示すマーカーが問題のあるファイルに残されます。
$ git diff
とすると、これを表示します。あなたが競合を解決するためにファイルを編集したら
$ git commit -a
とすると、マージの結果をコミットします。そして最後に、
$ gitk
とすると、結果の履歴の優れたグラフィック表現が表示されます。
この時点で、以下のコマンドでexperimentalブランチを削除できます
$ git branch -d experimental
このコマンドは、experimentalブランチでの変更がすでに現在のブランチにあることを確認します。
あなたがブランチクレイジーアイデアで開発し、それを後悔しているなら、あなたはいつでもブランチを(マージせずに)削除することができます
$ git branch -D crazy-idea
ブランチのコストは安くて、かつ操作は簡単なので、これは何かを一時的に試す良い方法です。
Using Git for collaboration
アリス(Alice)が /home/alice/project にGitリポジトリを使用して新しいプロジェクトを開始し、同じマシンにホームディレクトリを持っているボブ(Bob)が貢献したいとします。
ボブは以下のように始めます:
bob$ git clone /home/alice/project myrepo
これにより、アリスのリポジトリのクローンを含む新しいディレクトリ「myrepo」が作成されます。クローンは元のプロジェクトと同等の立場にあり、元のプロジェクトの履歴の独自のコピーを所有しています。
次に、ボブはいくつかの変更を加えてコミットします:
(edit files)
bob$ git commit -a
(repeat as necessary)
準備ができたら、ボブはアリスに /home/bob/myrepo のリポジトリから変更をプルするように指示します。アリスはこれを以下のように行います:
alice$ cd /home/alice/project
alice$ git pull /home/bob/myrepo master
これにより、ボブの「master」ブランチからの変更がアリスの現在のブランチにマージされます。その間にアリスが自分で変更を加えた場合は、競合を手動で修正する必要があります。
つまり「pull」コマンドは2つの操作を実行します。リモートブランチから変更をフェッチしてから、それらを現在のブランチにマージします。
一般に、アリスが「プル」を開始する前に、アリス自身のローカルの変更をコミットすることを望んでいることに注意してください。ボブの作業が、履歴が分岐してからアリスが行ったことと競合する場合、アリスは作業ツリーとインデックスを使用して競合を解決し、既存のアリス自身のローカル変更は競合解決プロセスの障害となります(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
これは、前に「git log」で見たのと同じ2ドットの範囲表記を使用します。
アリスは、フォークして以来、アリスとボブの両方が何をしたかを見たいと思うかもしれません。その場合、アリスはは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」で設定したリモートリポジト省略形を使用してボブからフェッチする場合、フェッチされたものはリモート追跡ブランチ(この場合は「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ログエントリの最初の行には、コミットの名前も示されていることに注意してください:
$ 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 # the first few characters of the name are
# usually enough
$ git show HEAD # the tip of the current branch
$ git show experimental # the tip of the "experimental" branch
通常、あらゆるコミットには、プロジェクトの以前の状態を指す1つの「親」コミットがあります:
$ git show HEAD^ # to see the parent of HEAD
$ git show HEAD^^ # to see the grandparent of HEAD
$ git show HEAD~4 # to see the great-great grandparent of HEAD
注意: マージコミットには複数の親が含まれる場合があることに注意してください:
$ git show HEAD^1 # show the first parent of HEAD (same as HEAD^)
$ git show HEAD^2 # show the second parent of HEAD
コミットに独自の名前を付けることもできます。
$ 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^
最後のコマンドには注意してください。作業ディレクトリの変更が失われるだけでなく、このブランチからそれ以降のすべてのコミットも削除されます。このブランチがそれらのコミットを含む唯一のブランチである場合、それらは失われます。また、他の開発者がプルする公開ブランチで「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’にコミットの「範囲」を与えることもできます。ここで、最初のコミットは必ずしも2番目の祖先とは限りません。 たとえば、ブランチの「stable」と「master」の先端が、しばらく前に共通のコミットから分岐した場合、
$ 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