Tsubatoの発信記録

主に機械学習やデータサイエンス関連で学んだことを書いています。

gitで個人的に追加/変更したファイルを管理外にしたい

gitの管理対象外にしたい場合は.gitignoreを使いますが、個人的に追加/変更したファイルを共有の.gitignoreに追加するのは憚れます。そうした場合に使えるコマンドを調べました。

個人的に追加したファイルを無視したい

  • ユースケース: 自分がよく使うコマンドをシェルスクリプトで残したい時
  • 方法: ローカル作業環境の.git/info/excludeに管理対象外にしたいファイルを追加する。

既にgitで管理されているファイルへの個人的な変更を無視したい

  • ユースケース: 設定用のファイルがgit管理されている時。
  • 方法: git update-index --skip-worktree [ファイル名]
    • 管理対象に戻したい場合はgit update-index --no-skip-worktree [ファイル名]
    • この設定が適用されているかを知るにはgit ls-files -vを使う。管理下のファイルにはH、skipされているファイルはSが付与される。

補足

変更を無視する方法として、git update-index --assume-unchangedもあります。 参考にしたページによると以下のような違いがあるらしいです。

  • assume-unchanged : そのファイルが作業ツリー上で変更されているときでも、git はその変更を無視して変更されていないとみなします。
  • skip-worktree : そのファイルが作業ツリー上で変更されているときには、git はその変更を保ちます。

上で挙げたユースケースの場合、リモートリポジトリの変更をpullした時は以下のような要求があります。

  • ローカルの変更を勝手に上書きされたくない(個人のconfigが消えると戻すのが面倒)
  • リモートリポジトリの同ファイルが変更されたことに気づきたい(自分だけ古いconfig使ってると困る)

一見するとどちらのコマンドも両方の要求を満たせないように思えたので、実際に試してみました。

実験

手順:

  1. git管理されているファイルをローカルで変更し、assume-unchangedあるいはskip-worktreeで管理外にする。
  2. リモートリポジトリでそのファイルを変更。
  3. git pullでリモートの変更をローカルに取り込もうとする。

結果: どちらの方法でも以下のようなエラーが出るので勝手に上書きされない。

error: Your local changes to the following files would be overwritten by merge:
        config
Please commit your changes or stash them before you merge.

ということでどちらのコマンドでもやりたいことは満たせていそうなので、取り敢えず多くのページで推奨されているskip-worktreeを使って使用感を見ていこうと思います。

参考