383
votes

I have several files in a CodeIgniter site that I will want to have in the repo but not track any changes on.

For example, I deploy a new installation of this framework to a new client, I want the following files to be downloaded (they have default values CHANGEME) and I just have to make changes specific to this client (database credentials, email address info, custom CSS).

// the production config files i want the files but they need to be updated to specific client needs
application/config/production/config.php
application/config/production/database.php
application/config/production/tank_auth.php
// index page, defines the environment (production|development)
/index.php
// all of the css/js cache (keep the folder but not the contents)
/assets/cache/*
// production user based styling (color, fonts etc) needs to be updated specific to client needs
/assets/frontend/css/user/frontend-user.css

Currently if I run

git clone git@github.com:user123/myRepo.git httpdocs

and then edit the files above, all is great. Until I release a hotfix or patch and run git pull. All of my changes are then overwritten.

6
You could just ignore client credential/configuration files and have the program build default files if they are missing when the repo is installed? - MatthewG

6 Answers

711
votes

git has a different solution to do this. First change the file you do not want to be tracked and use the following command:

git update-index --assume-unchanged FILE_NAME

and if you want to track the changes again use this command:

git update-index --no-assume-unchanged FILE_NAME

git-update-index documentation

123
votes

To pull an answer out of the comments of another answer:

$ git update-index --skip-worktree FILENAME

Appears to be a better option than --assume-unchanged

More can be read about this here: Git - Difference Between 'assume-unchanged' and 'skip-worktree'

63
votes

For my Code Igniter projects, I keep database.php.example and config.php.example in the repo.

Then I add config.php and applications/config/database.php to the .gitignore file.

So, finally, when I deploy, I can copy the .example files (to config.php and database.php), customize them, and they won't get tracked by GIT.

9
votes

The recommended way, as of git version 2.25.1, is to track templates of the files in the repository, copying them into new files and modifying them locally (ignoring the new filename in .gitignore) (from here):

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. In general, Git does not provide a way to ignore changes to tracked files, so alternate solutions are recommended.

For example, if the file you want to change is some sort of config file, the repository can include a sample config file that can then be copied into the ignored name and modified. The repository can even include a script to treat the sample file as a template, modifying and copying it automatically.

2
votes

I would put them in your .gitignore file and just copy them manually as needed.

So the skeleton filename would be in git, the ignore filenames would not be in git (but would be in .gitignore). That way, when the manual step to copy them to 'actual' from 'template' (better name than skeleton perhaps) is done they are immediately ignored.

2
votes

The answers given are solving the problem just partially, but introducing even more problems.

I needed to preserve the"Web.Local.config" file. The only solution that worked for me was to:

1. Exclude the file from the project

2. Create a separate copy of the file as Web.LocalTemplate.config

Now that "Web.LocalTemplate.config" is tracked by Git, all developers can use it as a starting point. However, the "Web.Local.config", not being part of the project will be automatically ignored.