本機テスト環境:macOS 11
01 | コース概要#
VSC:バージョン管理システム
- 中央集権型 —— クライアントは常にサーバーに接続している必要がある
- SVM
- 分散型 —— サーバーとクライアントの両方に完全なリポジトリがある
- Git、Linus 開発
- Git ベースのオープンソースコミュニティ —— 背景:DevOps 時代、開発運用
- GitHub—— 世界最大
- GitLab—— 企業でよく使用される;無料、継続的インテグレーション - CI を提供;例:阿里云、点评
02 | Git のインストール#
- はじめに - Git のインストール—— 公式サイト:Linux、macOS、Windows、ソースコード
03 | Git を使用する前に必要な最小限の設定#
## nameとemailの設定を追加
git config [--local | --global | --system] user.name 'あなたの名前'
git config [--local | --global | --system] user.email 'あなたのメール'
## 既存の設定を確認
git config --list [--local | --global | --system]
## 違い
## --local:このリポジトリ
## --global: 現在のユーザーのすべてのリポジトリ
## --system: このシステムのすべてのユーザー
- 効果:人員情報を記録し、CR(コードレビュー)時にメール通知を行うことができる
04 | 最初のリポジトリを作成し、ローカルユーザー情報を設定する#
- リポジトリを作成する 2 つの方法、どちらも.git フォルダを生成する
## 既存のプロジェクトフォルダ内にgitリポジトリを作成
git init
## [プロジェクト名]という名前の新しいgitリポジトリを作成
git init [プロジェクト名]
- ローカルユーザー情報を個別に設定する必要がある場合は、--local 設定を使用すればよい。この設定は最優先される。前のセクションを参照
- 簡単な commit を行う❗️
## このgitプロジェクトにファイルを追加する、略
## commitするファイルを追加
git add [ファイル名]
### PS:現在のパス下のすべてのファイルを追加—— git add .
## メッセージを添えてcommit操作を行う
git commit -m'何らかのメッセージ'
### gitの状態を確認する、例:どのファイルがcommit待ちで、どのファイルが追跡されていないか
git status
### gitの記録を確認する、例:commitの記録
git log
05 | いくつかの commit を通じて作業ディレクトリとステージングエリアを理解する#
- ステージングエリア❗️——Git の本質の一つ
- 使用シーン:2 つのプランを開発する、最初のプランが完成したら一時保存し、次に 2 つ目のプランを作成する。2 つ目のプランが最初のプランよりも良くない場合、最初のプランに戻ることができる
- PS:
- 作業ディレクトリの特定のファイルをステージングエリアに置き換えたい場合は、
git checkout -- file
- 作業ディレクトリの変更されたすべてのファイルを復元してステージングエリアと同じにするには、
git checkout *
- 作業ディレクトリの特定のファイルをステージングエリアに置き換えたい場合は、
git add -u
とgit add .
- 前者:追跡されているファイルのみを操作し、ファイルの変更と削除をステージングエリアに追加する
- 後者:新しいファイルの作成も操作し、ファイルの作成、変更、削除をステージングエリアに追加する
- PS:
git add all/-A
はリポジトリ全体に対して行われ、現在のパスだけではない
- 具体的な操作は前のセクションと似ている —— 簡単な commit
06 | ファイルの名前を変更する簡便な方法#
- ステップを詳細化
## 名前を変更
mv readme readme.md
## 新しいファイルreadme.mdを追加
git add readme.md
## 追跡されている古いファイルreadmeを削除
git rm readme
## 提交
git commit -m"rename"
git reset --hard
を使用して最新の commit に戻す、つまりステージングエリアを空にする- 簡略化されたステップを再表示
## 一つのコマンドで上記の3つを実行
git mv readme readme.md
## 提交
git commit -m"rename"
- 実践的なデモ
git status を使用してステージングエリアの状態をリアルタイムで観察する。
PS:最初の方法でも git status は renamed を検出できる
07 | git log を使用してバージョンの進化の歴史を確認する#
## 簡潔な単行の履歴を確認
git log --oneline
## 最近の4つの履歴を確認
git log -n4
git log -4
## すべてのブランチの履歴を確認
git log --all
## 指定したブランチ(名はBRANCH_NAME)の履歴を確認
git log BRANCH_NAME
## グラフィカルなバージョン履歴を確認
git log --graph
## 組み合わせて使用:すべてのブランチの最近の4つのグラフィカルな単行履歴を確認
git log --all -n4 --graph --oneline
## ウェブ版のgit logヘルプドキュメントにジャンプ
git help --web log
git log --all -n4 --graph --oneline
の効果図
追加コマンド
git branch
でローカルにどのようなブランチがあるかを確認し、-a
を使用するとローカルとリモートのブランチを同時に確認できるgit checkout -b
<new_branch> []- commit hash 値を start point とする新しいブランチ new_branch を作成
- 簡便のため、start point は hash 値の一部を選択でき、commit を一意に識別できればよい
git commit -am'msg'
- 作業ディレクトリとステージングエリアのファイルを直接バージョン管理に追加し、add を使用したのと同等
- ⚠️:追跡されているファイルのみを commit でき、新しいファイルは先に
git add .
でステージングエリアに追加する必要がある
PS
- ~ /.zshrc で、エイリアスを設定してよりフレンドリーな log 表示方法を設定でき、設定後は
lg ...
を使用するだけ
alias lg="git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
- 一般的に、単一文字のオプションは
-
に対応し、非単一文字のオプションは--
08 | gitk:グラフィカルインターフェースツールを使用してバージョン履歴を確認する#
- Mac でのインストール:
brew install git-gui
- 使用:
gitk
- インターフェースの簡単な表示
- View-New View を選択し、All refs を選択すると、すべてのブランチ、タグ情報が表示される
- 特定の commit を右クリックすると、多くの操作が可能で、Create tag などがある
PS
- なぜ一度の commit に著者 Author とコミッター Committer がいるのか
- 著作権を尊重するため
- 例えば
git cherry-pick
コマンド:指定した commit を他のブランチに適用する - 具体的な使用はgit cherry-pick チュートリアルを参照 —— 阮一峰
- もう一つの Git グラフィカルインターフェースツールを推薦:Sourcetree、実際にはツール間の違いは少なく、個人の習慣による
09 | .git ディレクトリの秘密を探る#
Git は優れたストレージ能力を持ち、ネットワークがなくてもローカルでバージョン管理ができる
- 🌟4 つの重要なファイル:HEAD、config、refs、objects、以下でそれぞれ分析する
- ❗️3 つの重要なオブジェクト:commit、tree、blob、PS:tag
- 関係図は上記の通り、参考:GIT オブジェクトモデル——Git Community Book 日本語版
- blob:Binary Large Object の略で、バイナリ大オブジェクト、ファイルオブジェクトとして理解できる
- 次のセクションでも詳しく説明するが、まずは 4 つの重要なファイルを見てみよう~
- HEAD:現在作業中のブランチを指す
HEAD 内のブランチを手動で変更すると、 git checkout
と同じ効果がある
- config:ローカルリポジトリの設定情報
主にユーザー情報に注目
config ファイルを手動で変更すると、 git config --local
と同じ効果がある
- refs:heads と tags フォルダを含む
- heads 内の各ブランチには 1 つの commit の hash 値が保存されている
- tags 内の各マイルストーンにも 1 つの commit の hash 値が保存されている
- また、tag の hash 値が commit を指すこともある
git cat-file
:リポジトリオブジェクトの情報を表示-t
:タイプ-p
:内容(cat コマンドを直接使用すると文字化けする可能性があるため、これらのオブジェクトは解析が必要)- 後者には一意の hash 値またはファイル名を指定すればよい
PS:注意深いあなたは、1 つの commit に tree の hash 値が保存されていることに気づくかもしれません。それは最初の関係図とつながっています。tree の内容を確認してみましょう。
- objects:すべてのオブジェクトを保存、tree /blob/commit を含む
- 1)ほとんどのフォルダ📁は hash 値の最初の 2 文字で命名され、その中に 38 文字で命名されたファイルが保存されている
- これらの 40 文字から構成される一意の hash 値がオブジェクトを指す
- 2)tree オブジェクトには blob オブジェクトの情報が保存されており、blob オブジェクトの内容は特定のファイルの内容である(例:css.x)
- tree オブジェクトは別の tree オブジェクトの情報も保存できる
- ファイルの内容が同じであれば、Git の目にはそれは唯一の blob である
- 3)blob オブジェクトの内容は、その指すファイルの内容と一致する
- 一致することは必ずしも保証されない、バージョンによる
- PS:pack フォルダと info フォルダもある
- 前者はパッケージ化された緩いフォルダを保存するために使用され、後者は前者と連携する
10 | commit、tree、blob の 3 つのオブジェクト間の関係#
前のセクションで彼ら 3 人について言及しました。このセクションでは、1 つの commit を具体的に見て理解を深めます。
- これは彼ら 3 者の関係図で、矢印の方向に注目してください。参考:GIT オブジェクトモデル——Git Community Book 日本語版
- 解析
- 1 つの commit の内容は 1 つの tree によって管理され、1 つだけ存在する
- 現在の commit 内のすべてのフォルダとファイルのスナップショットを保存
- 1 つの tree には複数の子 tree と複数の blob が存在することができる
- 1 つの blob にはファイルオブジェクトの具体的な情報が保存されている
- ファイルの内容が同じであれば唯一であり、ファイル名とは完全に無関係
- 1 つの commit の内容は 1 つの tree によって管理され、1 つだけ存在する
- 例
commit👉tree👉blob + tree
PS: lg
は第 7 セクションで設定した git log
のフレンドリー表示版コマンドです
11 | 小練習:tree の数を数える#
新しく作成した Git リポジトリには、1 つの commit しかなく、/doc/readme のみを含む
内にいくつの tree、いくつの blob が含まれているでしょうか?
以下で実験を開始します🧪
## まず新しいGitリポジトリを作成
git init watch_git_object
## リポジトリに入り、docフォルダを作成し、readmeを追加
cd watch_git_object
mkdir doc
echo "hello, world" > doc/readme
## この時点で.git/objects内にファイルタイプのファイルがあるか確認:空
find .git/objects -type f
## docをステージングエリアに追加
git add doc/
## 再度確認:Gitがblobオブジェクトを生成し、readmeの内容を記録した
find .git/objects -type f
- ステージングエリアに追加すると、blob オブジェクトが生成される
- ❗️この時点では commit、tree オブジェクトはまだない。次に commit を行う
## commitを行う
git commit -m'Add readme'
## .git/objects内のファイルを確認:すでに4つある
find .git/objects -type f
## それらのタイプと内容を1つずつ確認する、以下の図のように
git cat-file -t ***
git cat-file -p ***
- 新たに生成されたのは:1 つの commit、2 つの tree
- 彼らの関係は:
- commit👉tree(commit は 1 つの tree に対応)👉tree(doc フォルダ)👉blob(readme ファイル)
12 | HEAD ポインタが分離した場合の注意事項#
detached HEAD
- 発生:HEAD を特定の commit に切り替える(特定のブランチの最新の commit でも)
git checkout <HASH_OF_COMMIT>
、特定のブランチではなく
この時点で detached HEAD の状況が発生し、いくつかの実験的操作を行い、commit を行うことができる
1)これらの commit を保持したくない場合:直接ブランチに切り替え、他の追加操作を行わない
2)これらの commit を保持したい場合:新しいブランチを作成して、ブランチにリンクさせる必要がある
- 次に readme にいくつかの変更を加え、commit を行い、特定のブランチに切り替えると
Git はフレンドリーに提示します:先ほどの commit を保持したい場合は、commit の hash 値を使用して新しいブランチを作成できます
gitk を使用してこの時点でのブランチの状況を確認すると、先ほどの commit の影が見えないことがわかります
フレンドリーな提示に従い、 git branch fix_readme 34976f8
を実行します
前に行った commit はすでに fix_readme ブランチに関連付けられました
- 小結
- 使用シーン:いくつかの実験的な試みを行う
- ⚠️:行った commit を保持したい場合は、特定のブランチにリンクさせる必要がある
13 | HEAD とブランチをさらに理解する#
- 2 つの問題を持って学ぶ:
- 新しいブランチを作成するとき、HEAD はどのように変化するか?(HEAD はどこを指すのか)
- HEAD に関連する使用のコツは何か?(commit を指す、特別なマーク
^
、~
)
以下でそれぞれ探討します:
- 1
HEAD は特定のブランチを指すことも、特定の commit を指すこともできる
git checkout -b <NEW_BRANCH_NAME> <BASE_BRANCH_NAME/HASH_OF_COMMIT>
コマンドを使用して、特定のブランチまたは commit に基づいて新しいブランチを作成し、新しいブランチに切り替える
HEAD は分離したポインタから、fix_new ブランチを指すように変わったことがわかります
HEAD ファイルの情報を再確認します
実際には、HEADは特定のブランチを指し、そのブランチは特定のcommitを指しています
- 2
HEAD が最終的に commit を指すので、commit の hash 値を指すためにも使用できます~
例えば、 git diff <A> <B>
で 2 つの commit を比較する際
上記の 3 つのコマンドは等価です:
git diff 34976f8 a60a3d5
、 git diff HEAD HEAD~
、 git diff HEAD 'HEAD^'
⚠️:
HEAD の ^
と ~
マークは HEAD の祖先 commit を取得でき、彼らの違いは以下の図を参照してください:
このブランチ図の方向は、 git log --graph
で生成された図の方向とは逆で、A が最小であり、マージブランチの状況も考慮されています
参考:HEAD^ と HEAD~ の違いは何ですか?——StackOverflow
PS:zsh では、 ^
は特別な意味を持つため、引用符で囲む必要があります
ここまで学んだことで、Git に対する認識が更新されましたか~次のパートを楽しみにしていますか?!