Git
英語 ▾ トピック ▾ 最新バージョン ▾ gittutorial 最終更新日 2.46.1

名前

gittutorial - Git入門チュートリアル

概要

git *

説明

このチュートリアルでは、新しいプロジェクトをGitにインポートし、変更を加え、他の開発者と変更を共有する方法について説明します。

最新バージョンをテストするなど、主にGitを使用してプロジェクトを取得することに関心がある場合は、Gitユーザーマニュアルの最初の2つの章から始めることをお勧めします。

まず、git log --graph のようなコマンドのドキュメントは、次のようにして取得できます。

$ man git-log

または

$ git help log

後者を使用すると、任意のマニュアルビューアーを使用できます。詳細は git-help[1] を参照してください。

操作を行う前に、Gitに自分の名前と公開メールアドレスを登録することをお勧めします。最も簡単な方法は次のとおりです。

$ git config --global user.name "Your Name Comes Here"
$ git config --global user.email you@yourdomain.example.com

新しいプロジェクトのインポート

初期作業を含むtarball project.tar.gz があるとします。次のようにして、Gitリビジョン管理下に置くことができます。

$ tar xzf project.tar.gz
$ cd project
$ git init

Gitは次のように応答します。

Initialized empty Git repository in .git/

これで作業ディレクトリが初期化されました。.git という名前の新しいディレクトリが作成されていることに気付くかもしれません。

次に、git add を使用して、現在のディレクトリ(. に注意)以下のすべてのファイルの内容のスナップショットを取得するように Git に指示します。

$ git add .

このスナップショットは、Gitが「インデックス」と呼ぶ一時的なステージングエリアに保存されます。インデックスの内容をリポジトリに永続的に保存するには、git commit を使用します。

$ git commit

コミットメッセージの入力を求められます。これで、プロジェクトの最初のバージョンがGitに保存されました。

変更を加える

いくつかのファイルを修正し、更新された内容をインデックスに追加します。

$ 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文字以内)で始め、その後に空行と、より詳細な説明を続けることをお勧めします。コミットメッセージの最初の空行までのテキストはコミットタイトルとして扱われ、そのタイトルはGit全体で使用されます。たとえば、git-format-patch[1] はコミットをメールに変換し、件名行にタイトルを使用し、本文にコミットの残りの部分を使用します。

Gitはファイルではなくコンテンツを追跡する

多くのリビジョン管理システムは、システムに新しいファイルの変更の追跡を開始するように指示する add コマンドを提供します。Gitの add コマンドは、よりシンプルで強力なことを行います。git add は、新しいファイルと新しく変更されたファイルの両方で使用され、どちらの場合も、指定されたファイルのスナップショットを取得し、そのコンテンツをインデックスにステージングして、次のコミットに含める準備をします。

プロジェクト履歴の表示

いつでも、次のコマンドを使用して変更履歴を表示できます。

$ git log

各ステップで完全な差分も表示する場合は、次を使用します。

$ git log -p

多くの場合、変更の概要は、各ステップの感じをつかむのに役立ちます。

$ git log --stat --summary

ブランチの管理

単一の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 ブランチの変更が既に現在のブランチにあることを確認します.

ブランチ crazy-idea で開発していて、後悔した場合、いつでも次のコマンドでブランチを削除できます。

$ git branch -D crazy-idea

ブランチは安価で簡単なので、これは何かを試してみる良い方法です.

コラボレーションのためのGitの使用

Aliceが /home/alice/project にGitリポジトリを持つ新しいプロジェクトを開始し、同じマシンにホームディレクトリを持つBobが貢献したいとします。

Bobは次から始めます。

bob$ git clone /home/alice/project myrepo

これは、Aliceのリポジトリのクローンを含む新しいディレクトリ myrepo を作成します。クローンは元のプロジェクトと同等であり、元のプロジェクトの履歴のコピーを所有しています。

Bobはいくつかの変更を加えてコミットします。

(edit files)
bob$ git commit -a
(repeat as necessary)

準備ができたら、Aliceに /home/bob/myrepo のリポジトリから変更をプルするように指示します。彼女は次のようにします。

alice$ cd /home/alice/project
alice$ git pull /home/bob/myrepo master

これは、Bobの master ブランチの変更をAliceの現在のブランチにマージします。Aliceがその間に独自の変更を行った場合、競合を手動で修正する必要があるかもしれません。

したがって、pull コマンドは2つの操作を実行します。リモートブランチから変更を取得し、現在のブランチにマージします。

一般に、Aliceはこの pull を開始する前にローカルの変更をコミットする必要があります。Bobの作業が、履歴が分岐して以来Aliceが行ったことと競合する場合、Aliceは作業ツリーとインデックスを使用して競合を解決し、既存のローカルの変更は競合解決プロセスに干渉します(Gitは引き続きフェッチを実行しますが、マージを拒否します。-Aliceは何らかの方法でローカルの変更を取り除き、これが発生したときに再びプルする必要があります)。

Aliceは、最初にマージせずに、fetch コマンドを使用してBobが行ったことを覗き見ることができます。これにより、Aliceは特別な記号 FETCH_HEAD を使用してBobが行ったことを検査し、プルする価値があるものがあるかどうかを判断できます。次のようにします。

alice$ git fetch /home/bob/myrepo master
alice$ git log -p HEAD..FETCH_HEAD

