Telling Git to ignore that basic_abc/
is gone
Caveat This solution only works as long as you don't change branches in your sandbox. Jump near the end of this answer for details. end caveat
You can use git update-index --skip-worktree <file>
to tell Git to ignore changes you've made locally to a file, so that git status
and all other commands will just treat it as unchanged.
I tested, and this also works for a file that was removed. What I did not find is a way to do it for a whole directory, but it's not hard to script on the bash command line.
One file:
git update-index --skip-worktree basic_abc/file1
All the files in basic_abc/
:
git status --porcelain |
grep " D src/main/resources/basic_abc" |
sed "s/^ D //" |
xargs git update-index --skip-worktree
Explanations:
git status
is run with --porcelain
so that you have stable machine-readable output.
- If needed, fix the grep expression so it finds exactly the files you want Git to pretend were not deleted/moved.
- The
sed
command keeps just the filename.
- And
xargs
calls git update-index --skip-worktree
on the results of that pipeline.
Telling Git to ignore that basic/
has appeared
As @EddieDeng said, you can use .git/info/exclude
or .gitignore
to accomplish this, see his answer.
Reverting the --skip-worktree
operation
You didn't ask, but the next logical question, when you've made changes to files in basic_abc
/ basic
, will be how to commit them. I'm mentioning it here because once you've run that --skip-worktree
loop, renaming basic
back to basic_abc
and running git status
or git add
won't work!
Fortunately, that question is already half answered here on SO: How to list files ignored with 'skip-worktree' shows how to list the skipped files, and this command can revert them to not being skipped:
git ls-files -v . |
grep "S src/main/resources/basic_abc" |
sed "s/^S //" |
xargs git update-index --no-skip-worktree
I'm not sure whether the git ls-files -v .
output is as stable as the git status --porcelain
output is, especially since the -t/-v/-f
options are marked semi-deprecated in the manual, but this works at the moment, and I don't know how else to extract that list from Git.
The caveats, or why you should probably not do this
Thanks to @bk2204 for linking to Git FAQ: How do I ignore changes to a tracked file?, where it basically says "don't".
There are problems with update-index
, because it only updates the index, and not some other persistent flag. See @torek's excellent write up on these problems.
The key point I want to highlight here is that as soon as you checkout another branch in your sandbox, you will lose the skip-worktree bits set previously.
Just tested:
# do the --skip-worktree operation above
git checkout some-feature-branch
git checkout master
and now my sandbox has both basic/*
and basic_abc/*
, i.e., two full copies of all those files.
So my final point is, only use this solution if you're not planning to change branches in that sandbox. (And since I change branches all the time, for me, that's the same as "don't use this solution".)
A better solution?
I think the best approach would be to rethink your setup altogether. Instead of modifying your sandbox, you should write some install/deploy script that creates the run-time structure you need outside of your sandbox. Then you have a clear separation and full flexibility: source code is under Git management, deployed code has whatever structure it needs, outside Git management. And you could use symlinks to make that deployed structure lightweight and dynamically updateable, if you wanted to avoid the actual copying.