🎎

「originってどこにいるの?」.gitフォルダの中身からGitの仕組みを紐解く

2025/03/03に公開

はじめに

前回gitignoreの使い方や設定時の注意点をまとめました。
https://zenn.dev/channnnsm/articles/2cc6b5f875229d

当初gitとつくから、.gitフォルダに入っているもんだと思っていましたが、整理した中で、.gitフォルダ.gitignoreファイルの役割の違いを理解しました。

普段何気なく使っていたgit push origin ブランチ名のoriginがどこにいるのかが明らかになって、はれてgitコマンドの意味を語れるようになりました。

また、Git履歴を消して新規リポジトリとして管理したいケースがあり、その手順も残します。

最初にまとめを貼っておきます!

.gitフォルダ.gitignoreファイルってどう違うんだっけ

まずGitフォルダを表示する

そもそもGitフォルダは、.で始まる隠しファイルで、初期設定だと表示されません。
Windows環境でCursorに.gitフォルダを表示するには、以下の方法を試しました。

  1. Cursor Settings > General > AppearanceのOpen editor settings.を開く

  2. 検索バーに「files.exclude」と入力

  3. .gitフォルダが除外されている場合、リストから削除する

他のエディタでの表示方法については、各エディタのドキュメントをご参照ください。

Gitの基本構造と.gitignoreの役割

Gitの基本的な仕組みや「.git」ディレクトリの役割、fetchやremotesなどの概念を整理します。
(※ディレクトリもフォルダも同じ意味合いで使っています)

1. .git ディレクトリ

  • git init を実行すると、カレントディレクトリに .git という隠しフォルダが作成される。
  • このフォルダがGitの「履歴管理」のすべてを保持しており、以下のようなものが含まれる。
    • hooks: Gitフックのサンプルスクリプト(Git操作の前後に自動的にアクションを実行できる)
    • info: リポジトリに関する追加情報
    • objects:コミットデータやファイルのスナップショット
    • refs:ブランチやタグの情報
      • heads:ローカルのブランチの情報
      • remotes:リモートのブランチの情報 ※初期状態では存在しないが、リモートリポジトリを追加するとここに格納
        • origin:よく使うoriginはremotesの配下にいる!

.git を削除するとGitの管理情報が失われ、追跡が解除される。

📅※2025年3月3日時点で、git initしたときの初期状態のディレクトリ構成

.git
├── hooks  # Gitフックのスクリプトが格納されるディレクトリ
│   ├── applypatch-msg.sample  # applypatch-msgフック
│   ├── commit-msg.sample  # commit-msgフック
│   ├── fsmonitor-watchman.sample  # fsmonitor-watchmanフック
│   ├── post-update.sample  # post-updateフック
│   ├── pre-applypatch.sample  # pre-applypatchフック
│   ├── pre-commit.sample  # pre-commitフック
│   ├── pre-merge-commit.sample  # pre-merge-commitフック
│   ├── pre-push.sample  # pre-pushフック
│   ├── pre-rebase.sample  # pre-rebaseフック
│   ├── pre-receive.sample  # pre-receiveフック
│   ├── prepare-commit-msg.sample  # prepare-commit-msgフック
│   ├── push-to-checkout.sample  # push-to-checkoutフック
│   ├── sendemail-validate.sample  # sendemail-validateフック
│   ├── update.sample  # updateフック
├── info  # Gitの補助情報を格納するディレクトリ
│   ├── exclude  # グローバルな.gitignoreのような機能を持つファイル
├── objects  # Gitオブジェクト(コミット・ツリー・ブロブ)を格納するディレクトリ
│   ├── info  # オブジェクト関連のメタデータを格納するディレクトリ
│   ├── pack  # Gitのパックファイル(圧縮されたオブジェクト)を格納するディレクトリ
├── refs  # ブランチやタグの参照情報を格納するディレクトリ
│   ├── heads  # 各ローカルブランチの参照情報
│   ├── tags  # タグの参照情報
├── config  # リポジトリの設定ファイル(ユーザー名、リモート設定など)
├── description  # リポジトリの説明(Gitwebなどのインターフェースで使用される)
└── HEAD  # 現在のブランチを指し示すファイル

