Version Control with Git ch5 File Management and the Index

Git勉強メモ

出典: 


File Management and the Index

  • indexは将来の変更を管理する

    • commitは2ステップの操作

      • indexにステージング
      • ステージング内容をcommit
  • 本章の内容

    • ファイルの追加削除
    • 一時的・無関係なファイルの無視

It’s All About the Index

  • リーナス曰く、「indexを理解せずしてGitの真の力を理解することはできない」
  • indexにはファイル内容は格納されない

    • commitしたいものを参照しているだけ
  • indexの状態はgit statusコマンドでいつでも問い合わせられる

    • git ls-filesで内部状態も見られる
  • ステージング時はgit diffが便利

    • git diff

      • 作業ディレクトリに残っている差分
    • git diff --cached

      • ステージング済の変更差分

        • commit予定
    • git addするたびに前者は減って、後者が増える

File Classifications in Git

  • 3種類

    • Tracked

      • Gitリポジトリで追跡中のファイル
      • git addで追加
    • Ignored

      • .gitignoreで無視してるやつ
    • Untracked

      • 前者2つに該当しない残り全てのファイル
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は特別な意味を持つファイルだが、それ自体は普通のファイルと同じように扱われる

    • addしていないのでuntracked

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)
  • まだuntracked
  • git addする
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

  • git addの逆
echo "Random stuff" > oops
git rm oops
  • trackedのものしかgit rmできない
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で未ステージに戻す
git rm --cached oops
rm 'oops'
  • ステージング一覧からoopsが消えていることを確認
git ls-files --stage
100644 0487f44090ad950f61955271cf0a2d6c6a83ad9a 0	.gitignore
100644 e476983f39f6e4f453f0fe4a859410f63b58b500 0	data
  • オブジェクトストア中の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
.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)
  • -f(force)で強制削除できる
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は作業用ディレクトリのファイルだけ削除する

    • まだtracked
  • 誤ってrmした場合で、復元するにはcheckoutする

    • 【補】最近はrestoreになったはず
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ではリネームを特別扱いしない
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

  • SVNではリネームを特別扱いする

    • svn mvでそれと教えてあげる必要がある

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

  1. 下記3つが一致している状態がclean

    • 作業ディレクトリ
    • index
    • オブジェクトストア

      • = HEADが指しているtree
  2. 作業ディレクトリに変更を加えると

    • 作業ディレクトリと他2つとがout of syncになる
  3. ステージングすると

    • 作業ディレクトリとindexとは一致
    • indexと、HEADが指しているtreeとがout of sync
  4. 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

    • 討議