Git

gitでファイルの一部だけコミットから無視する

More than 3 years have passed since last update.


やりたい事

ファイルやディレクトリは.gitignoreに指定すれば良いが、

ファイルの一部分(特定の行など)だけ無視するにはどうすれば良いのか?

例えば認証が必要なProxy環境でgitを使用する場合は以下のプロキシ設定が必要だが、

パスワードを含む部分だけはリポジトリにはコミットしたくない。


.gitconfig

[core]

quotepath = false
autoCRLF = false
:
[http]
proxy = http://username:password@proxy.sample.jp:8080
[https]
proxy = http://username:password@proxy.sample.jp:8080

素直にプロキシ設定を外部ファイル(例:.gitconfig.local)に分けるべきだがそれはできない状況だとして。


.gitconfig

[include]

path = .gitconfig.local


対応方法

下記リンクのようにキーワード展開などで利用されるfilterを利用すれば実現できる。

How to tell git to ignore individual lines, i.e. gitignore for specific lines of code [duplicate]

ただしリンク先の方法は本来やりたい"無視"ではなく"除外"する方法なので、

ここでの方法とはちょっと異なるためその点は注意。

(ローカルのみでデバッグ用コードを挿入したいような場合はリンク先の方法が有効)


1. 属性の設定

まず以下の内容で<project root>/.gitattributesを作成。


.gitattributes

.gitconfig filter=ignoreproxy



  • ファイル名が.gitconfigならignoreproxyという名前のフィルタを適用せよという意味


  • *.rb filter=ignoreproxyなどの指定も可能


  • <project root>/.git/info/attributesに記述しても良し(その場合はattributesはコミットされない)


2. フィルタの定義

次に~/.gitconfigignoreproxyというフィルタを追加する。


.gitconfig

[filter "ignoreproxy"]

smudge = cat
clean = sed '/^\\ *proxy/s!http://[^@]*!http://username:password!'



  • smudgeはcheckoutする時、cleanはステージする時に適用される(参考)


  • smudgeでは何もしないのでcatコマンドでそのまま出力しているだけ


  • cleanでは強制的に変更後のusernamepasswordを元に戻している

  • グローバルに適用したくなければ<project root>/.git/configに書いても良し


確認

この状態でusernamepasswordを変更しても、この部分だけはちゃんとコミットされない。


.gitconfig

[core]

quotepath = false
autoCRLF = true
:
[http]
proxy = http://taro:123abc@proxy.sample.jp:8080
[https]
proxy = http://taro:123abc@proxy.sample.jp:8080

確認のためgit diffとしても

 [core]

quotepath = false
- autoCRLF = false
+ autoCRLF = true
:
[http]
proxy = http://username:password@proxy.sample.jp:8080

プロキシ設定部分に関しては差分とならない。