7

I have a few files in git (namely configure files), that I need to be in the git repo, but I don't want them to ever update (for some reason, running them, and make, changes the configure file).

So is there any way I can tell git to ignore any CHANGES to the file, but to keep the original file still in the repo? Currently the only way I've found out to do something like this is to add the file to the .gitignore file, and the git add the file to the project directly (using -f to override). Is there any better way?

Leif Andersen
  • 21,580
  • 20
  • 67
  • 100

2 Answers2

9

You could use git update-index --assume-unchanged on the file.

--assume-unchanged option can be used as a coarse file-level mechanism to ignore uncommitted changes in tracked files (akin to what .gitignore does for untracked files). You should remember that an explicit git add operation will still cause the file to be refreshed from the working tree. Git will fail (gracefully) in case it needs to modify this file in the index e.g. when merging in a commit; thus, in case the assumed-untracked file is changed upstream, you will need to handle the situation manually.

Alan Haggai Alavi
  • 72,802
  • 19
  • 102
  • 127
  • That seem to have worked for me. Although it seems like this will not be sent to the larger repo when I do a git push. Is this correct? – Leif Andersen Apr 14 '11 at 13:15
  • _[Leif Andersen](http://stackoverflow.com/users/288439/leif-andersen)_: You are right. – Alan Haggai Alavi Apr 14 '11 at 13:20
  • This is dangerous as your local file may in some cases be overwritten/updated with data from origin. See discussion at https://stackoverflow.com/questions/13630849/git-difference-between-assume-unchanged-and-skip-worktree – Arni J Apr 04 '18 at 10:05
5

I wouldn't manage those files with git at all. I'd put them in your .gitignore so git would ignore them, and put template files (such as foo.template for a file named foo, or maybe template/foo) into git. Then when you clone the repo, you can copy them out, and modify them, and git won't do anything with the copies, while still managing the templates. If you have several such files, you can supply a script or make rule or something of the sort to populate all of your config files from their templates, to make it easier to get set up.

A better design would be to separate project config from local config, or have project level defaults that can be overridden in a separate local file. The project level files get committed, the local files get ignored, and they are both used. Perhaps some config settings only make sense for the project and some only make sense locally, in which case you just pull the appropriate setting from the appropriate file; or you could use the project setting as defaults, and let the local config override the defaults. This way, you can update the project settings, which are shared, for everyone at once, while not interfering with people's local settings. Of course, this depends on having control of the settings format; if you're using a third-party tool that takes its settings in a particular format, all mixed into one file, you'll probably have to use the template approach.

Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
  • Committing `.sample` files is what we typically do too; but be careful about people using outdated copies. We've also cheated by committing the file to the repo and **then** adding it to `.gitignore` -- though I would only do this in a pinch. – Uriah Carpenter Apr 14 '11 at 04:42
  • @Uriah Yeah, you do have to be careful about outdated copies, but you need to be careful about that in any system in which you have config files that are supposed to be locally modified but are complex enough to need version controlled templates. I'll add a note about a better design to my answer as well, though it's one that may not be available depending on whether they control the config file format. – Brian Campbell Apr 14 '11 at 05:03