Git

Gitでソースを消す方法

目的

  • Gitの履歴の保持方法を知る
  • ソース(の差分)を消失する方法を知る
  • 意図せず消さないための注意点を考える

Git

  • 分散型のバージョン管理システム
  • 作者: Linus Torvalds
  • メンテナ: 濱野純
  • 元々 Linux kernel のソース管理の為に作られた

履歴

ImmutableなコミットのDAG(Directed ascyclic graph, 有向非巡回グラフ) で履歴を管理

dag.png


コミット

各々のコミットは、ソースツリーを参照している(ImmutableなTree, Blobで構成される)

commit.png


リポジトリの構造

  • Immutableなオブジェクトが格納されてる
    • 操作によりオブジェクトが追加される
    • 記録した情報は基本消えない
  • オブジェクト間の参照
    • コミットは親コミットを参照
    • コミットはルートツリーを参照
    • Treeは子のTree,Blobたちを参照
  • ブランチ、タグはコミットへのポインタ

基本的な操作

git add ${FILES} && git commit

  • Tree, Blob たちを記録
  • ルートツリーと親コミットを参照する Commit を記録

過去に記録したものには手を加えない


いろいろな操作

  • 過去のある時点のソースコードを取得する
    • git checkout ${COMMIT_SHA1}
  • ファイルを消してコミット
    • git rm ${FILE} && git commit
  • 過去の変更を打ち消すコミットを生成する
    • git revert ${COMMIT_SHA1}

これらも安全な操作(リポジトリから何も消さない)


安全側に倒した設計

ソース(の差分)が消える操作を(オプションもしくは事前条件で)抑止

例: 変更を加えているファイルが checkout で更新されそう

$ git checkout work
error: Your local changes to the following files would be overwritten by checkout:
    readme.txt
Please commit your changes or stash them before you switch branches.
Aborting

何も消えないの?

  • .git/ (リポジトリ)を壊さない範囲で
  • ミスで消えないよう配慮はされている
  • これから消し方を説明します!
    • そもそも記録してない情報は消える
    • 記録したものも消そうと思えば消せる

記録してない情報

  • git add してないファイル
  • git add してない差分

これらはリポジトリに入っていないので消せる


管理してないファイルを消す

$ git clean
fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given; refusing to clean

デフォルト(clean.requireForce=true)では引数なしは弾かれる

  • -n で何が消えるか確認
  • -f で実際に消す
  • -d とか -x もよく使う
  • ビルドで生成されたファイルを消すときなど

ファイルの変更を消す

$ git checkout ${PATH}
  • 指定したファイルは index と同じ内容になる
  • HEAD にするなら git checkout HEAD ${PATH}
  • 変更しかけた1ファイルを元に戻す

ファイルたちの変更を消す

$ git reset --hard
  • HEAD と同じ内容になる
  • 変更しかけたファイルたち(と index)を元に戻す

ブランチの削除

$ git branch -d work
error: The branch 'work' is not fully merged.
If you are sure you want to delete it, run 'git branch -D work'.
  • upstream もしくは HEAD にマージされてなければ一旦弾いてくれる
  • どうすれば迂回できるかはメッセージに出てる

それでも先に進む?


ブランチの削除

-D または -d -f でブランチを削除

  • 消えるのはブランチだけ
  • コミットはその時点では消えない
  • git gc (GC = garbage collection)
  • どこからも参照されていないコミットは gc で消える
    • 参照されていれば消えない

参照されていれば消えない

  • いろいろやり直せることも思い出す
  • ローカルブランチ気軽に使おう
  • 例えば以下の手順でバックアップ作れる
$ git add ${FILES}
$ git commit
$ git branch backup
$ git reset HEAD~1

リモートの話

$ git push ${REMOTE} ${BRANCH}
  • リモートに履歴をバックアップできる
  • ローカルで消えても戻せる可能性
  • 手元の .git/ が壊れた場合にも助かるかも

まとめ

  • git を使ったソースの消し方を見た
  • 基本的には履歴を安全に保持してくれる
  • 消える可能性があるのは
    • コミットしてないもの
    • タグやブランチから参照されてないもの
  • 知った上で使えば大丈夫
    • 必要に応じてバックアップするとよいかも