ChatGPT解决这个技术问题 Extra ChatGPT

How do I configure git to ignore some files locally?

Can I ignore files locally without polluting the global git config for everyone else? I have untracked files that are spam in my git status but I don't want to commit git config changes for every single little random untracked file I have in my local branches.


M
Minhas Kamal

From the relevant Git documentation:

Patterns which are specific to a particular repository but which do not need to be shared with other related repositories (e.g., auxiliary files that live inside the repository but are specific to one user's workflow) should go into the $GIT_DIR/info/exclude file.

The .git/info/exclude file has the same format as any .gitignore file. Another option is to set core.excludesFile to the name of a file containing global patterns.

Note, if you already have unstaged changes you must run the following after editing your ignore-patterns:

git update-index --assume-unchanged <file-list>

Note on $GIT_DIR: This is a notation used all over the git manual simply to indicate the path to the git repository. If the environment variable is set, then it will override the location of whichever repo you're in, which probably isn't what you want.

Edit: Another way is to use:

git update-index --skip-worktree <file-list>

Reverse it by:

git update-index --no-skip-worktree <file-list>

As a note, make sure to run git update-index --assume-unchanged [<file>...] after making the addition to the exclude file. The changes won't be picked up until then.
I did not need to run 'git update-index ...' for the changes to take effect using git 1.7.9.5.
You only need to use git update-index if you've already made a change to the file and now want it to be ignored. If you change exclude prior to making the change, it's not necessary.
While this stops the file from appearing as changed during commits like .gitignore, unlike ignored files, the file(s) will still be reset back to the repo version if you execute git reset --hard.
Per stackoverflow.com/questions/23097368/… and stackoverflow.com/questions/13630849/…, skip-worktree would likely be preferred to assume-unchanged.
1
1615903

Update: Consider using git update-index --skip-worktree [<file>...] instead, thanks @danShumway! See Borealid's explanation on the difference of the two options.

Old answer:

If you need to ignore local changes to tracked files (we have that with local modifications to config files), use git update-index --assume-unchanged [<file>...].


Just to note, I added a file to $GIT_DIR/info/exclude (e.g., my-file.php) and then had to run git update-index --assume-unchanged my-file.php for it to start being ignored. Thanks for the tip!
To undo it: git update-index --no-assume-unchanged my-file.php
Just for clarification: assume-unchanged is for tracked files (exist in the repo)... OP was asking for UNtracked files, in which case .git/info/exclude is what you want (to avoid polluting the often shared and tracked .gitignore)
According to stackoverflow.com/questions/23097368/… this is considered unsafe, and your files may still be committed if you're not careful. It's intended as a performance aid, not as a foolproof solution to this problem.
I rushed to --assume-unchanged before reading your update. I undid with --no-assume-unchanged and then did the --skip-worktree... Am I in the clear?
p
phatmann

Add the following lines to the [alias] section of your .gitconfig file

ignore = update-index --assume-unchanged
unignore = update-index --no-assume-unchanged
ignored = !git ls-files -v | grep "^[[:lower:]]"

Now you can use git ignore my_file to ignore changes to the local file, and git unignore my_file to stop ignoring the changes. git ignored lists the ignored files.

This answer was gleaned from http://gitready.com/intermediate/2009/02/18/temporarily-ignoring-files.html.


"!git ls-files -v | grep "^[[:lower:]]" - Any chance you know how to do this on windows cmd?
Install a real shell (for example Babun provides bash or zsh) ;) I know your feelings, but I recently switched from Windows to Linux and I'd never to use cmd again.
@Haohmaru, you could always use WSL (Windows Subsystem for Linux).
WOW ! great commands
E
Emil Sit

You have several options:

Leave a dirty (or uncommitted) .gitignore file in your working dir (or apply it automatically using topgit or some other such patch tool).

Put the excludes in your $GIT_DIR/info/exclude file, if this is specific to one tree.

Run git config --global core.excludesfile ~/.gitignore and add patterns to your ~/.gitignore. This option applies if you want to ignore certain patterns across all trees. I use this for .pyc and .pyo files, for example.

