2026/06/18

Gitリポジトリの操作

Gitでは変更の保存先が4つの場所に分かれており、コマンドによってどの場所まで変更を反映するかが決まる。
`add` → `commit` → `push` と段階を踏むのが基本で、`commit -a` や `pull` は複数の操作をひとつのコマンドにまとめた省略形にあたる。

---

## 4つの場所

| 場所 | 別名 | 物理的な位置 | 役割 |
|------|------|-------------|------|
| Workspace | 作業ディレクトリ | 自PC(.git/ の外) | 実際にファイルを編集する場所 |
| Index | ステージングエリア | 自PC(.git/ 内) | 次のコミットに含める変更を仮置きする場所 |
| Local repo | ローカルリポジトリ | 自PC(.git/ 内) | コミット履歴・ブランチの保管場所 |
| Remote repo | リモートリポジトリ | 外部サーバー | GitHub / GitLab など、チームで共有する場所 |

---

## ブランチの実体

すべてのブランチは `.git/` フォルダ内に格納されている。Workspaceに見えているファイルは「現在チェックアウトしているブランチの中身」だけ。

```
repo/
  ├── .git/
  │   ├── refs/
  │   │   ├── heads/          ← ローカルブランチの参照
  │   │   │   ├── main
  │   │   │   └── branch-xxx
  │   │   ├── remotes/
  │   │   │   └── origin/     ← リモートブランチの参照
  │   │   │       ├── main
  │   │   │       └── branch-xxx
  │   │   └── stash            ← stashスタックの先頭を指す参照
  │   ├── logs/
  │   │   └── refs/
  │   │       └── stash        ← stash履歴(stash@{n}の一覧)
  │   ├── worktrees/           ← 追加した各worktreeごとのHEAD・indexを保持
  │   │   └── repo-feature/
  │   └── objects/            ← 全ブランチ・stash・worktreeの中身が圧縮されて格納
  ├── app/
  ├── resources/
  └── ...                     ← 現在のブランチの中身だけが見えている
```

ブランチを切り替えると、`.git/objects/` から該当ブランチのファイルが展開されWorkspaceが書き換わる。
stashも同じ`.git/`内に、通常のコミットと同じ仕組み(コミットオブジェクト)で保存される。
worktreeを追加すると、`.git/worktrees/`配下に専用のHEAD・indexが作られ、`objects/`は元のリポジトリと共有される。

---

## 送信系コマンド(ローカル → リモート方向)

### `git add`:Workspace → Index

```bash
git add <ファイル>   # 指定ファイルをステージ
git add .           # 全変更をステージ
```

### `git commit`:Index → Local repo

```bash
git commit -m "メッセージ"
```

### `git commit -a`:Workspace → Local repo(add + commit を一括)

```bash
git commit -a -m "メッセージ"
```

追跡済みファイル(tracked)の `add` と `commit` を一括で実行する省略形。
新規ファイル(untracked)は自動でステージされないため、別途 `git add` が必要。

### `git push`:Local repo → Remote repo

```bash
git push origin main
git push -u origin main   # 初回。-u で upstream を設定し、以後は git push だけで OK
```

---

## 取得系コマンド(リモート → ローカル方向)

### `git fetch`:Remote repo → Local repo

```bash
git fetch origin
```

リモートの更新を Local repo に取り込むだけ。Workspace は変化しない。
取得後に `git log origin/main` で差分を確認してから merge できる。

### `git pull`:Remote repo → Workspace(fetch + merge を一括)

```bash
git pull origin main
```

`fetch` に続いて merge まで一括で行い、Workspace まで反映する。
コンフリクトが起きる可能性があるため、`fetch` → 確認 → `merge` の順が安全。

### `git checkout` / `git switch`:Local repo → Workspace

```bash
git checkout <ブランチ名>   # ブランチを切り替えてワーキングツリーを更新
git switch <ブランチ名>     # 現代的な書き方(checkout の代替)
```

### `git restore`:Local repo → Workspace または Index

```bash
git restore <ファイル>              # Workspace の変更を最終コミット時点に戻す
git restore --staged <ファイル>     # Index の変更を取り消す(Workspace は変化しない)
```

### `git clone`:Remote repo → Workspace(初回のみ)

```bash
git clone 
```

`init` + `fetch` + `checkout` を一括実行し、リポジトリ全体をローカルにコピーする。

---

## 一時退避コマンド(Workspace/Index → Stash)

