勉強日記

チラ裏

Version Control with Git ch5 File Management and the Index

shop.oreilly.com


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
    • 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-objectSHA1値を算出可能
  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. 作業ディレクトリに変更を加えると
  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
    • 討議