Also, make sure you are using patterns and not explicitly enumerating files, when applicable.


I think you need git config --global to set the option globally.
Actually, just add .gitignore to .gitignore ;)!
P
Piotr Korlaga

I think you are looking for:

git update-index --skip-worktree FILENAME

which ignore changes made local

Here's http://devblog.avdi.org/2011/05/20/keep-local-modifications-in-git-tracked-files/ more explanation about these solution!

to undo use:

git update-index --no-skip-worktree FILENAME

There is a relevant discussion between --skip-worktree and --assume-unchanged at this SO question
How would I undo this, or see the list of files/patterns that currently are being ignored via --skipworktree, should I later change my mind and want to start tracking the file again?
how to undo this?
To undo please use git update-index --no-skip-worktree <file>
@Anomaly To list the files being ignored by --skip-worktree, you need this git ls-files -v | grep ^S
B
Brad Koch

You can simply add a .gitignore file to your home directory, i.e. $HOME/.gitignore or ~/.gitignore. Then tell git to use that file with the command:

git config --global core.excludesfile ~/.gitignore

This is a normal .gitignore file which git references when deciding what to ignore. Since it's in your home directory, it applies only to you and doesn't pollute any project .gitignore files.

I've been using this approach for years with great results.


Thanks, @EricChen. I've updated the ansswer; give that a try and and then use git check-ignore <file-name> to verify. LMK if it works for you
It only worked for me without the =: git config --global core.excludesfile ~/.gitignore
I put a .gitignore file under home directory and told git to use that file instead, then deleted the files I would like to untrack locally. However, after I push the changes, the remote repository also deleted those files. Did I do something wrong?
Wow, @xyz; .gitignore is about ignoring files that exist in your local directory. What you should have done is git rm --cached which removes them from the repo but leaves them in your local. You should be able to go back to your previous commit with something like git reset --soft HEAD^ to undo that commit and recover your files. That's the beauty of git: it's all still there in your git history.
B
Birchlabs

You can install some git aliases to make this process simpler. This edits the [alias] node of your .gitconfig file.

git config --global alias.ignore 'update-index --skip-worktree'
git config --global alias.unignore 'update-index --no-skip-worktree'
git config --global alias.ignored '!git ls-files -v | grep "^S"'

The shortcuts this installs for you are as follows:

git ignore config.xml git will pretend that it doesn't see any changes upon config.xml — preventing you from accidentally committing those changes.

git will pretend that it doesn't see any changes upon config.xml — preventing you from accidentally committing those changes.

git unignore config.xml git will resume acknowledging your changes to config.xml — allowing you again to commit those changes.

git will resume acknowledging your changes to config.xml — allowing you again to commit those changes.

git ignored git will list all the files which you are "ignoring" in the manner described above.

git will list all the files which you are "ignoring" in the manner described above.

I built these by referring to phatmann's answer — which presents an --assume-unchanged version of the same.

The version I present uses --skip-worktree for ignoring local changes. See Borealid's answer for a full explanation of the difference, but essentially --skip-worktree's purpose is for developers to change files without the risk of committing their changes.

The git ignored command presented here uses git ls-files -v, and filters the list to show just those entries beginning with the S tag. The S tag denotes a file whose status is "skip worktree". For a full list of the file statuses shown by git ls-files: see the documentation for the -t option on git ls-files.


This doesn't work for untracked files :< (git 2.13.5 on osx)
Is the '!' supposed to be in '!git ls-files -v | grep "^S"'? The command doesn't work for me with it on there.. and seems to work fine with it removed.
the exclamation mark in a git alias tells git to run an external command, rather than a git subcommand. I put it in because I need a shell pipeline, so I need to invoke git from outside. I just tried removing the exclamation mark (as per your recommendation), but that does not work for me. I get Expansion of alias 'ignored' failed; 'git' is not a git command. This makes sense; without the exclamation mark: git aliases your command to git git ls-files ….
Thanks for the explanation. I am not familiar with git alias and was just running in a shell to test before making the alias.
This is a brilliant solution. Since git tracks per directory, when you run the above alias git ignore <filename>, it only applies to that directory. And when you finally want to make your changes to that file and commit and push to remote, just use the handy git unignore <filename> to temporarily start tracking it again! Thanks!
Z
Zach Lysobey