この操作は、Alice がコミットされていないローカルな変更を持っている場合でも安全です。範囲表記 HEAD..FETCH_HEAD は、「FETCH_HEAD から到達可能なすべてを表示するが、HEAD から到達可能なものは除外する」という意味です。Alice は既に現在の状態 (HEAD) に至るすべての情報を知っているので、このコマンドで、Bob の状態 (FETCH_HEAD) にあって彼女がまだ見ていないものを確認します。

Alice が、履歴が分岐して以来 Bob が何をしたかを視覚化したい場合は、次のコマンドを実行できます。

$ gitk HEAD..FETCH_HEAD

これは、先ほど git log で見たのと同じ 2 ドットの範囲表記を使用しています。

Alice は、分岐して以来、両方が何をしたかを確認したい場合があります。彼女は 2 ドット形式の代わりに 3 ドット形式を使用できます。

$ gitk HEAD...FETCH_HEAD

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

これらの範囲表記は、gitkgit log の両方で使用できることに注意してください。

Bob が何をしたかを調べた後、緊急なことがなければ、Alice は Bob からプルせずに作業を続けることを決定するかもしれません。Bob の履歴に Alice がすぐに必要なものがある場合、Alice は作業中の変更を stash し、pull を実行し、最後に結果の履歴の上に作業中の変更を unstash することを選択するかもしれません。

小規模で緊密なグループで作業している場合、同じリポジトリと何度もやり取りすることは珍しくありません。_リモート_リポジトリの短縮形を定義することで、作業を簡単にすることができます。

alice$ git remote add bob /home/bob/myrepo

これにより、Alice は pull 操作の最初の部分を、自分のブランチとマージせずに git fetch コマンドを使用して単独で実行できます。

alice$ git fetch bob

完全な形式とは異なり、Alice が git remote で設定されたリモートリポジトリの短縮形を使用して Bob からフェッチする場合、フェッチされた内容はリモート追跡ブランチ(この場合は bob/master)に格納されます。そのため、この後

alice$ git log -p master..bob/master

は、Bob が Alice の master ブランチから分岐して以来行ったすべての変更のリストを表示します。

これらの変更を調べた後、Alice は変更を彼女の master ブランチにマージできます。

alice$ git merge bob/master

この merge は、次のように、_彼女自身のリモート追跡ブランチからプルする_ことによっても実行できます。

alice$ git pull . remotes/bob/master

git pull は、コマンドラインで他に何が指定されていても、常に現在のブランチにマージすることに注意してください。

後で、Bob は Alice の最新の変更を使用してリポジトリを更新できます。

bob$ git pull

彼は Alice のリポジトリへのパスを指定する必要がないことに注意してください。Bob が Alice のリポジトリをクローンしたとき、Git はリポジトリの設定に彼女のリポジトリの場所を保存し、その場所がプルに使用されます。

bob$ git config --get remote.origin.url
/home/alice/project

git clone によって作成された完全な設定は、git config -l を使用して表示でき、git-config[1] マニュアルページは各オプションの意味を説明しています。)

Git はまた、Alice の master ブランチの pristine なコピーを origin/master という名前で保持しています。

bob$ git branch -r
  origin/master

Bob が後で別のホストから作業することを決定した場合でも、ssh プロトコルを使用してクローンとプルを実行できます。

bob$ git clone alice.org:/home/alice/project myrepo

あるいは、Git にはネイティブプロトコルがあり、http を使用することもできます。詳細は git-pull[1] を参照してください。

Git は、さまざまなユーザーが変更をプッシュする中央リポジトリを持つ CVS のようなモードでも使用できます。git-push[1]gitcvs-migration[7] を参照してください。

履歴の探索

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	# 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

1b2e1d63ffv2.5 という名前で参照できます。この名前を他の人と共有する予定がある場合(たとえば、リリースバージョンを識別するため)、 "tag" オブジェクトを作成し、署名する必要があるかもしれません。詳細は 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 番目の祖先ではないコミットの「範囲」を与えることもできます。たとえば、ブランチ stablemaster の先端がしばらく前に共通のコミットから分岐した場合、

$ 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 週間のコミットから任意のコミットを参照できます。(注:control キーを押しながら "-" または "+" を押すと、gitk のフォントを調整できます。)

最後に、ファイル名を取るほとんどのコマンドでは、オプションでファイル名の前にコミットを付けることで、ファイルの特定のバージョンを指定できます。

$ git diff v2.5:Makefile HEAD:Makefile.in

また、git show を使用して、そのようなファイルを表示することもできます。

$ git show v2.5:Makefile

次のステップ

このチュートリアルは、プロジェクトの基本的な分散リビジョンコントロールを実行するのに十分なはずです。ただし、Git の深さとパワーを完全に理解するには、それが基づいている 2 つの単純なアイデアを理解する必要があります。

  • オブジェクトデータベースは、プロジェクトの履歴(ファイル、ディレクトリ、コミット)を保存するために使用される、かなり洗練されたシステムです.

  • インデックスファイルは、ディレクトリツリーの状態のキャッシュであり、コミットの作成、作業ディレクトリのチェックアウト、マージに関連するさまざまなツリーの保持に使用されます.

このチュートリアルのパート 2 では、オブジェクトデータベース、インデックスファイル、および Git を最大限に活用するために必要なその他のこまごまとしたことを説明します。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。

GIT

git[1] スイートの一部

scroll-to-top