8

I have some partially generated file foo that I want to be checked in to the repository in an initial state but I don't want any changes to ever be noticed by git.

I thought putting it in the .gitignore file and git add -f foo would be enough, but git status and git diff show the changes in foo as well as git add . adding it. Is there anyway I can do this?

Something like git update-index --assume-unchanged foo but have it automatically for everyone, not just locally.

Hindsight edit: After dealing with similar problems to this for a while, --skip-worktree is preferable to --assume-unchanged, see this question for why. The problem of magically making it apply to everyone still exists.


To be a little more specific it's some file that keeps track of an in-memory database for unit tests that needs the lines CREATE USER SA PASSWORD "" and GRANT DBA TO SA, if I delete this file when it gets regenerated those lines aren't there. It keeps track of the state of the database between runs which is why I don't want its changes to be checked into the repository.

I'm aware this is an odd case and that figuring out how to have it generated with those lines or not have it keep track of the state is probably a better solution.


Steps to reproduce

mkdir test
cd test
git init

echo "hey" > foo
git add .
git commit -m "Add hey to foo"

echo "foo" > .gitignore
git add .
git commit -m "Ignore foo"

echo "bye" > foo
git diff          # will show foo's change
git status        # will show foo has changed
git add .         # will add foo's change to index
Captain Man
  • 6,997
  • 6
  • 48
  • 74
  • @AD7six I specifically mentioned "Something like `git update-index --assume-unchanged foo` but have it automatically for everyone, not just locally." This is not a duplicate. – Captain Man Oct 23 '15 at 15:50
  • @CaptainMan, not sure if this will work but I'd try adding a `post-merge` hook. This will be called after doing a pull from the repository. In that hook, you can just add `git update-index --assume-unchanged foo`. That way, everyone who pulls the commit that contains your file will have this file marked as "assume-unchanged." The only downside is that this will be done every time the user pulls or merges, but the cost is not too expensive so it shouldn't be noticeable. – houtanb Oct 23 '15 at 16:13
  • @HBHB hooks are not automatically installed when you clone a repo. – AD7six Oct 23 '15 at 16:22
  • @AD7six I've updated the title and bolded it so it's more obvious. – Captain Man Oct 23 '15 at 18:32
  • 1
    I'm pretty sure there's no way to do it using only git, sorry. – gbr Oct 23 '15 at 20:38
  • @CaptainMan does the solution I provided work for you? – houtanb Oct 30 '15 at 13:37

3 Answers3

5

This is a bit of a hack, but it's a git-only solution that will work.

  1. Create a new repository that contains only this file and include this new repository in your main repository as a submodule.
  2. Modify .gitmodules in your main repository with the ignore=dirty tag for this new submodule.

So now, when this file is modified, the submodule will be marked as dirty but people using the repository won't see the submodule marked as dirty when checking git status. What's more, they can pull and push at will without sharing the changes made to the file in the submodule.

Community
  • 1
  • 1
houtanb
  • 3,852
  • 20
  • 21
1

You could create a copy of the initial file and place it elsewhere in the repository, so that the copy won't be changed by your tools. Then, in your build script or test script, it can copy it into the proper location (which should probably be ignored by git) and modify at will.

It's not a perfect git-only solution, but running git mv tests/foo test-templates/ && echo "tests/*" >> .gitignore and adding cp test-templates/foo tests/ to your build or test script should be a pretty easy change.

8bittree
  • 1,769
  • 2
  • 18
  • 25
1

This cannot be done using only git.

Captain Man
  • 6,997
  • 6
  • 48
  • 74