何とは言わない天然水飲みたさ

git入門の前に知っておきたい概念

[0]が、本質的には同じことである。

gitリポジトリにおけるコミット全体は、有向(非巡回)グラフを形成する。

commit <file(s)>, <ファイル(群を)>コミットする [他動詞]

コミット[名詞]を作ること。

コミット[名詞]を「zipで保存されたプロジェクト」で喩えたが、これに合わせて言うなら、コミットするとは「プロジェクトをzipで保存する」行為をいう。

では何からコミット[名詞]を作るかといえば、直観的には「現在のプロジェクト(ファイル群)の状態」(ワーキングディレクトリ)からである。 しかし、実はgitでは間に一段挟んで、ファイルを即座に保存するのではなく、ステージング・エリアに追加されたファイルを、そこに追加された状態で保存することになっている。
詳細はステージング・エリアを参照。

checkout <commit>, <コミットを>チェックアウトする [他動詞]
checkout <branch>, <ブランチを>チェックアウトする [他動詞]

コミット[名詞]を(ワーキングディレクトリに)展開し再現すること。

コミット[動詞]を「プロジェクトをコピーしてzipで保存する」ことだと喩えたが、これをなぞるなら、チェックアウトとは「zipを展開してプロジェクトに上書きすることで、別の状態のプロジェクトを再現する」ということである。

ブランチをチェックアウトするというのは、ブランチが実際にはひとつのコミットを指すポインタのようなものであるから、「ブランチで指されたコミットをチェックアウトする」という意味である。

working directory, ワーキングディレクトリ [名詞]

現在あるがままのプロジェクトのディレクトリ(のファイル群)の状態のこと。 また、その状態のディレクトリ自体のこと。

要するに直訳の通り「作業中のディレクトリ」の状態である。

branch, ブランチ [名詞]

普通の英語で言うと「枝」。
gitの文脈では、ブランチはあるコミット[名詞]を指すラベルのようなものであり、また、そのコミットを含む先祖の一連のコミット(つまり、履歴が繋がっている、以前のコミット)を意味する。 詳しくは「git branch commit」とかでGoogleで画像検索した方がわかりやすいだろう。

staging area, ステージング・エリア, ステージング領域 [名詞]

次のコミット[動詞]で作成されるコミット[名詞]に保存されるファイル群(の追加や変更)。

  • staging areaに追加されたファイルは、その追加された新たな内容が(古い内容に代わって)次の新たなコミットに含まれる。
    • 前回のコミットに含まれていたファイルは、staging areaにあるファイルで置き換えられる。
    • 前回のコミットに含まれていなかったファイルは、次のコミット[名詞]から新規追加される。
  • staging areaから排除された(unstageされた)ファイルは、次のコミット[名詞]に含まれなくなる。
  • staging areaに追加されなかったファイルは、前回のコミットでの内容がそのまま引き継がれる。 (追加・変更・削除関係なく、次のコミットに反映されない。)

詳しくは下で解説する。

add <file(s)>, <ファイル(群を)>追加する [他動詞]
stage <file(s)> [他動詞]
index <file(s)> [他動詞]

新規ファイルやファイルの変更を次のコミットに含むために、ステージング・エリアに追加すること
逆に、stageされた新規ファイルや変更されたファイルをステージング・エリアから取り除くことをunstageとも言う。

たとえば「ブログを管理してるgitリポジトリで、前回のコミットの状態から2記事を新しく追加したけど、まず1記事だけ追加した状態のコミットを作っておきたい」などのケースは実際よくあることだ。
もし現在のファイルの状態からしかコミット[名詞]を作れないのでは、追加しない方の記事を一度削除してコミット[動詞]、という面倒な手順を踏むことになってしまうが、ステージング・エリアをうまく使ってやることで、ワーキングディレクトリを変更することなく部分的に変更をコミットに追加することができる。

diff, 差分 [名詞]
change(s), 変更 [名詞]

グラフの用語で言うなら、コミット[名詞]ステージング・エリアのファイルがノードで、diff(差分)はエッジ(辺)だ。
よって、diffはコミット間以外でも、コミットとステージング・エリア間やステージング・エリアとワーキングディレクトリ間でも考えることができる。

diffが何に役立つかというと、コミット[名詞]間で何がどう変更されたかを確認できたり、またあるdiffを別のブランチコミット[名詞]に適用(rebase/cherrypick)することで、あるブランチでの変更を別のブランチへ同様に適用することができる。
要するに「安定版用のブランチで行われたバグ修正を、不安定版用ブランチにも持ってくる」ということが簡単に可能になる。
また、過去の変更をなかったことにする(revert)こともできる。 (取り消したいdiffの逆の変更を適用すればいい。)

merge <branches>, <ブランチを>マージする [他動詞]

ある共通のコミット[名詞]から分岐した2つのブランチを融合し、新しくひとつのコミット[名詞]を作ること。

共通のファイルはそのまま使用。 一方のみで変更された箇所はそちらの変更を取り込む。 両方で変更された箇所は、衝突(conflict)として扱い、どうするかユーザに委ねる。

コマンド

[git reset (--hard/--soft)]ワーキングツリー、インデックス、HEADを使いこなす方法 - Qiita

git resetについて。 図がわかりやすい。

Git - ブランチとマージの基本

ブランチとコミットの図がわかりやすい。

見えないチカラ: A successful Git branching model を翻訳しました

実際のソフトウェア開発におけるブランチの効果的な利用法。 git flowというプラグインで楽に使えるようになる。 プラグインで隠蔽されていても、内部でやっているのはcheckout, pull, merge等の組み合わせだ。 上述の用語を理解していれば何が起きているのかはわかるだろう。