3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Git管理下に置くが変更は無視する、はできない

Last updated at Posted at 2021-02-08

概要

設定ファイルに含まれるパスワードなどの機密情報を伏せて Git の管理下に置き、各自がローカルで書き入れた部分の変更を無視させたいことがあるが、Git にはそのための機能はない

どうすべきか

例えば以下のような方法で代替する。

機密情報を含むファイルを config.ini とすると、

  1. .gitignoreconfig.ini を追加する
  • 機密情報を伏せて config.ini.tmpl のような別名で保存する
  • config.ini がすでにコミットされている場合、git rm --cached config.ini で削除する
  • 変更をコミットする

README などに、リポジトリをクローンしたら config.ini.tmplconfig.ini にコピーしたうえで機密情報を書き入れるよう指示しておくと良い。

うまくいかない方法

検索すると以下の方法がよく挙げられているが、いずれも有効なのはローカルにおいてのみである。

.gitignore に追加して git rm --cached する

ファイルが Git 管理下にある限り、変更は追跡される。
Git による管理から外すが、ローカルにあるファイルは削除したくない場合には有効。

検証
`config.ini` をコミットしたうえで、`.gitignore` に追加してみる。
$ echo PUT_SECRET_HERE > config.ini
$ git add . && git commit -m "機密情報を含む設定ファイル"
[master (root-commit) 02a5408] 機密情報を含む設定ファイル
 1 file changed, 1 insertion(+)
 create mode 100644 config.ini
$ echo config.ini > .gitignore
$ git add . && git commit -m "gitinogreに追加"
[master f30c427] gitinogreに追加
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore
$ echo my_secret > config.ini
$ git diff
diff --git a/config.ini b/config.ini
index 68c539e..0506d9e 100644
--- a/config.ini
+++ b/config.ini
@@ -1 +1 @@
-PUT_SECRET_HERE
+my_secret

変更が追跡されていることが分かる

この変更を元に戻したうえで、git rm --cached してみる。

$ git checkout config.ini
Updated 1 path from the index
$ git rm --cached config.ini
rm 'config.ini'
$ git commit -a -m "いったん追跡から外す" 
[master f09e4fc] いったん追跡から外す
 1 file changed, 1 deletion(-)
 delete mode 100644 config.ini

すると config.ini は Git の管理化から外れた。

さて、.gitignore に追加した後であれば、変更は無視されるだろうか?
config.ini を再度 Git 管理下に入れてみよう。config.ini.gitignore により無視されておりgit add ではステージングできないため、 -f オプションをつける必要がある。

$ git add -f config.ini
$ git commit -m "再度追跡させる"
[master 2fc25de] 再度追跡させる
 1 file changed, 1 insertion(+)
 create mode 100644 config.ini
$ echo new_secret > config.ini        
$ git diff
diff --git a/config.ini b/config.ini
index 68c539e..ff0ae85 100644
--- a/config.ini
+++ b/config.ini
@@ -1 +1 @@
-PUT_SECRET_HERE
+new_secret

変更の追跡が再開していることが分かる。

git update-index --skip-worktree する

ローカルでは追跡されなくなるが、 upstream はこの設定を保持しない。
つまり、共有リポジトリでこれを運用するなら、すべてのコミッターがこの設定を行う必要がある
いずれ何も知らない新人によって機密情報は公開されてしまうだろう。

検証
`git update-index --skip-worktree` により、ローカルでは変更が追跡されなくなることを確認する。
$ cat config.ini
PUT_SECRET_HERE
$ git update-index --skip-worktree config.ini
$ echo my_secret > config.ini
$ git diff
$ cat config.ini
my_secret

config.ini の変更が追跡されていないことが分かる。

この状態では変更がなくコミットできないので、適当なファイルを追加してプッシュしてみよう。

$ touch something
$ git add . && git commit -m "skip-worktreeを実行"  
[master 377ba4a] skip-worktreeを実行
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 something
$ git push 

これを別のディレクトリにクローンして、config.ini を変更してみる。

$ git clone https://example.com/repo.git new_repo
$ Cloning into 'new_repo'...
$ cd new_repo 
$ echo new_secret > config.ini
$ git diff
diff --git a/config.ini b/config.ini
index 68c539e..ff0ae85 100644
--- a/config.ini
+++ b/config.ini
@@ -1 +1 @@
-PUT_SECRET_HERE
+new_secret

やはり config.ini の変更は追跡されていることが分かる。

公式ドキュメントでも、特定ファイルの変更を無視する目的に update-index --skip-worktree ないし --assume-unchanged を使用できないことが注記されている。

Users often try to use the assume-unchanged and skip-worktree bits to tell Git to ignore changes to files that are tracked. This does not work as expected, since Git may still check working tree files against the index when performing certain operations.

Git - git-update-index Documentation

参考

How to stop tracking and ignore changes to a file in Git? - Stack Overflow

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?