This is a brief one-line solution to exclude a local file.

 echo YOUR_FILE_OR_DIRECTORY >> .git/info/exclude

Perfect for specific symlinks
You also can enter folders directly under .git/info/exclude if in case echo does not work
yes, the same @UmairHamid
A
Ahmed Kareem

Both --assume-unchanged and --skip-worktree are NOT A CORRECT WAY to ignore files locally... Kindly check this answer and the notes in the documentation of git update-index. Files that for any reason keep changing frequently (and/or change from a clone to another) and their changes should not be committed, then these files SHOULD NOT be tracked in the first place.

However, the are two proper ways to ignore files locally (both work with untracked files). Either to put files names in .git/info/exclude file which is the local alternative of .gitignore but specific to the current clone. Or to use a global .gitignore (which should be properly used only for common auxiliary files e.g. pyz, pycache, etc) and the file will be ignored in any git repo in your machine.

To make the above as kind of automated (adding to exclude or global .gitignore), you can use the following commands (add to your bash-profile):

Per clone local exclude (Note that you should be in the root of the repository when calling the command because of using the relative path), change ##FILE-NAME## to .git/info/exclude

Global .gitignore, first make global .gitignore here then change ##FILE-NAME## to ~/.gitignore

Linux

alias git-ignore='echo $1 >> ##FILE-NAME##'
alias git-show-ignored='cat ##FILE-NAME##'
git-unignore(){
  GITFILETOUNIGNORE=${1//\//\\\/}
  sed -i "/$GITFILETOUNIGNORE/d" ##FILE-NAME##
  unset GITFILETOUNIGNORE
}

MacOS (you need the .bak for sed inplace modifications (i.e. you are forced to add a file extension to inplace sed. i.e. make a backup before replacing something), therefore to delete the .bak file I added rm filename.bak)

alias git-ignore='echo $1 >> ##FILE-NAME##'
alias git-show-ignored='cat ##FILE-NAME##'
git-unignore(){
  GITFILETOUNIGNORE=${1//\//\\\/}
  sed -i.bak "/$GITFILETOUNIGNORE/d" ##FILE-NAME##
  rm ##FILE-NAME##.bak
  unset GITFILETOUNIGNORE
}

Then you can do:

git-ignore example_file.txt
git-unignore example_file.txt


a
aak318

In order to ignore untracked files especially if they are located in (a few) folders that are not tracked, a simple solution is to add a .gitignore file to every untracked folder and enter in a single line containing * followed by a new line. It's a really simple and straightforward solution if the untracked files are in a few folders. For me, all files were coming from a single untracked folder vendor and the above just worked.


Great! FYI: This works only because git only tracks (and lets you commit) files, not folders.
v
voltdev

Just Simply add path to the file ypu want to remove from commits on any branch of current repo:

Unhide hidden files in Windows Directories Settings Open Path REPO_MAIN_PATH/.git/info/exclude Add for example **/toExcludeFile.bat

And thats it ! For me answears above are too long. KISS - Keep it stupid simple


Your solution would be more simple if you didn't explain how it's the most simple.
d
drkvogel

For anyone who wants to ignore files locally in a submodule:

Edit my-parent-repo/.git/modules/my-submodule/info/exclude with the same format as a .gitignore file.


G
Gavin S. Yancey

If your repo doesn't already have a .gitignore file, then a simple solution is to create a .gitignore file, and in it add .gitignore to the list of files to be ignored.


And what if the team then wants to add to add a gitignore later? Does this even work? Sounds like a terrible idea and like something that shouldn't even work.
This guy's answer cracked me up. No way anybody's doing this.
This is a quick and simple solution, as long as there is a place to put it. Our repo has a shared .gitignore file at the top. But my dirty files are in a deep folder, so I just added my own .gitignore next to them. +1