This post is a quick note because I keep forgetting the syntax and always have to google it again, which wastes time. The eternal problem: you edit package.json or a config file locally just to get things running, but git status or your IDE’s changed-files panel always lists those files, which is really annoying to look at, and sometimes one careless git add . and you’re toast.
1. File already pushed to the Server (Tracked) but you want to edit it locally
The problem: .gitignore does not work on a file that is already tracked. So no matter how hard you try to add it to .gitignore, nothing happens.
Solution (use Skip Worktree):
This command tells Git: “I’m editing this file, mind your own business, stop reporting changes, keep the remote version for me.”
Hide the file (ignore changes):
1 | git update-index --skip-worktree <path-to-file> |
Show the file again (to commit it):
1 | git update-index --no-skip-worktree <path-to-file> |
Check which files are currently hidden:
1 | git ls-files -v | grep ^S |
Note:
- Use
--skip-worktree(for config/app settings), not--assume-unchanged(that one is for performance/SDK). skip-worktreeis safer when you pull new code, it won’t casually override your local changes.
2. File not yet Tracked (untracked)
Split and classify clearly into the 3 levels below. Not everything belongs in the project’s shared .gitignore.
Level 1: System/IDE junk - set ignore at the global level
Files like .DS_Store, .vscode/, Thumbs.db.
Set the file:
1 | git config --global core.excludesFile ~/.gitignore_global |
Create the gitignore_global file and add the files/folders you want to ignore (exactly like .gitignore).
Reset (if you configured it wrong):
1 | git config --global --unset core.excludesFile |
Level 2: Personal junk inside the project - at the project level, local repo
For example: scratch files, an appsettings.Local.json file, edits specific to this repo. You don’t want to push them and you also don’t want to touch the shared .gitignore (afraid of conflicts with the team).
Solution:
Edit this file directly: .git/info/exclude (it sits inside the hidden .git folder).
The syntax is exactly the same as .gitignore.
Level 3: Project junk - at the project level and shared with the team
Build files, node_modules, .env. For these you just use .gitignore as usual.
Decision flow summary
- Is the file already on the remote?
- YES ->
git update-index --skip-worktree - NO -> Keep reading
- Does the team need this file?
- NO (Just mine/OS) -> Global Config or
.git/info/exclude. - NO (Build junk) ->
.gitignore. - YES -> Commit.
Done, that’s it.