shop.oreilly.com
File Management and the Index
- indexは将来の変更を管理する
- commitは2ステップの操作
- indexにステージング
- ステージング内容をcommit
- 本章の内容
- ファイルの追加削除
- 一時的・無関係なファイルの無視
It's All About the Index
- リーナス曰く、「indexを理解せずしてGitの真の力を理解することはできない」
- indexにはファイル内容は格納されない
- indexの状態は
git status
コマンドでいつでも問い合わせられる
- ステージング時は
git diff
が便利
git diff
git diff --cached
git add
するたびに前者は減って、後者が増える
File Classifications in Git
- 3種類
- Tracked
- Gitリポジトリで追跡中のファイル
git add
で追加
- Ignored
- Untracked
git init
Initialized empty Git repository in /home/wand/learn/git/sandbox_ch5/.git/
git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
- 作りたてのリポジトリは空
- tracked, ignored, untrackedいずれもなし
echo "New data" > data
git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
data
nothing added to commit but untracked files present (use "git add" to track)
~/learn/git/sandbox_ch5 $
- ファイルを生成すると、untrackedなファイルが1つレポートされる
- 一時的なファイルを無視したい場合は
.gitignore
ファイルを記述する
touch main.o
git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
data
main.o
nothing added to commit but untracked files present (use "git add" to track)
echo main.o > .gitignore
git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
data
nothing added to commit but untracked files present (use "git add" to track)
.gitignore
は特別な意味を持つファイルだが、それ自体は普通のファイルと同じように扱われる
Using git add
git add
はファイルをステージングする
- Gitのファイルの分類的には、untrackedなファイルをtrackedにする
- ディレクトリに対して行うと、それ以下全ファイル・全サブディレクトリが再帰的にステージングされる
git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
data
nothing added to commit but untracked files present (use "git add" to track)
git add data .gitignore
git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitignore
new file: data
git ls-files --stage
でステージング済のファイルのSHA1値を得られる
git ls-files --stage
100644 0487f44090ad950f61955271cf0a2d6c6a83ad9a 0 .gitignore
100644 534469f67ae5ce72a7a274faf30dee3c2ea1746d 0 data
git hash-object
でSHA1値を算出可能
New data
+ And some more data now
git hash-object data
e476983f39f6e4f453f0fe4a859410f63b58b500
- 変更をステージングし、ファイルのSHA1値がこの値になることを確認
git add data
git ls-files --stage
100644 0487f44090ad950f61955271cf0a2d6c6a83ad9a 0 .gitignore
100644 e476983f39f6e4f453f0fe4a859410f63b58b500 0 data
- 「
data
ファイルがindexにある」というのは厳密には誤り
- ファイル内容はblobはオブジェクトストアに格納される
find .git/objects
.git/objects
.git/objects/53
.git/objects/53/4469f67ae5ce72a7a274faf30dee3c2ea1746d
.git/objects/pack
.git/objects/04
.git/objects/04/87f44090ad950f61955271cf0a2d6c6a83ad9a
+ .git/objects/e4
+ .git/objects/e4/76983f39f6e4f453f0fe4a859410f63b58b500
.git/objects/info
Some Notes on Using git commit
Using git commit --all (git commit -A)
- 追跡中のファイルの未ステージの変更を全てコミットするショートハンド
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: ready
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: notyet
Untracked files:
(use "git add <file>..." to include in what will be committed)
subdir/
git commit
だとreadyの変更分のみがコミットされる
git comit -A
git commit --all
-m
オプションを指定していないので、エディタが立ち上がる:
git commit --all sample
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Changes to be committed:
# modified: notyet
# modified: ready
#
# Untracked files:
# subdir/
#
- ステージングしていないnotyetもコミットされる
- untrackedなsubdir以下はコミットされない
[master 1f8fb13] git commit --all sample
2 files changed, 2 insertions(+)
Writing Commit Log Messages
- コミットメッセージは必須
-m
オプションを省略するとエディタが立ち上がる
.git/COMMIT_EDITMSG
ファイル
- 空のまま保存するとcommitをキャンセル
Using git rm
echo "Random stuff" > oops
git rm oops
fatal: pathspec 'oops' did not match any files
git add oops
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitignore
new file: data
new file: oops
git ls-files --stage
100644 0487f44090ad950f61955271cf0a2d6c6a83ad9a 0 .gitignore
100644 e476983f39f6e4f453f0fe4a859410f63b58b500 0 data
100644 fcd87b055f261557434fa9956e6ce29433a5cd1c 0 oops
git rm --cached oops
rm 'oops'
- ステージング一覧からoopsが消えていることを確認
git ls-files --stage
100644 0487f44090ad950f61955271cf0a2d6c6a83ad9a 0 .gitignore
100644 e476983f39f6e4f453f0fe4a859410f63b58b500 0 data
find .git/objects
.git/objects
.git/objects/53
.git/objects/53/4469f67ae5ce72a7a274faf30dee3c2ea1746d
.git/objects/pack
.git/objects/04
.git/objects/04/87f44090ad950f61955271cf0a2d6c6a83ad9a
.git/objects/e4
.git/objects/e4/76983f39f6e4f453f0fe4a859410f63b58b500
.git/objects/info
.git/objects/fc
.git/objects/fc/d87b055f261557434fa9956e6ce29433a5cd1c
|
作業ディレクトリ |
index |
rm |
消す |
|
git rm --cached |
|
消す |
git rm |
消す |
消す |
git rm --cached
は作業ディレクトリのファイルは残す
- Gitの追跡からは外れるため、「最新」である保証はないことに注意
git rm
は作業ディレクトリのファイルも削除する
git commit -m "Add some files"
git rm data
rm 'data'
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: data
...
- 対象ファイルに変更があると、
git rm
は失敗する
git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: data
no changes added to commit (use "git add" and/or "git commit -a")
git rm data
error: the following file has local modifications:
data
(use --cached to keep the file, or -f to force removal)
git rm -f data
rm 'data'
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: data
rm
は作業用ディレクトリのファイルだけ削除する
- 誤って
rm
した場合で、復元するにはcheckoutする
git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: data
no changes added to commit (use "git add" and/or "git commit -a")
git checkout HEAD -- data
git status
On branch master
nothing to commit, working tree clean
Using git mv
mv
+ git rm
+ git add
のショートハンド
git mv data mydata
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: data -> mydata
- オプションなしの
git log
ではリネーム前の履歴は取得できない
git commit -m "Moved data to mydata"
git log mydata
commit d00968b0c16f9f6b5e200aabd50f18baf76693c4 (HEAD -> master)
Author: Daiki Horiyama <xxxxxxxxx@gmail.com>
Date: Sun Oct 27 01:40:33 2019 +0900
Moved data to mydata
--follow
オプションでリネーム前の履歴も追える
git log --follow mydata
commit d00968b0c16f9f6b5e200aabd50f18baf76693c4 (HEAD -> master)
Author: Daiki Horiyama <xxxxxxxxx@gmail.com>
Date: Sun Oct 27 01:40:33 2019 +0900
Moved data to mydata
commit 37575a6a417a821c3053bbbf42a7955aa21d0bd2
Author: Daiki Horiyama <xxxxxxxxx@gmail.com>
Date: Sun Oct 27 01:27:16 2019 +0900
Add some files
A Note on Tracking Renames
Problems with Tracking a Rename
- リネームはわりと哲学的な問題
- 似ているだけの別のファイルなのか
- 複数名が別々のリネームを実施した場合、マージはどうするか
The .gitignore File
!
で否定
- 例外なので普通の指定よりも強い
- 除外したものも含める
*.o
はignoreするが、vendor/driver.o
だけは管理したいようなケース
- glob
.gitignore
はリポジトリ管理下の普通のファイルなので、clone先に伝播する
- 自分のリポジトリ固有の設定は
.git/info/exclude
に記述
A Detailed View of Git's Object Model and Files
- 下記3つが一致している状態がclean
- 作業ディレクトリに変更を加えると
- 作業ディレクトリと他2つとがout of syncになる
- ステージングすると
- 作業ディレクトリとindexとは一致
- indexと、HEADが指しているtreeとがout of sync
- commitすると
- indexがtreeとしてオブジェクトストアに永続化される
- HEADは新しいtreeを指す
- 作業ディレクトリ、index、オブジェクトストアの3つは一致する
英語
- safekeeping
- amass
- prospective
- culminate
- corpus
- porcelain
- arcane
- preclude
- mandate
- Darn!
- alleviate
- baffle
- elude
- engender
- perennial
- fodder
- dissension
- parley