Git用語集

# はじめに

:::note info
この記事はLITALICO Engineers Advent Calendar 2023 カレンダー1の8日目の記事です
:::

LITALICOに2022年4月に入社したエンジニアの@taka-fujitaです
今回は、チーム内の勉強会で扱ったgitの『[Glossary](https://git-scm.com/docs/gitglossary)（用語集）』の内容についてまとめていきたいと思います


# 前提
- Glossaryの内容全てではなく、業務の中で特によく聞く用語を厳選して取り扱います
    - 勉強会ではほぼ全ての用語について触れましたが、記事の分量の都合上今回は絞り込むことにしました
- 各用語について、原文・和訳・解説、の三段構えで整理していきます
    - 必要に応じてターミナルでの実データを用いた確認も入れています
- 説明はコマンドの内容ではなく『用語の内容』です
    - コマンド実行時、gitがどのような挙動をしているかについては言及していません
- 用語同士お互いに参照し合っている場面が多くみられますが、説明している用語を上から順番になぞることでそれらの参照関係をスムーズに理解することができるように整理しているつもりです
    - 途中の単語から確認した場合、理解できない単語があるかもしれませんが、その場合適宜本記事での用語の説明を参照するようにしてみてください


# 用語解説

## object

### 原文
The unit of storage in Git. It is uniquely identified by the SHA-1 of its contents. Consequently, an object cannot be changed.

### 和訳
Gitにおける記録の単位。その内容のSHA-1によって一意に特定できる。結果的にオブジェクトは変更不可能である。

### 解説
gitが管理している情報の単位
object type の説明にて記述があるが、下の4種類のいづれかに該当する

- commit
- tree
- tag
- blob

>結果的にオブジェクトは変更不可能

オブジェクトを変更するとSHA-1の計算結果は変わるため、「オブジェクトを変更する = 新たなSHA-1を持つ別のオブジェクトを作成する」ということになる
したがって「オブジェクトを変更する」という操作はgitでは存在せず、「オブジェクトを新規で作成する」しか存在しないことになるので上記のような表現をしている


## SHA-1

### 原文
"Secure Hash Algorithm 1"; a cryptographic hash function. In the context of Git used as a synonym for object name.

### 和訳
暗号学的ハッシュ関数の一種である「セキュアハッシュアルゴリズム1」の略称。Gitの文脈においては「object name」の同義語。

### 解説
SHA-1の具体的なアルゴリズムについては、暗号技術入門などを読んでいただけると
一般的に「SHA-1」と言った場合は関数そのものを指すことが多い印象だが、Gitの文脈ではSHA-1が出力したハッシュ値のことを指すことが多い

## object name

### 原文
The unique identifier of an object. The object name is usually represented by a 40 character hexadecimal string. Also colloquially called SHA-1.

### 和訳
オブジェクトの一意な識別子のこと。通常は16進数の40文字の文字列で表現される。SHA-1とも呼ばれる。


### 解説
原文に書いてある通り、オブジェクトの一意な識別子のことを「object name」と呼ぶ
SHA-1の出力が160ビットなので16進数表記すると40文字になる


## hash


### 原文
In Git’s context, synonym for object name.

### 和訳
Gitの文脈では、object name と同義

### 解説
「object name」と同義
gitの文脈においては、「object name = SHA-1 = SHA-1が出力したハッシュ値」という関係が成り立っている

## object database

### 原文
Stores a set of "objects", and an individual object is identified by its object name. The objects usually live in `$GIT_DIR/objects/`.

### 和訳
一連のオブジェクト達の保存場所のこと。それぞれのオブジェクトはオブジェクト名で識別される。通常は`$GIT_DIR/objects/` にある。

### 解説
`$GIT_DIR`は通常`.git`になるので、`.git/objects/`が該当する
このディレクトリ以下にはSHA-1の先頭2文字のディレクトリが並んでおり(16進数なので00からffまで)、そのディレクトリ内には38文字のファイルがある
ディレクトリ名とファイル名を合わせて40文字のSHA-1となり、38文字のファイルの方がobjectとなっている


オブジェクトの中身はcat-fileコマンド等で確認できる
```bash
# .git/objects/の中身
% ls .git/objects 
00	0e	1b	28	35	42	4f	5c	69	76	83	90	9d	aa	b7	c4	d1	df	ec	f9
01	0f	1c	29	36	43	50	5d	6a	77	84	91	9e	ab	b8	c5	d3	e0	ed	fa
02	10	1d	2a	37	44	51	5e	6b	78	85	92	9f	ac	b9	c6	d4	e1	ee	fb
03	11	1e	2b	38	45	52	5f	6c	79	86	93	a0	ad	ba	c7	d5	e2	ef	fc
04	12	1f	2c	39	46	53	60	6d	7a	87	94	a1	ae	bb	c8	d6	e3	f0	fd
05	13	20	2d	3a	47	54	61	6e	7b	88	95	a2	af	bc	c9	d7	e4	f1	fe
06	14	21	2e	3b	48	55	62	6f	7c	89	96	a3	b0	bd	ca	d8	e5	f2	ff
07	15	22	2f	3c	49	56	63	70	7d	8a	97	a4	b1	be	cb	d9	e6	f3	
08	16	23	30	3d	4a	57	64	71	7e	8b	98	a5	b2	bf	cc	da	e7	f4
0a	17	24	31	3e	4b	58	65	72	7f	8c	99	a6	b3	c0	cd	db	e8	f5
0b	18	25	32	3f	4c	59	66	73	80	8d	9a	a7	b4	c1	ce	dc	e9	f6
0c	19	26	33	40	4d	5a	67	74	81	8e	9b	a8	b5	c2	cf	dd	ea	f7
0d	1a	27	34	41	4e	5b	68	75	82	8f	9c	a9	b6	c3	d0	de	eb	f8

# SHA-1の先頭2文字のディレクトリの中身（38文字のファイルが並んでいる）
% ls .git/objects/00
1e378abe9f88f1ea9a51fa96802c4cae0c7a0b	5d3ea3f427f7f56b511cc8ad03dbb57eb879e9
244141494de86fab065a10a2c650c3ab33dfca	8c1b25847724941c24c9dcccef083dcfd20472

# SHA-1で管理されたobjectの中身（今回は tree object）
% git cat-file -p 00c91a46e712aa751a461e545648cbb91463cab0
100644 blob e3b04cb6358c0862be8f59a17333122b964d3296	hogehoge
100644 blob 07ace0cd2feaba8686a1ab474120f75e77ee303a	hogehoge
100644 blob 7b454084bfa2d8dd978ea74118401ab0f015b16e	hogehoge
                            （省略）
```

## object type

### 原文
One of the identifiers "commit", "tree", "tag" or "blob" describing the type of an object.

### 和訳
オブジェクトの型を表す識別子で、commit, tree, tag, blobの4種類のこと。

### 解説
gitの文脈ではobjectは4種類に分類され、下記のいずれかとなる

- commit
- tree
- tag
- blob


## blob object

### 原文
Untyped object, e.g. the contents of a file.


### 和訳
型無しのオブジェクトのこと。例えばファイルの内容など。

### 解説
commit, tree, tag に該当しない全てのオブジェクトがblobとなる


## tree

### 原文
Either a working tree, or a tree object together with the dependent blob and tree objects.


### 和訳
「ワーキングツリー」または「依存するblobオブジェクトとツリーオブジェクトを含むツリーオブジェクト」。

### 解説
後述する「ワーキングツリー」や、後述する「ツリーオブジェクト」の総称

## tree object

### 原文
An object containing a list of file names and modes along with refs to the associated blob and/or tree objects. A tree is equivalent to a directory.

### 和訳
ファイル名とモードのリストと、関連するblobオブジェクトやツリーオブジェクトへの参照を含むオブジェクト。ツリーはディレクトリに相当する。

### 解説
以下のような情報を含んだものが tree object

```bash
# tree objectの中身
% git cat-file -p 00c91a46e712aa751a461e545648cbb91463cab0
100644 blob 7fe2b0a44e8fba6818105e96b9362dc8328e36c8	hoge.ts
100644 blob d00a25b6631c22e949f1fcef861d5c155216d752	hoge.json
100644 blob bfeab89121958f74237397762f261676cb49dde8	fuga.json
040000 tree b460f3f892100b8a48a538d3806d7f705378afc2	folder
040000 tree 42a1a1a29fe23f082ed61cf354f91e76e0e3fca8	folder2
040000 tree 179a086351a1eb1cc3e34b2693afde2636d3e8f8	folder3
                            （省略）
```


## working tree

## 原文
The tree of actual checked out files. The working tree normally contains the contents of the HEAD commit’s tree, plus any local changes that you have made but not yet committed.

## 和訳
実際にチェックアウトされたファイルのツリー。ワーキングツリーは通常、HEADコミットのツリーの内容に加えて、コミットされていないローカルで行われたあらゆる変更が含まれる。

## 解説
チェックアウトされたファイル（の依存するblobオブジェクト）と、HEADコミットが持つツリーオブジェクトを含めたもののこと
コミットの中には tree が存在するので、HEADコミットの tree の内容とローカルで行われた変更（差分）を含んでいるイメージ

```bash
# commit object の中身
% git cat-file -p f2a9570ecfc7920af9895a501c66fe365266e7dc
tree e4bb10eaa547e06a14faa801e37a933b20969bed  # commitの中に存在するtree
parent 63363de0147d0545f660b64077756f89ea47ac59
parent 5aca7690c85dac8c3b124f14cbaf5b2066962f83
```


## HEAD

### 原文
The current branch. In more detail: Your working tree is normally derived from the state of the tree referred to by HEAD. HEAD is a reference to one of the heads in your repository, except when using a detached HEAD, in which case it directly references an arbitrary commit.

### 和訳
現在のブランチのこと。より詳細：ワーキングツリーは通常、HEADによって参照されるツリーの状態に由来する。HEADは、任意のコミットを直接参照する detached HEAD を使う時を除き、リポジトリ内の heads の中の1つへの参照である。

### 解説
任意のコミットを直接参照する場合（detached HEAD）を除き、HEADは現在のブランチのことであり、それはリポジトリ内の heads の中の1つの参照となる

> ツリーの状態に由来する

ワーキングツリーには、コミットされていないローカルで行われたあらゆる変更（HEADコミットが参照しているツリー情報との差分）が含まれるという話


>リポジトリ内の heads の中の1つの参照

実際にHEADの中身を確認するとイメージがわく
```bash
# HEADの中身を確認
% cat .git/HEAD                                           
ref: refs/heads/main  #headsの1つを参照している
```

## head

### 原文
A named reference to the commit at the tip of a branch. Heads are stored in a file in $GIT_DIR/refs/heads/ directory, except when using packed refs. (See [git-pack-refs[1]](https://git-scm.com/docs/git-pack-refs).)


### 和訳
ブランチの先端にあるコミットへの名前付き参照のこと。packed refs を使用する場合を除き、`headsは $GIT_DIR/refs/heads/` ディレクトリ内のファイルに保存される。([git-pack-refs[1]](https://git-scm.com/docs/git-pack-refs) を参照)


### 解説
head は名前付き参照のこと（名前はブランチ名で、参照はブランチの先端にあるコミット）

```bash
# headsの参照先（objectを参照しているのがわかる）
% cat .git/refs/heads/main 　　　　
992278ea1f11d163d3cbdfedb9882579c26a77b8  

# headsが参照しているobjectの中身（ブランチの先端にあるコミットオブジェクト）
% git cat-file -p 992278ea1f11d163d3cbdfedb9882579c26a77b8
tree 5dbda0d53cf8b8dda6e109f7dcfc343d5cf31c4c
parent 7d9bf60796de3f203639cfc26e43f5479b2f0614
author hogehoge <hogehoge> 1692586388 +0900
committer hogehoge <hogehoge> 1692586388 +0900
```




## detached HEAD

### 原文
Normally the HEAD stores the name of a branch, and commands that operate on the history. HEAD represents operate on the history leading to the tip of the branch the HEAD points at. However, Git also allows you to check out an arbitrary commit that isn’t necessarily the tip of any particular branch. The HEAD in such a state is called "detached".
Note that commands that operate on the history of the current branch (e.g. git commit to build a new history on top of it) still work while the HEAD is detached. They update the HEAD to point at the tip of the updated history without affecting any branch. Commands that update or inquire information about the current branch (e.g. git branch --set-upstream-to that sets what remote-tracking branch the current branch integrates with) obviously do not work, as there is no (real) current branch to ask about in this state.


### 和訳
通常、HEADにはブランチの名前とm履歴を操作するコマンドが含まれる。HEADは、HEADが指すブランチの先端までの履歴に対する操作を表す。しかし、Gitでは必ずしも特定のブランチの先端ではない任意のコミットをチェックアウトすることもできる。このような状態の HEAD を「detached」と呼ぶ。
現在のブランチの履歴を操作するコマンド (例: ブランチの先端に新しい履歴を構築する `git commit` ) は、HEADが detached となっている間も機能することに注意すること。履歴を操作するコマンドは、いづれのブランチにも影響を与えることなく、更新された履歴の先端を指すようにHEADを更新する。現在のブランチに関する情報を更新または照会するコマンド (例: 現在のブランチをどのリモート追跡ブランチと統合させるかを設定する `git Branch --set-upstream-to` ) は、状態を問い合わせるための (実際の) 現在のブランチがないため明らかに機能しない。


### 解説
HEADがブランチの先端のコミットではない、任意のコミットを参照している状態の呼び方のこと
detached の状態でもコミットをすることは可能だが、ブランチを参照していない状態のためブランチに関する情報を参照・更新するようなコマンドは実行することができない




## checkout

### 原文
The action of updating all or part of the working tree with a tree object or blob from the object database, and updating the index and HEAD if the whole working tree has been pointed at a new branch.

### 和訳
オブジェクトデータベースから、ツリーオブジェクトやblobの内容にワーキングツリーの全体もしくは一部を更新し、もしワーキングツリー全体が新しいブランチにポイントされた場合には、indexとHEADを更新するアクションのこと。


### 解説
オブジェクトデータベースを用いてワーキングツリーを更新するアクションのこと
`git checkout [<branch>]` のように現在のブランチと異なるブランチ（or コミット）を指定してチェックアウトする場合には、indexとHEADの情報も更新される

ブランチが参照しているツリーの内容になるようにワーキングツリーを更新し、そのツリーの内容になるようにindexのオブジェクトのリストも更新され、HEADがブランチを参照するように切り替わる、という流れ


## index

### 原文
A collection of files with stat information, whose contents are stored as objects. The index is a stored version of your working tree. Truth be told, it can also contain a second, and even a third version of a working tree, which are used when merging.

### 和訳
統計情報を持つファイルの集合体であり、その内容はオブジェクトとして保存される。インデックスはワーキングツリーのバージョンが保存されたものである。実のところ、インデックスにはワーキングツリーの第2、さらには第3のバージョンを格納することもでき、これらはマージ時に使用される。


### 解説
indexはオブジェクトデータベースの中にあるファイルオブジェクトの参照を集めたものであり、ワーキングツリーのとある状態のスナップショットである
オブジェクトデータベースにオブジェクトが作成されるタイミングについて、`git add`が実行された時となる
これらの理由は、indexがオブジェクトを参照するので、addしたタイミングでオブジェクトデータベースにオブジェクトが存在している必要があるため（`add`コマンドがindexの更新をしている、というのはつまり「indexのファイルリストの中のSHA-1を更新すること」と同義である）

> その内容はオブジェクトとして保存される

1つ1つのファイルはオブジェクトであり、それらはオブジェクトデータベースの中に存在しているファイルのSHA-1であるということ


#### indexの中身
`.git/index`のファイル情報はバイナリ情報のため、人間が理解できる形式のものだと以下となる

```bash
# indexの中身
% git ls-files --stage
100644 8f5aedb718c87c8f4a192c2530ad1f90efc8dc25 0       hoge.ts
100644 4c22f5e7e5f47a26b5db5fb16ef5b996186ffc82 0       folder1/folder2/hoge.ts
100644 6f96f57e84a24a626cd9def5b7e3ae59c889e230 0       folder1/folder2/folder3/hoge.ts
```

ファイル名ではなくフルパスが表示されることから、再起的にディレクトリの中身を網羅して全ファイルへSHA-1の参照を持っているのが特徴

#### 【参考】 treeの中身
indexとの違いはtreeの参照を持っていること

```bash
# treeの中身
git cat-file -p a0b74bdea597d1b809ed505f916b1d3d4e895f71
100644 blob 8f5aedb718c87c8f4a192c2530ad1f90efc8dc25    hoge.ts
040000 tree 3bd319d591f505318ca050ea4977ea2c11600779    folder1
040000 tree 0935262b57fdd50dcb66fcd17d9d42e0c61b28f4    folder2
```

indexとは異なり、ディレクトリからのフルパスではなくファイル名のみが表示される


## branch

### 原文
A "branch" is a line of development. The most recent commit on a branch is referred to as the tip of that branch. The tip of the branch is referenced by a branch head, which moves forward as additional development is done on the branch. A single Git repository can track an arbitrary number of branches, but your working tree is associated with just one of them (the "current" or "checked out" branch), and HEAD points to that branch.

### 和訳
「ブランチ」とは開発のラインである。ブランチ上の最新のコミットは、そのブランチの先端と呼ばれる。ブランチの先端は branch head によって参照され、ブランチで追加の開発が行われると branch head は先に進む。単一のGitリポジトリは任意の数のブランチを追跡できるが、ワーキングツリーはそれらのうちの1つのブランチにのみ関連付けられており (「現在の」または「チェックアウトされた」ブランチ) 、HEADはその関連づけられたブランチを指す。


### 解説
開発のラインのことをブランチという（開発のラインというのは、コミットを連ねた状態をイメージ）
コミットが追加されると、ブランチの先頭に追加される
単一のリポジトリの中にブランチを複数用意することは可能だが、ワーキングツリーとして関連づけることができるブランチは1つのみとなっている（この1つのブランチはHEADが指し示す）

> コミットが追加されると、ブランチの先頭に追加される

#### ブランチの先頭に追加される実際の挙動
```bash
# 現時点のheadsのSHA-1
% cat .git/refs/heads/hoge
ac2f93a41d2f6963479aeff83082685464efe6ac

# 現時点の最新コミットの中身
% git cat-file -p ac2f93a41d2f6963479aeff83082685464efe6ac
tree d170cd3309d6edf0c5bc32808c5266d3d7ae08f5
parent 992278ea1f11d163d3cbdfedb9882579c26a77b8
author hoge <hoge> 1692664229 +0900
committer hoge <hoge> 1692664229 +0900

コミットメッセージ①
```

新しいコミットを追加する

```bash
# 新しいコミット追加後のheadsのSHA-1
% cat .git/refs/heads/hoge     
8d5381a6400931d164d93c8b227f3a9f6a144443

# 追加した新しいコミットの中身
% git cat-file -p 8d5381a6400931d164d93c8b227f3a9f6a144443
tree 38553264cfebff0f8d55f92a735931cf260f137f
parent ac2f93a41d2f6963479aeff83082685464efe6ac # 新規コミット前にheadsが参照していたSHA-1と一致している
author hoge <hoge> 1693441561 +0900
committer hoge <hoge> 1693441561 +0900

コミットメッセージ②
```

`git log`の中身を確認すると、ブランチの先頭にコミットが追加されているのが視覚的にもわかる

```bash

git log hoge 
commit 8d5381a6400931d164d93c8b227f3a9f6a144443 (HEAD -> hoge)
Author: hoge <hoge>
Date:   Thu Aug 31 12:00:00 2000 +0900

    コミットメッセージ②

commit ac2f93a41d2f6963479aeff83082685464efe6ac (origin/hoge)
Author: hoge <hoge>
Date:   Tue Aug 22 12:00:00 2000 +0900

    コミットメッセージ①
```

<br>

> ワーキングツリーとして関連づけることができるブランチは1つのみとなっている（この1つのブランチはHEADが指し示す）

ブランチを切り替えるたびに、HEADの中身が変わっているのが確認できる
```bash
% cat .git/HEAD 
ref: refs/heads/hoge

% git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

% cat .git/HEAD       
ref: refs/heads/main
```



## ref

### 原文
A name that begins with refs/ (e.g. refs/heads/master) that points to an object name or another ref (the latter is called a symbolic ref). For convenience, a ref can sometimes be abbreviated when used as an argument to a Git command; see [gitrevisions[7]](https://git-scm.com/docs/gitrevisions) for details. Refs are stored in the repository.
The ref namespace is hierarchical. Different subhierarchies are used for different purposes (e.g. the refs/heads/ hierarchy is used to represent local branches).
There are a few special-purpose refs that do not begin with refs/. The most notable example is HEAD.


### 和訳
object name や他の ref を指す (後者はシンボリック ref と呼ばれる) `refs/` から始まる名前 (例：`refs/heads/master`)のこと. 便利なことに, Gitコマンドの引数として使うときには ref を省略することもある. 詳しくは [gitrevisions[7]](https://git-scm.com/docs/gitrevisions) を参照. refはリポジトリに保存される.
ref名前空間は階層構造になっている. 異なるサブ階層は異なる目的のために使用される（例えば, `refs/heads/` はローカルブランチを格納するために使用される）. 
refs/で始まらない特別な目的のrefもいくつかある. 最も顕著な例はHEADである. 


### 解説
object name やその他の ref を指し示す名称のこと
`refs/heads/branch` を確認すると、object name が表示される
`refs/`以下にあるディレクトリは複数あるが、これらの中身は異なるものを意味(表現)するrefが格納されている
具体的には、`heads/`であればローカルブランチを意味するrefが、`tags/`であればタグを意味するrefが格納される
HEADについて、基本的にはシンボリックrefの役割となるが、detached HEADの場合コミットオブジェクトを指し示すので、通常のrefとなる

>ref を省略することもある. 

`git merge main` のように `refs/heads/main` ではなく `main` としていることが一例

```bash
# 省略ありの例
% git merge main                
Already up to date.

# 省略なしの例
% git merge refs/heads/main
Already up to date.
```

<br>

> HEADについて、基本的にはシンボリックrefの役割となるが、detached HEADの場合コミットオブジェクトを指し示すので、通常のrefとなる

#### 通常のHEAD
```bash
% cat .git/HEAD       
ref: refs/heads/main
```

#### detached HEAD
```bash
% cat .git/HEAD                                    
e885ee5511a039a9de7775c68470a5ce418128ba
```
`ref: refs/heads/main`という形式になっていないことが特徴



## commit

### 原文
As a noun: A single point in the Git history; the entire history of a project is represented as a set of interrelated commits. The word "commit" is often used by Git in the same places other revision control systems use the words "revision" or "version". Also used as a short hand for commit object.
As a verb: The action of storing a new snapshot of the project’s state in the Git history, by creating a new commit representing the current state of the index and advancing HEAD to point at the new commit.

### 和訳
名詞として使われた場合、これはgitの歴史においての一つの地点を表す。つまり、プロジェクト全体の歴史は、相互に関連するcommitの集合として表される。”commit”という単語はgitにおいてはしばしば、他の修正管理システムが”revision”や”version”という言葉を使うのと同じ場所で使われる。また、これは”commit object”の短縮系としても使われる。
動詞として使われた場合、これはgitの歴史において、プロジェクトの状態の新しいスナップショットを蓄積するという行為である。これは、indexの現在の状態を表す新しいcommitを作成し、HEADをその新しいcommitの地点へ移動させることによって行われる。


### 解説
名詞の用法での意味は２つ
1. gitの歴史においての一つの地点
2. `commit object`（後述）と同義

動詞の用法は、`git commit`叩いた時の挙動と一致
commitコマンド実行時の詳しい挙動についてはコマンドのリファレンスを参照


## revision

### 原文
Synonym for commit (the noun).


### 和訳
commit(名詞)の同義語。


### 解説
revision = commit(名詞) 



## commit object

### 原文
An object which contains the information about a particular revision, such as parents, committer, author, date and the tree object which corresponds to the top directory of the stored revision.

### 和訳
parents や committer, author, date、そして保存された revision の最上位ディレクトリに相当するtreeオブジェクトといった、特定の revision についての情報を含むオブジェクトである。

### 解説
以下の内容が「commit object」である

```bash
% git cat-file -p 992278ea1f11d163d3cbdfedb9882579c26a77b8
tree 6573f65a81e38177ccfdca78c8b1f39098b5ff0f
parent 8b6396bac0974bfa33f1ff9b8ddf440c63326221
author hogehoge <hogehoge> 1692586388 +0900
committer hogehoge <hogehoge> 1692586388 +0900
```

- treeはgitで管理されている最上位（TOP）ディレクトリに相当するツリーオブジェクトのSHA-1
- parentは親コミットのSHA-1
- authorはコミットされた内容の差分を作成した人
- committerはコミットを実際に行った人

※ authorとcomitterの乖離について、`git commit --amend`などで、コミットメッセージを修正した時などに発生する


## parent
### 原文
A commit object contains a (possibly empty) list of the logical predecessor(s) in the line of development, i.e. its parents.

### 和訳
単一のcommit objectは、開発の過程において、（空の場合もあるが）論理的に先行するもののリストを含んでおり、それが、つまるところparentsである。

### 解説
特定の commit object における、ひとつ前の commit object のこと


## directory

### 原文
The list you get with "ls" :-) 

### 和訳
lsコマンドで取得できるリストだよ

### 解説
一般的な”directory”の意味と同じ（git特有の文脈があるわけではない）



## commit-ish (also committish)

### 原文
A commit object or an object that can be recursively dereferenced to a commit object. The following are all commit-ishes: a commit object, a tag object that points to a commit object, a tag object that points to a tag object that points to a commit object, etc.

### 和訳
commit object自体、あるいは、commit objectに再帰的にデリファレンスできるobjectのこと。次のものはすべてcommit-ishである。commit object, commit objectを指しているtag object, commit objectを指しているtag objectを指しているtag object

### 解説
commit-ishとは、commit object自体と、それを参照する参照元を含めた表現

> 再帰的にデリファレンスできるobjectのこと

デリファレンスとは、ポインタなどの参照からそれが指している値を参照すること
再帰的にというのは、例としてあげられている

- commit objectを指しているtag objectを指しているtag object

のように、直接 commit object を参照していなくとも、参照先を追っていくと最終的に commit object に辿り着くものもcommit-ishに含まれるということ


## cache

### 原文
Obsolete for: index.

### 和訳
indexの死語

### 解説
indexのこと



## tag

### 原文
A ref under refs/tags/ namespace that points to an object of an arbitrary type (typically a tag points to either a tag or a commit object). In contrast to a head, a tag is not updated by the commit command. A Git tag has nothing to do with a Lisp tag (which would be called an object type in Git's context). A tag is most typically used to mark a particular point in the commit ancestry chain.

### 和訳
`refs/tags/`以下にあるrefで、任意のタイプのオブジェクトを指す(典型的にはタイプはtagかcommitのいずれか)。headとは対照的に、タグはcommitコマンドによって更新されない。Gitのタグは、Lispタグとは何の関係もない(これはGitの文脈ではオブジェクトタイプと呼ばれる)。タグはコミット祖先チェーン内の特定地点をマークするために最も一般的に使用される。

### 解説
主にcommitを指すrefである点はheadと同様であるが、headが参照先を変えるのを前提とするのに対して、tagは基本的に一度参照したものを参照し続けるという違いがある


## tag object

### 原文
An object containing a ref pointing to another object, which can contain a message just like a commit object. It can also contain a (PGP) signature, in which case it is called a "signed tag object".

### 和訳
別のオブジェクトを指すrefを含むオブジェクトのこと。コミットオブジェクトと同様にメッセージを含めることができる。(PGP) 署名を含めることもでき、その場合は「署名付きタグオブジェクト」と呼ばれる。

### 解説
tagは軽量タグ・注釈付きタグ・署名付きタグの3種類があり、このうち、軽量タグはタグオブジェクトではないただのrefである
- Aコミットを指す軽量タグBを作成すると、AコミットのSHA-1を指すBという名前のファイルが`refs/tags`以下に作成される
- Aコミットを指す注釈付きタグ(または署名付きタグ)Bを作成すると、AコミットのSHA-1を指すタグオブジェクトが作成され、そのタグオブジェクトのSHA-1を指すBという名前のファイルが`refs/tags`以下に作成される
- 署名付きタグはなりすまし防止のために使われる


## core Git

### 原文
Fundamental data structures and utilities of Git. Exposes only limited source code management tools.

### 和訳
Gitの基本的なデータ構造とユーティリティのこと。限定的なソースコード管理ツールのみを露出する。

### 解説
これだけだとわからないため、plumbing（後述）とporcelain（後述）で補足説明

## plumbing

### 原文
Cute name for core Git.

### 和訳
core Gitのイケてる言い方

### 解説
これだけだとわからないため、porcelain（後述）で補足説明



## porcelain

### 原文
Cute name for programs and program suites depending on core Git, presenting a high level access to core Git. Porcelains expose more of a SCM interface than the plumbing.

### 和訳
core Gitに依存するプログラムおよびプログラムスイートのイケてる名前で、core Git への高レベルのアクセスを提供する。porcelainはplumbingよりもSCM インターフェースの多くを露出させる。

### 解説
オブジェクトを操作するようなプリミティブなものがplumbingで、それらを利用してVCSとして完成させているのがporcelain

【参考情報】
- https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain
- https://git-scm.com/docs の『Plumbing Commands』部分



## master

### 原文
The default development branch. Whenever you create a Git repository, a branch named "master" is created, and becomes the active branch. In most cases, this contains the local development, though that is purely by convention and is not required.

### 和訳
デフォルトの開発ブランチのこと。Gitリポジトリを作成するたびに、masterという名前のブランチが作成され、アクティブなブランチになる。ほとんどの場合、masterにはローカル開発が含まれるが、これは単に慣例によるものであり、必須ではない。

### 解説
今はmasterではなくmainのこと

> masterにはローカル開発が含まれるが

この内容はやや解釈が難しいが、masterに開発物が集約されていくという話がしたいのではないかと予想


## clean

### 原文
A working tree is clean, if it corresponds to the revision referenced by the current head. Also see "dirty".

### 和訳
ワーキングツリーが現在のHEADによって参照されるリビジョンに一致している場合、「ワーキングツリーはクリーンである」という。dirtyも参照。

### 解説
`git status`コマンドでよく見かけるcleanの内容と一致
後述の dirty ではない状態


## dirty

### 原文
A working tree is said to be "dirty" if it contains modifications which have not been committed to the current branch.

### 和訳
カレントブランチへコミットしていない変更がある場合、ワーキングツリーは「ダーティである」言う。

### 解説
`git status`でdiffが出ている状態のこと


## rebase

### 原文
To reapply a series of changes from a branch to a different base, and reset the head of that branch to the result.

### 和訳
ブランチの一連の変更を別のベースに再適用し、そのブランチのheadを再適用結果にセットする。

### 解説
rebaseコマンドがやっていることのざっくりした説明がされている（詳細はコマンドのリファレンス参照）
「別のベースに再適用」は「もともとの親とは違うコミットを親とする」という意味


## alternate object database

### 原文
Via the alternates mechanism, a repository can inherit part of its object database from another object database, which is called an "alternate".

### 和訳
代替メカニズムを利用して、リポジトリは別のオブジェクトデータベースからオブジェクトデータベースの一部を継承できる。これをalternateという。

### 解説
1つのPCに2つのリポジトリをクローンするような場合に、2つのクローンリポジトリ間でオブジェクトデータベースは共通しているので通信コストを節約したくなる
こういうケースで、片方のリポジトリのオブジェクトデータベースをもう片方から参照することによってオブジェクトデータベースのダウンロードをサボる事ができる仕組みがある（cloneコマンドのオプションでこれを制御できる）
オブジェクトが勝手に消えて参照できなくなるケースがあるなど、注意点がいくらかあるらしい（使ったことがないため詳細不明）

## cherry-picking

### 原文
In SCM jargon, "cherry pick" means to choose a subset of changes out of a series of changes (typically commits) and record them as a new series of changes on top of a different codebase. In Git, this is performed by the "git cherry-pick" command to extract the change introduced by an existing commit and to record it based on the tip of the current branch as a new commit.

### 和訳
SCM の用語で、一連の変更 (通常はコミット) から変更の一部を選択し、それらを別のコードベースの上に新しい一連の変更として記録することを意味する。Gitでは「git cherry-pick」コマンドによって既存のコミットの変更を抽出し、カレントブランチの先端に新しいコミットとして記録する。

### 解説
一部のコミットを別のブランチに適用することができ、それを「cherry-picking」と呼ぶ
詳しい挙動は`cherry-pick`コマンドのリファレンスを確認してもらう



## repository

### 原文
A collection of refs together with an object database containing all objects which are reachable from the refs, possibly accompanied by meta data from one or more porcelains. A repository can share an object database with other repositories via alternates mechanism.

### 和訳
refs のコレクションで、refから到達可能(reachable)なすべてのオブジェクトを含むオブジェクトデータベースと、1つ以上の porcelains のメタデータが付属する可能性がある。リポジトリは、alternates mechanism を通して他のリポジトリとオブジェクトデータベースを共有することができる。

### 解説
リポジトリ（`.git`）は、refの情報(`.git/refs`)と、refから到達可能(reachable)なすべてのオブジェクトを含んだオブジェクトデータベース（`.git/objects/`）を有しているという話

> `porcelains`のメタデータが付属する

`.git/COMMIT_EDITMSG`のようなファイルを指しているのだと解釈している（`.git/COMMIT_EDITMSG`は、一番最後に実行したコミットのコミットメッセージが記録されているファイル）
その他の例だと、`/git/FETCH_HEAD`（一番最後にfetchを実行した時に取得したリモートのブランチ名やそれが指し示すコミットオブジェクトの情報などを整理したファイル）なども該当すると考えている

> 1つ以上の porcelains のメタデータが付属する可能性がある

`git init`で作成された直後のリポジトリ（`.git`）のように、`.git/COMMIT_EDITMSG`などのファイルが存在しないケースも存在するため、『1つ以上の〜可能性がある』と表現しているのだと解釈

> リポジトリは、alternates mechanism によって他のリポジトリとオブジェクトデータベースを共有することができます。

`alternate object database`（前述）の話


## remote repository

### 原文
A repository which is used to track the same project but resides somewhere else。To communicate with remotes、see fetch or push.

### 和訳
同じプロジェクトを追跡するために使われるが、異なる場所に存在するリポジトリのこと。リモートリポジトリと通信する方法については、fetch や push の説明を確認すること。

### 解説
あるリポジトリに対して、異なる場所に存在している通信可能なリポジトリのこと
具体のリモートリポジトリの場所については`git remote -v`で確認することができる
fetch や push を用いたリモートリポジトリとの通信の話は後述

```bash
git remote -v
origin	git@github.com:hogehoge/fugafuga.git (fetch)
origin	git@github.com:hogehoge/fugafuga.git (push)
```


## refspec

### 原文
A "refspec" is used by fetch and push to describe the mapping between remote ref and local ref.

### 和訳
`refspec` は、リモートrefとローカルrefのマッピングを描くために、fetch と push で使用される。

### 解説

fetch / pull 実行時、リモートリポジトリでのブランチの参照（`refs/heads`以下にあるファイルの中身）を、ローカルリポジトリのどこに書き込むかを示したもの
`.git/config`の中に記述されている（`git clone`や`git remote add`をしたタイミングで自動で記述される）

```bash
# .git/configの一部
[remote "origin"]
	url = git@github.com:hogehoge/fugafuga.git
	fetch = +refs/heads/*:refs/remotes/origin/*  # refspecの記述
```

書式は `<src>:<dst>` であり、オプションとして冒頭に `+` を含めることもできる（`+`については後述）
`<src>`は参照を記録したいリモートリポジトリのブランチを示しており、`<dst>`がローカルリポジトリの書き込む場所を示している
上記`refs/heads/*:refs/remotes/origin/*`の場合、リモートリポジトリの`refs/heads`以下のブランチの参照をローカルリポジトリの`refs/remotes/origin`以下に書き込むということを示している
これにより、fetch実行時リモートリポジトリの`refs/heads`以下にあるブランチの参照は`refs/remotes/origin`に書き込まれるようになる

ワイルドカードを使用せず、以下のように明示的に一つのブランチを指定することも可能

`fetch = +refs/heads/master:refs/remotes/origin/master`

この場合、fetch実行時リモートリポジトリから取得するブランチの参照は`master`のみとなり、ローカルリポジトリの`refs/remotes/origin/master`に書き込むようになる
また、以下のようにリモートリポジトリとローカルリポジトリのブランチ名を同じにせず変えることもできる

`fetch = +refs/heads/master:refs/remotes/origin/mymaster`

`+`のオプションについて、`+`をつけることで`fast-forward`の操作が可能な関係かどうかに関係なく参照を更新するというもの（`+`がついていない場合、`<src>`と`<dst>`が`fast-forward`の操作が可能な関係でないとエラーが発生する）


※ 簡易説明（`fast-forward`の操作が可能な関係）
```
A --- B --- C（← ローカルの`refs/remotes/origin/branch'A'`）
            |
             --- D --- E --- F（← リモートの`refs/heads/branch'A'`）
```

※ 簡易説明（`fast-forward`の操作が可能ではない関係）
```
A --- B --- C --- G（← ローカルの`refs/heads/origin/branch'A'`）
            |
             --- D --- E --- F（← リモートの`refs/heads/branch'A'`）
```

## remote-tracking branch

### 原文
A ref that is used to follow changes from another repository。It typically looks like refs/remotes/foo/bar (indicating that it tracks a branch named bar in a remote named foo)、and matches the right-hand-side of a configured fetch refspec。A remote-tracking branch should not contain direct modifications or have local commits made to it.

### 和訳
別のリポジトリの変更を追跡するために使われる ref のこと。通常は `refs/remotes/foo/bar` のような形をしており (`foo` という名前のリモートリポジトリの `bar` という名前のブランチを追跡していることを示している)、fetch refspec の設定の右側と一致する。remote-tracking branch には、直接変更を加えたりローカルコミットをしてはいけない。

### 解説
`refspec`における `<dst>` の内容に相当するもので、`refs/remotes/foo/bar` の形となっている


## fetch

### 原文
Fetching a branch means to get the branch's head ref from a remote repository、to find out which objects are missing from the local object database、and to get them、too。See also git-fetch[1].

### 和訳
ブランチをフェッチするというのは、リモートリポジトリからブランチの head ref を取得し、ローカルのオブジェクトデータベースから不足しているオブジェクトを調べ、不足しているオブジェクトを取得するということを意味する。git-fetch[1] も参照。

### 解説
`refspec`の情報を参考に、リモートリポジトリの`refs/heads`以下に記述されている内容（ブランチの参照情報）を取得する操作のこと
このとき、リモートリポジトリの`refs/heads`以下に記述されているコミットオブジェクトから reachable なオブジェクトの情報を調べて、ローカルリポジトリのオブジェクトデータベースに不足しているオブジェクトの情報を、ローカルリポジトリのオブジェクトデータベースに追加する


## merge

### 原文
As a verb: To bring the contents of another branch (possibly from an external repository) into the current branch。In the case where the merged-in branch is from a different repository、this is done by first fetching the remote branch and then merging the result into the current branch。This combination of fetch and merge operations is called a pull。Merging is performed by an automatic process that identifies changes made since the branches diverged、and then applies all those changes together。In cases where changes conflict、manual intervention may be required to complete the merge.
As a noun: unless it is a fast-forward、a successful merge results in the creation of a new commit representing the result of the merge、and having as parents the tips of the merged branches。This commit is referred to as a "merge commit"、or sometimes just a "merge".

### 和訳
動詞としての活用：別のブランチの内容（外部リポジトリからの場合もある）を現在のブランチに取り込むこと。マージ先のブランチが別のリポジトリのものである場合、まずリモートブランチを fetch し、その結果(fetchによって取得したリモートリポジトリのブランチ)を現在のブランチに merge する（取り込む）。この fetch と merge の操作の組み合わせを pull と呼ぶ。マージは、ブランチが分岐してからの変更を特定し、それらの変更をまとめて適用する自動プロセスによって行われる。変更が conflict した場合、マージを完了させるために手作業での介入（修正）が必要になることがある。
名詞としての活用：fast-forwardでない限り、マージが成功すると、マージに関係したブランチ（複数）の先端を親に持つマージの結果を表す新しいコミットの生成を行う。このコミットは「merge commit」と呼ばれ、しばしば単に「merge」と呼ばれることもある。

### 解説
動詞の場合：別のブランチの内容を現在のブランチに取り込むこと
別のリポジトリのブランチとマージしたい場合、fetchコマンドを実行して、リモートリポジトリのブランチの情報をローカルリポジトリに取得し、その後取得したリモートリポジトリのブランチ情報を用いてマージの処理を行う（fetchとmergeを処理を合わせたのがpull） 

> マージは、ブランチが分岐してからの変更を特定し、それらの変更をまとめて適用する自動プロセスによって行われる。
詳細はmergeコマンドのリファレンスを参照

名詞の場合は、マージ処理の結果作成されるコミットオブジェクトのことを指す
`fast-forward`でない場合、マージ処理実行時に、merge処理に関係したブランチ（複数）の先端のコミットオブジェクトを親とするコミットオブジェクトが作成される
このコミットオブジェクトを生成するコミットのことを「merge commit」と呼び、名詞で『merge』が使われる場合に同じ意味を表す（`fast-forward`の場合の対応については後述）


#### マージコミットの中身について
parentが2つあるが、それ以外は普通のコミットオブジェクトと同様
```bash
# マージコミットの中身
git cat-file -p e37b2cd2086eb9e430563edd106bf768284708e1
tree 5406e7748e1fd3a8eeed01b306309c799141dfd4
parent c7ce61eb3e0e28e4136c93dd0dac7e31d3b3250b
parent e864cced184661ddcbfe3e665216274d06f644d4
author hogehoge <hogehoge> 1695953120 +0900
committer hogehoge <hogehoge> 1695953120 +0900

Merge branch 'main'

```


## fast-forward

### 原文
A fast-forward is a special type of merge where you have a revision and you are "merging" another branch's changes that happen to be a descendant of what you have。In such a case、you do not make a new merge commit but instead just update your branch to point at the same revision as the branch you are merging。This will happen frequently on a remote-tracking branch of a remote repository.

### 和訳
fast-forward は特殊なマージで、あるリビジョン（コミット）を持っていて、そのリビジョン（コミット）の子孫である他のブランチの変更を取り込むようなマージである。この場合、新しいマージコミットは作られず、その代わりにマージ先のブランチと同じリビジョン（コミット）を指すように現在のブランチを更新します。リモートリポジトリを追跡する remote-tracking branch では、このようなことが頻繁に起こります。

### 解説
下記のようなコミット状況を想定する

```
A --- B --- C（← branch'A'）
            |
             --- D --- E --- F（← branch'B'）
```

`branch'A'` が `branch'B'` の変更を取り込むような状況のマージを fast-forward という
このとき、マージコミットは作成されず、以下のように `branch'A'` が `branch'B'` のコミットを参照するように変更される

```
A --- B --- C
            |
             --- D --- E --- F（← branch'A' branch'B'）
```


> リモートリポジトリを追跡する remote-tracking branch では、このようなことが頻繁に起こります


以下の状況がよく起こる、という意味だと解釈
```
A --- B --- C（← ローカルの`refs/remotes/origin/branch'A'`）
            |
             --- D --- E --- F（← リモートの`refs/heads/branch'A'`）
```


## pull

### 原文
Pulling a branch means to fetch it and merge it。See also git-pull[1].

### 和訳
pullとは fetch して merge することを意味する.

### 解説
pull = fetch + merge



## push

### 原文
Pushing a branch means to get the branch's head ref from a remote repository、find out if it is an ancestor to the branch's local head ref、and in that case、putting all objects、which are reachable from the local head ref、and which are missing from the remote repository、into the remote object database、and updating the remote head ref。If the remote head is not an ancestor to the local head、the push fails.

### 和訳
ブランチをプッシュするということは、リモートリポジトリからブランチの head ref を取得し、それがブランチのローカル head ref の先祖であるかどうかを調べ、先祖である場合、ローカル head ref から到達可能で、リモートリポジトリから欠落しているすべてのオブジェクトをリモートオブジェクトデータベースに入れ、リモート head ref を更新することを意味します。リモートヘッドがローカルヘッドの先祖でない場合、プッシュは失敗します。

### 解説
pushは以下の流れ
1. 指定したリモートリポジトリのブランチが参照している ref の情報（`.git/refs/heads/ブランチ名`の中身）を取得する
2. 現在操作しているリポジトリのブランチが参照している ref の情報と、1で取得した ref の情報の関係（先祖かどうか）を調べる
3. （先祖である場合）現在操作しているリポジトリのブランチが参照している ref から到達可能なオブジェクトの中で、リモートリポジトリのオブジェクトデータベースに存在していないオブジェクトをリモートリポジトリのオブジェクトデータベースに追加し、リモートリポジトリのブランチが参照している ref を現在操作しているリポジトリのブランチが参照している ref に更新する
3. （先祖でない場合）エラーとなり失敗する







# おわりに
gitの『[Glossary](https://git-scm.com/docs/gitglossary)』にはまだまだ用語がたくさんあるのですが、よく見聞きする用語についてはおおむねカバーできたのではないかと思います
弊社では、本記事のように基礎・基本を正しく学び、適切な技術の基盤を作っていく勉強会も活発に行っております
ご興味持ってくださった方は応募の検討も是非してみてください〜

https://herp.careers/v1/litalico/requisition-groups/ea1f6b9d-88b7-4254-a06a-8cfdd83bd575


明日は、PHPのカンファレンスに複数回登壇している凄腕エンジニアの @katzumi さんの記事になります！
是非明日の記事も楽しんでいってください〜！