git update-index --skip-worktree
というコマンドをご存知でしょうか?
これはGitで既に管理されているファイルをローカルで無視する方法です。
例えば、『設定ファイルなど既にGitで管理されているファイルをローカルで少しだけ修正したい(だけど、修正はあくまでローカルで利用するときだけ)』などの場合に便利なコマンドです。
詳しくは以下の記事を参考にしてください。
Gitで既に管理されているファイルをローカルで無視する方法
しかし、この無視していたファイルが原因でリポジトリの修正を取り込めない場合があります。
今回はその対処方法について説明します。
今回の例
以下のような前提をもとに説明をしていきます。
config/application.rb
というファイルをローカルで利用する際に少しだけ修正していたgit update-index --skip-worktree config/application.rb
でGitの管理から除外するようにしたgit pull origin master
でorigin master
の修正を取り込もうとしているorigin master
ではconfig/application.rb
も修正されている
現状確認
まず普通にpull
しようとすると以下のようになります。
ローカルでもorigin master
でもconfig/application.rb
を修正しているのでうまくpull
できません。
$ git pull origin master
From https://github.com/xxxxx/test
* branch master -> FETCH_HEAD
Updating aaaaaaaa
error: Your local changes to the following files would be overwritten by merge:
config/application.rb
Please commit your changes or stash them before you merge.
Aborting
ステータスを確認すると以下のようになります。
Gitの管理から除外しているのでconfig/application.rb
は変更内容として現れません。
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
Gitの管理外のファイル一覧をチェックすると確かに除外されていることがわかります。(Sで表示されているファイルはskip-worktree
の状態であることを示す)
$ git ls-files -v | grep ^S
S config/application.rb
解決方法
まずは--no-skip-worktree
でGitで管理するように戻します。
$ git update-index --no-skip-worktree config/application.rb
ステータスを確認すると以下のようになっています。
修正内容がGitで管理されていることがわかります。
$ git status
On branch master
Your branch is up-to-date with 'origin/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: config/application.rb
no changes added to commit (use "git add" and/or "git commit -a"
一旦stash
で変更を一時退避させます。
$ git stash
変更を退避した後、pullします。
$ git pull origin master
masterの内容をマージした後、さきほどstash
で退避させた内容をpop
で元に戻します。
$ git stash pop
改めて、Gitの管理下から除外するようにします。
$ git update-index --skip-worktree config/application.rb
参考
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!