2. ローカル環境 と リモート環境 の関係性

  • リモート (GitHub等) にある最新の情報を取得するにはgit fetchを実行する必要がある。
  • fetchしただけでは、remotes/origin/mainは更新されるが、main(ローカルブランチ、ローカルの作業ディレクトリ)はそのままで反映されず、git mergegit pullを使って統合する必要がある。
  • remotes/origin/にあるデータは、サーバーから取得した状態のもので、ローカルのheadsとは別管理。
  • .githubディレクトリは、GitHub Actions(CI/CDの設定)などが含まれており、.gitとは役割が異なる。

3. .gitignore の役割

  • Gitで管理したくないファイルやフォルダを指定するための設定ファイル
  • .gitignoreに書かれたパターンに一致するファイルは、git addしてもステージングされない

📌 .gitignore によく含まれるもの

分類
環境依存のファイル .DS_Store(Mac)、Thumbs.db(Windows)
ログファイル *.log
ビルド成果物 dist/, build/, *.o
依存パッケージ node_modules/, venv/
個人情報や設定ファイル .env, config.yml, *.pem

→ すでにGit管理下にあるファイルは、.gitignore に追加しても無視されないので、git rm --cached <ファイル名> する必要がある。

  • 例えば、誤ってsecrets.txtというファイルをGit管理下に追加してしまった場合、.gitignoreにsecrets.txtを追記しただけでは、まだGitの管理対象のままです。
  • この状態から管理対象を外すには、git rm --cached secrets.txtを実行する必要があります。
  • その後、コミットすることで、変更が.gitignoreに反映され、secrets.txtはGitの管理対象から外れます。

Gitフォルダとgitignoreの違いのまとめ

  • .git はリポジトリの履歴や管理情報を保持するフォルダで、削除するとGitの管理が解除される
  • git fetch はリモートの状態をローカルに反映するが、ローカルの作業ディレクトリは変更されない
  • .gitignore はGitで管理したくないファイルを指定するもので、すでに管理されているファイルには効果がない
  • .github はGitHub用の設定ファイルを含むフォルダで、.git とは別物

Git履歴を消して新規リポジトリとして管理する手順

クローンしたリポジトリの過去の履歴を消して、ローカルで新しいプロジェクトとして作業したいケースがあります。

そうすることのメリットは、
・過去の履歴を完全に削除し、クリーンな状態で作業できる
・不要なコミット履歴や.gitフォルダの肥大化を防げる
・履歴に含まれてしまった秘密情報(APIキーなど)を完全に削除できる

手順:

  1. GitHubで新しいリポジトリを作成を済ませておく
  2. GitHub からコピーしたい元のリポジトリをクローン
    git clone <コピーしたい元のリポジトリのURL>
    cd <リポジトリ名>
    
  3. .git フォルダを削除
    rm -rf .git  # macOS/Linux
    rd /s /q .git  # Windows (PowerShell)
    
    この時点で、過去の履歴は完全に消えています。
  1. 新しいGitリポジトリとして初期化

    git init
    

    このコマンドで新しい .git フォルダが作成され、Gitの管理がリセットされます。

  2. ファイルをステージング&コミット

    git add .
    git commit -m "Initial commit"
    
  3. 事前に作っていた新しいリポジトリのリモートに追加

    git remote add origin <新しいリポジトリのURL>
    
  4. 初回プッシュ

    git push -u origin main
    

    ※main はブランチ名です。ご利用のブランチ名に合わせて変更してください。

代替案として「Gitの履歴を特定の状態にリセットする」git rebase -i HEAD~ngit filter-branchという方法もあります。

おわりに

Gitの基本構造や、gitフォルダの中にどんなファイルが格納されているのか理解できました。
また、流れを図解したことで、直感的にもイメージがしやすくなりました。

最後に、今回参考にした記事を載せておきます!

https://git-scm.com/docs/git-init

https://git-scm.com/book/ja/v2/Git-の基本-変更内容のリポジトリへの記録#r_ignoring

Discussion