1

This question is essentially the opposite of this one.

There are certain files that exist for reasons on the team's remote. They are not frequently changed, but that doesn't matter: having them in my local repository causes issues.

I can very easily delete these files but it means I need to be very careful with how and what I commit. Switching branches when these files have changed can be a pain if the files have changed between those branches.

How can I delete these files locally, keep them on the remote, with the illusion of a clean working tree? I'd like to be able to switch branches and do work (stage/unstage/discard) without the presence of these said files. If they change on one branch and I switch to that branch, the files should remain deleted.

My best workaround so far:

  1. Delete all the said files after branching (for all of my dev branches).
  2. Commit.
  3. Do work as usual.
  4. Rebase + drop the first commit before opening a pull request.

Steps 1 and 2 can be done with a git hook, but I haven't bothered setting that up.

Thanks!


Also a note on the XY problem ("why would you want to do this"): the "correct" solution is to open a support ticket with the team that built my IDE which I'm already doing. A workaround in the meantime might also help answer this question in case it applies elsewhere.

I find two reasons for asking this:

  1. My colleague wants local .pyi files present on the trunk branch for a Python 3.6 project. PyCharm uses these .pyi files as a source of truth, e.g.: if you add a function to a file, you must add a stub to the associated .pyi file or PyCharm won't be able to find or suggest the new function.
  2. GitHub Actions require you to commit your entire node_modules directory as well as an entrypoint .js file when publishing a ref as an Action version. This is problematic with multiple branches of a TypeScript GitHub Action where the developer usually runs tsc before committing since the compiled .js in the working tree will always conflict when switching branches. Stashing is the correct way to handle this but it can be inconvenient at times.
Thomas
  • 701
  • 2
  • 8
  • 23
  • If you are telling us that these files should not even be present, then I'd say the problem is with the person(s) who committed them in the first place. – Tim Biegeleisen Feb 25 '20 at 04:39
  • I don't disagree and I've discussed it with my colleague but unfortunately I find myself still searching for a workaround. – Thomas Feb 25 '20 at 04:46
  • OK -- is there some version of these files, according to you, in which they would not be causing any problems? – Tim Biegeleisen Feb 25 '20 at 04:48
  • The existence of the files themselves unfortunately cause the problem. I've outlined the two reasons for asking this question in the original question. – Thomas Feb 25 '20 at 04:51

2 Answers2

2

You can try:

git update-index --assume-unchanged -- unWantedFile
rm unWantedFile
# work
# ...
# later on
git update-index --no-assume-unchanged -- unWantedFile
git restore unWantedFile

That should be enough to work in a working tree without that file, while telling Git the file is still there.

It works too with git update-index --skip-worktree -- unWantedFile.
I have written about the difference between the two here.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks! This worked a treat. As I switch branches to other branches that do not change these files, things work exactly as I'd like. I never need to use `git update-index --no-assume-unchanged -- unWantedFile` for now, just the first command. – Thomas Feb 25 '20 at 05:44
  • @Thomas It should work, but read the caveat at the end of https://stackoverflow.com/a/23806990/6309 – VonC Feb 25 '20 at 05:45
  • `rm restore`? `git checkout/restore`, I suppose? – phd May 04 '20 at 21:58
  • @phd Yes, `git restore`. Thank you.. I have edited the answer accordingly. – VonC May 05 '20 at 00:13
2

The sparse-checkout should work.

Enable sparse-checkout:

git config core.sparsecheckout true

Create the config file .git/info/sparse-checkout and input the patterns:

*
!path/to/file1/you/want/to/delete
!path/to/file2/you/want/to/delete
!path/to/file3/you/want/to/delete

The patterns mean "to checkout everything(*) except(!) the rest paths".

Make it work:

git checkout

This way, these files are not checked out and everything is the same to you as long as you don't need to modify or checkout these files. In case you need these files to be checked out, remove or comment the file paths in .git/info/sparse-checkout and leave only *, and run git checkout again to checkout the hidden files.

ElpieKay
  • 27,194
  • 6
  • 32
  • 53