`stash`はリモートにもLocal repoの通常の履歴にも残らない、作業途中の変更専用の一時置き場。対象ファイルの指定は不要で、デフォルトでトラッキング済みファイルの変更がすべて退避される。

```bash
git stash                              # 変更中の全ファイルをstash
git stash push -m "ログイン機能の途中作業"  # メッセージ付き(推奨)
git stash -u                            # 未追跡(untracked)ファイルも含める
git stash list                          # 一覧確認
git stash pop                           # 最新のstashを適用して削除
git stash apply stash@{1}               # 特定のstashを指定して適用(stashは残る)
git stash drop stash@{0}                # 適用せず削除だけ
```

`pop`は適用後にstashを削除、`apply`は残したまま適用する(複数ブランチに同じ変更を当てたい場合などに使う)。

---

## 比較系コマンド(差分確認)

| コマンド | 比較する場所 | 確認できること |
|----------|-------------|----------------|
| `git status` | Workspace ↔ Index ↔ Local repo(HEAD) | 3箇所を横断し、Untracked / 未add(Modified) / Staged(add済み未commit)をまとめて一覧表示 |
| `git diff` | Workspace ↔ Index | `add` 前の変更(まだステージしていない差分) |
| `git diff HEAD` | Workspace ↔ Local repo | 最終コミットから現在までの全差分 |
| `git diff --staged` | Index ↔ Local repo | `add` 済みでまだ `commit` していない差分 |

---

## リポジトリの作成

### `git init`:空のローカルリポジトリを新規作成する

手元にあるフォルダをGit管理下に置く。Remote repo なしのローカル完結でも運用でき、後から `git remote add` でリモートに接続することもできる。

```bash
mkdir my-project && cd my-project
git init
git add .
git commit -m "first commit"

# ローカル完結の場合はここまで。以降は add → commit を繰り返す。

# Remote repo に接続する場合は GitHub で空リポジトリを作成してから実行
git remote add origin https://github.com/user/repo.git
git push -u origin main
```

### `git clone`:リモートリポジトリをローカルに取得する

GitHub 側でリポジトリを先に作り、手元に持ってくる場合。`init` + `fetch` + `checkout` を一括で行う。

```bash
git clone https://github.com/user/repo.git
cd repo
```

---

## ブランチ切り替えとフォルダの関係

ブランチを切り替えても**フォルダ自体は変わらない**。Gitがフォルダ内のファイルをブランチに合わせて自動的に書き換える。

```
repo/   ← フォルダは変わらない
  ├── app/
  ├── resources/
  └── ...        ← 中身(ファイルの内容)がブランチに合わせて切り替わる
```

通常の`checkout`は「1つのフォルダで1つのブランチ」しか同時に見られない。複数ブランチを同時に別々のフォルダで開きたい場合は`git worktree`を使う。

---

## 複数ブランチの同時チェックアウト(git worktree)

`git worktree`を使うと、同じLocal repoを共有したまま、ブランチごとに別々のWorkspace(フォルダ)を用意できる。`clone`と違い`objects/`は共有されるため、コミットやfetchの内容が全worktreeへ即座に反映される。1ブランチにつき1 Workspaceが原則で、同じブランチを複数worktreeで同時チェックアウトはできない。

```bash
git worktree add ../repo-feature branch-xxx     # 既存ブランチ用に新しいフォルダを作成
git worktree add ../repo-hotfix -b hotfix/xxx   # 新規ブランチも同時に作成してチェックアウト
git worktree list                                # 一覧確認
git worktree remove ../repo-feature              # 削除(未コミットの変更がある場合は --force)
git worktree prune                                # フォルダを直接削除した場合の参照掃除
```

---

## `gh pr checkout`:Remote repo → Workspace(PRブランチへの切り替え)

内部的に `git fetch` + `git checkout` の2ステップが走る複合操作。cloneしたリポジトリのフォルダ内で実行する必要がある(空フォルダでは実行不可)。

```bash
cd repo/		      # cloneしたフォルダへ移動(mainブランチ)
gh pr checkout 2      # PR #2のブランチに切り替わる
git checkout main     # 作業完了後、mainブランチに戻す
git branch            # 現在のブランチを確認(*が付く)
```

---

## `git remote add`:既存のローカルリポジトリをリモートに接続する

`git init` 済みのプロジェクトを後から GitHub に紐づける場合。

```bash
git remote add origin https://github.com/user/repo.git
git branch -M main
git push -u origin main
```

0 件のコメント:

コメントを投稿

人気の投稿