Git は、コード履歴、ブランチ、マージ、チーム コラボレーションを管理するための分散バージョン管理システムです。
1.コアモデル
Working Tree(ワークスペース)
↓ git add
Index / Staging Area(ステージングエリア)
↓ git commit
Local Repository(地元の倉庫)
↓ git push
Remote Repository(遠隔倉庫)
3 つの主要な領域:
| エリア | 機能 |
|---|---|
| Working Tree | 現在編集中のファイル |
| Staging Area | 提出書類の内容 |
| Local Repository | 保存された Commit 履歴 |
注: git add はファイルの追跡を開始するだけでなく、さらに重要なことに、の現在のファイル内容のスナップショット を一時記憶域に配置します。
したがって、同じファイルにステージングされた変更とステージングされていない変更の両方が含まれる可能性があります。
2. 中心となる概念
Repository
Git ウェアハウスには、送信オブジェクト、ブランチ参照、履歴レコードなどの情報が含まれています。
git init
git clone <url>
通常、ウェアハウスには .git/ ディレクトリが含まれます。
Tracked / Untracked
- Tracked: ファイルはすでに Git によって追跡されています。
- Untracked: Git ファイルはまだ追跡されていません。
- Modified: ファイルの内容が変更されました。
- Staged: 変更は一時記憶域に入りました。
git status
.gitignore
まだ追跡されていないファイルを無視するために使用されます。
node_modules/
.env
dist/
__pycache__/
すでに追跡されているファイルは、.gitignore が追加されても引き続き追跡されます。
トレースを停止しますが、ローカル ファイルは保持します。
git rm --cached .env
機密情報が Git 履歴に送信された場合、追跡を停止しても既存の履歴内の漏洩コンテンツは消去されません。対応するキーを取り消し、履歴を消去することも検討する必要があります。
Commit
Commit は、特定の時点でのプロジェクトの完全なスナップショットとして理解でき、親 Commit、作成者、時刻、投稿情報などのメタデータを保存します。
A ── B ── C ── D
↑
main
各 Commit には固有のオブジェクト ID があります。
HEAD
HEAD は通常、現在のブランチへのシンボリック参照です。
HEAD → main → D
一般的な表現:
| 表現 | 意味 |
|---|---|
HEAD | 現在のコミット |
HEAD^ | 最初の親コミット |
HEAD~2 | 最初の親コミットに沿って 2 回前進します |
HEAD~3 | 最初の親コミットに沿って 3 回前進します |
HEAD^2 | 2 番目の親コミット、Merge Commit で共通 |
HEAD^3 は最初の 3 つのコミットではなく、3 番目の親コミットです。
Detached HEAD
Commit に直接切り替えます。
git switch --detach abc123
現時点では、HEAD はブランチではなく Commit を直接指します。
過去のコードを確認するのに適しています。ここで開発を続ける準備ができている場合は、新しいブランチを作成する必要があります。
git switch -c fix/old-version
3. ローカル支店とリモート追跡支店
Git は分散バージョン管理システムです。
GitHub:
main → C
Local:
main → B
origin/main → C
main: ローカル支店。origin/main: ローカルに保存されたリモート追跡ブランチのステータス。origin: リモート倉庫の名前。通常は clone によって自動的に作成されます。
新しいコミットがリモートで生成された場合:
GitHub:
A ── B ── C ── D
Local:
main → B
origin/main → C
実行:
git fetch origin
更新日:
main → B
origin/main → D
ただし、ローカルの main は直接変更されません。
fetch および pull
git fetch origin
現在の作業ブランチを直接マージせずに、リモート更新を取得します。
git pull
最初に Fetch、次に Merge、Rebase、または構成に応じて Fast-forward のみ。
以下を明示的に指定します。
git pull --no-rebase
git pull --rebase
git pull --ff-only
偶発的なマージ コミットを回避したいシナリオでは、--ff-only を使用します。
4. 基本コマンド
初期化と構成
git init
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git clone <url>
ステータスの表示
git status
git branch
git branch -a
git remote -v
ステージングと提出
git add src/foo.ts
git add .
git commit -m "feat: add user profile"
git add . 現在のディレクトリおよびサブディレクトリ内の修飾された追加、変更、および削除を一時記憶領域に追加します。
送信する前に次のことを確認することをお勧めします。
git diff --staged
違いを表示する
# ワークスペースとステージングエリア
git diff
# 一時保管場所や HEAD
git diff --staged
# 2つ Commit
git diff A B
# 単一のコミットを表示する
git show <commit>
履歴を見る
git log
git log --oneline
git log --oneline --graph --decorate --all
git log -n 5
git log --author="Author Name"
その中には:
git log --oneline --graph --decorate --all
ブランチおよびマージ関係の表示に適しています。
5.支店管理
作成して切り替える
git branch feature/login
git switch feature/login
# 作成して切り替える
git switch -c feature/login
削除
# 安全な削除
git branch -d feature/login
# 強制削除
git branch -D feature/login
# リモートブランチを削除する
git push origin --delete feature/login
-d は、ブランチが適切にマージされたことをチェックします。 -D は、この安全性チェックをスキップします。
名前の変更
git branch -m new-name
Upstreamでプッシュ
git push -u origin feature/login
-u は、ローカル ブランチと上流ブランチの間の追跡関係を確立します。
その後、通常は次のことが可能になります。
git push
git pull
ただし、実際の Push ターゲットも Git 構成の影響を受けます。
6. Merge: ブランチをマージします
仮定:
C ── D feature
/
A ── B ── E main
main:
git switch main
git merge feature
結果:
C ── D ──┐
/ │
A ── B ── E ───── M
↑
main
Merge Commit M には 2 つの親コミットがあります。
Git は、共通の先祖と両側の変更に基づいて 3 方向のマージを実行します。
Fast-forward Merge
main が新しいコミットを生成しない場合:
A ── B main
\
C ── D feature
実行:
git switch main
git merge feature
結果:
A ── B ── C ── D
↑
main, feature
このとき、Git は分岐ポインタを前方に移動するだけでよく、必ずしも新しい Merge Commit を作成する必要はありません。
7. Rebase: リベース
仮定:
A ── B ── C main
\
D ── E feature
feature ブランチで実行します。
git switch feature
git rebase main
結果:
A ── B ── C main
\
D' ── E' feature
Rebase ブランチ内のコミットを新しいベース コミットに再適用した後。
通常、親コミットなどの情報の変更により、新しい Commit ID が生成されます。
Merge および Rebase
| コントラスト | Merge | Rebase |
|---|---|---|
| 本来の歴史 | 予約する | 再生されたコミットを書き直す |
| 図を送信する | フォークと Merge Commit が生成される可能性があります | 通常はより直線的です |
| 共有ブランチ | 比較的安全な | 勝手に書き換えてはいけません |
| 一般的な用途 | 機能ブランチをマージする | 個人開発ブランチを更新 |
共通原則:
- Rebase の書き換えを避けるために、チームで共有されている履歴を優先する必要があります。
- 独立して保守される機能ブランチの場合、Rebase を使用して履歴を整理できます。
- 詳細は、チームの Git ワークフロー仕様の対象となります。
8. Merge / Rebase の競合
競合の例:
<<<<<<< HEAD
const timeout = 30;
=======
const timeout = 60;
>>>>>>> feature
最終的なコンテンツは手動で決定し、競合するマーカーを削除する必要があります。
Merge 競合
git status
# 競合ファイルを変更する
git add config.ts
git merge --continue
適切な状況で git commit を実行してマージを完了することもできます。
Merge をあきらめます:
git merge --abort
Rebase 競合
git status
# 競合ファイルを変更する
git add config.ts
git rebase --continue
Rebase をあきらめます:
git rebase --abort
注: Rebase の場合、ours および theirs の意味は通常の Merge と混同されやすく、「自分のコード」と「他人のコード」として機械的に理解できません。
9. Restore、Reset、Revert
3 つの命令はすべて取り消しに関連していますが、責任は異なります。
git restore
主にワークスペースまたは一時記憶領域にファイルの内容を復元します。
# ファイルに対するステージングされていない変更を破棄し、元の状態に戻します。 Index
git restore src/foo.ts
# 一時保存をキャンセルし、ワークスペースの変更を保持します
git restore --staged src/foo.ts
# ステージング領域とワークスペースの両方が復元されます。 HEAD
git restore --source=HEAD --staged --worktree src/foo.ts
注: デフォルトでは、git restore file はソースとして Index を使用しますが、これは必ずしも HEAD と等しいわけではありません。
git reset
現在のブランチの Commit ポインタを移動し、モードに応じてステージング領域とワークエリアを変更するかどうかを決定できます。
| モード | HEADを移動する | Indexをリセット | Working Treeをリセット |
|---|---|---|---|
--soft | はい | いいえ | いいえ |
--mixed (デフォルト) | はい | はい | いいえ |
--hard | はい | はい | はい |
たとえば:
# 最後を元に戻す Commit,ステージングを続ける
git reset --soft HEAD~1
# 最後を元に戻す Commit,ワークスペースの変更を保持しますが、ステージングは解除します
git reset HEAD~1
# 指定されたコミットに戻り、ワークスペースとステージング領域をリセットします。
git reset --hard abc123
--hard は破壊的であり、コミットされていない作業が失われる可能性があります。他の人によってプルされたコミットの場合は、通常、Reset の後に強制的にプッシュしないでください。
ファイルを指定する場合:
git reset HEAD -- src/foo.ts
現在のブランチを移動せずに、ファイルの一時コンテンツを HEAD に復元するだけです。
git revert
元の履歴を削除せずに、新しいリバース コミットを作成します。
A ── B ── C ── D
↓ revert C
A ── B ── C ── D ── E
git revert <commit>
チームの共有ブランチに対する Push のコミットに適しています。
選び方は?
| 需要 | おすすめ |
|---|---|
| ステージングされていない変更を破棄する | git restore |
| アンステージ | git restore --staged |
| プッシュされていない Commit を元に戻し、変更を保持します | git reset --soft |
| 共有ブランチの Commit を元に戻す | git revert |
| ローカルの変更を完全に破棄してロールバックします | git reset --hard、慎重です |
10. 最終変更 Commit
提出情報を変更します。
git commit --amend
ファイルを追加するのを忘れました:
git add forgotten.py
git commit --amend --no-edit
--amend は実際には、現在のブランチの末尾にある古い Commit を置き換える新しい Commit を作成します。
古いコミットが共有ブランチに Push されている場合は注意してください。
11. Stash: 変更を一時的に保存します
git stash は、コミットされていない作業を一時的に保存するために使用されます。
git stash
デフォルトでは、追跡されたファイルのステージングされた変更とステージングされていない変更は保存されますが、通常の Untracked ファイルは保存されません。
新しいファイルを含める必要があります。
git stash push -u -m "WIP: profile form"
よく使用されるコマンド:
git stash list
# 最新のものを復元する Stash,そしてリストから削除します
git stash pop
# 復元するが保持する Stash
git stash apply
# 指定されたものを削除する Stash
git stash drop stash@{0}
開発中の一時的な切り替え作業に適しています。
注: stash pop は競合する可能性があり、回復プロセスが成功しない可能性があります。
12. Cherry-pick: 指定された提出物を選択します
仮定:
main: A ── B ── C
feature: A ── B ── D ── E
D の変更を main に適用したいだけです。
git switch main
git cherry-pick <D>
結果:
main: A ── B ── C ── D'
該当するシナリオ:
- 他のブランチから Bug Fix を選択します。
- ブランチをリリースするために特定の修正をバックポートします。
- 機能ブランチ全体をマージしたくない。
通常、Cherry-pick は新しい Commit を作成します。
13. Reflog: 失われたコミットの取得
git reflog は、ローカル HEAD および参照の履歴変更の一部を記録します。
git reflog
たとえば、次のように実行します。
git reset --hard HEAD~2
ロールバックが間違っていることがわかった場合は、まず次のコマンドを実行します。
git reflog
オリジナルの Commit ID を見つけます。
次に、回復ブランチを作成します。
git branch recovery <commit-id>
または、安全を確認してから再度 Reset をお試しください。
次の点に注意する必要があります。
- Reflogは主にローカル記録です。
- Reflog エントリは期限切れになります。
- コミットされていない変更をすべて取得できるという保証はありません。
誤って Commit を見つけた後に見つからない Reset、Rebase を回復するのに特に適しています。
14. Tag: バージョンラベル
Tag は通常、リリース バージョンをマークするために使用されます。
軽量タグ:
git tag v1.0.0
注タグ:
git tag -a v1.0.0 -m "Release v1.0.0"
プッシュ:
git push origin v1.0.0
チェックアウト:
git tag
git show v1.0.0
Tag は Branch とは異なります。
- Branch は通常、新しい Commit と一緒に動きます。
- Tag は通常、特定のオブジェクトを指します。
15. 強制プッシュ
git push --force
リモートブランチ履歴は強制的に上書きされる可能性があり、これには高いリスクが伴います。
実際に独自のブランチ履歴を書き換える必要がある場合には、これを使用することをお勧めします。
git push --force-with-lease
リモート参照がローカルの期待と一致しているかどうかをチェックし、他の人の新しいコミットを上書きするリスクを軽減します。
ただし、絶対的な安全を意味するわけではありません。特にバックグラウンドでの Fetch や複雑なチーム コラボレーション シナリオでは、依然として注意が必要です。
共有 main ブランチを任意に強制的にプッシュしないでください。
16. 日々の開発ワークフロー
ステップ 1: 機能ブランチを作成する
git switch main
git pull --ff-only
git switch -c feature/avatar-upload
ステップ 2: 開発して送信する
git status
git diff
git add .
git diff --staged
git commit -m "feat: add avatar upload"
ステップ 3: プッシュする
git push -u origin feature/avatar-upload
GitHub で Pull Request を作成し、Review を待ちます。
ステップ 4: Review に従って変更します。
git add .
git commit -m "fix: validate avatar file type"
git push
ステップ 5: PR マージ後のクリーンアップ
git switch main
git pull --ff-only
git branch -d feature/avatar-upload
リモート関数ブランチがプラットフォームによって自動的に削除されない場合は、オンデマンドで削除できます。
git push origin --delete feature/avatar-upload