Add all files to a commit except a single file?
I have a bunc开发者_运维问答h of files in a changeset, but I want to specifically ignore a single modified file. Looks like this after git status
:
# modified: main/dontcheckmein.txt
# deleted: main/plzcheckmein.c
# deleted: main/plzcheckmein2.c
...
Is there a way I can do git add
but just ignore the one text file I don't want to touch? Something like:
git add -u -except main/dontcheckmein.txt
git add -u
git reset -- main/dontcheckmein.txt
Note: Git has subsequently added special syntax for this, which is explained in other answers.
Now git
supports exclude certain paths and files
by pathspec magic :(exclude)
and its short form :!
. So you can easily achieve it as the following command.
git add --all -- :!main/dontcheckmein.txt
git add -- . :!main/dontcheckmein.txt
Actually you can specify more:
git add --all -- :!path/to/file1 :!path/to/file2 :!path/to/folder1/*
git add -- . :!path/to/file1 :!path/to/file2 :!path/to/folder1/*
For Mac and Linux, surround each file/folder path with quotes
git add --all -- ':!path/to/file1' ':!path/to/file2' ':!path/to/folder1/*'
1) To start ignoring changes to a single already versioned file
git update-index --assume-unchanged "main/dontcheckmein.txt"
and to undo that git update-index --no-assume-unchanged "main/dontcheckmein.txt"
github docs to ignore files
2) To completely ignore a specific single file preventing it from being created at repository
First, look at this stackoverflow post: Git global ignore not working
In .gitignore
, add the relative path to the file without leading ./
.
So, if your file is at MyProject/MyFolder/myfile.txt
, (where .git
is also in the MyProject
folder), add MyFolder/myfile.txt
to your at .gitignore
file.
You can confirm what rules are associated with ignore via git check-ignore "MyFolder/myfile.txt"
About global ignore
That link talks about ~/.gitignore_global
, but the file is related to your project. So, if you put the exclude pattern MyFolder/myfile.txt
in ~/.gitignore_global
, it will work but will not make much sense...
On the other hand, if you setup your project with git config core.excludesfile .gitignore
where .gitignore
is in MyProject
, the local file will override ~/.gitignore_global
, which can have very useful rules...
So, for now, I think it's best to make some script to mix your .gitignore
with ~/.gitignore_global
at .gitignore
.
One last warning
If the file you want to ignore is already in the repository, this method will not work unless you do this: git rm "MyFolder/myfile.txt"
, but back it up first, as it will be removed locally also! You can copy it back later...
For a File
git add -u
git reset -- main/dontcheckmein.txt
For a folder
git add -u
git reset -- main/*
While Ben Jackson is correct, I thought I would add how I've been using that solution as well. Below is a very simple script I use (that I call gitadd) to add all changes except a select few that I keep listed in a file called .gittrackignore
(very similar to how .gitignore works).
#!/bin/bash
set -e
git add -A
git reset `cat .gittrackignore`
And this is what my current .gittrackignore
looks like.
project.properties
I'm working on an Android project that I compile from the command line when deploying. This project depends on SherlockActionBar, so it needs to be referenced in project.properties, but that messes with the compilation, so now I just type gitadd
and add all of the changes to git without having to un-add project.properties every single time.
To keep the change in file but not to commit I did this
git add .
git reset -- main/dontcheckmein.txt
git commit -m "commit message"
to verify the file is excluded do
git status
Git provides :(exclude)
pathspecs prefix for paths to be excluded.
Its short magic signature is :^
.
Documentation: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-exclude
git add . :^main/dontcheckmein.txt
Some answers to this thread mention :!
, which would also work, but only with quotes. In general, !
is considered a horrible character for shell expansion.
If you are like me — always review what is going to be committed using -p
flag within the git add
command — :^
magic signature works like a charm, too:
git add -p . :^main/dontcheckmein.txt
git add .
git reset main/dontcheckmein.txt
Use git add -A
to add all modified and newly added files at once.
Example
git add -A
git reset -- main/dontcheckmein.txt
We can add all the files and exclude the file which has to be removed by git reset.
git add .
git reset -- <file_name_to_exclude>
add all files
git add .
get file path to paste below
git status
remove from the commit
git reset -- file/to/path/file-to-ignore.txt
For the specific case in the question, easiest way would be to add all files with .c extension and leave out everything else:
git add *.c
From git-scm (or/and man git add
):
git add <pathspec>…
Files to add content from. Fileglobs (e.g. *.c) can be given to add all matching files. <...>
Note that this means that you could also do something like:
git add **/main/*
to add all files (that are not ignored) that are in the main
folder. You can even go wild with more elaborate patterns:
git add **/s?c/*Service*
The above will add all files that are in s(any char)c
folder and have Service
somewhere in their filename.
Obviously, you are not limited to one pattern per command. That is, you could ask git to add all files that have an extension of .c and .h:
git add *.c *.h
This link might give you some more glob pattern ideas.
I find it particularly useful when I'm making many changes, but still want my commits to stay atomic and reflect gradual process rather than a hodgepodge of changes I may be working at the time. Of course, at some point the cost of coming up with elaborate patterns outweighs the cost of adding files with simpler methods, or even one file at a time. However, most of the time I'm easily able to pinpoint just the files I need with a simple pattern, and exclude everything else.
By the way, you may need to quote your glob patterns for them to work, but this was never the case for me.
Try this:
git checkout -- main/dontcheckmein.txt
Not directly what you asked as it does not achieve it in one command but the result should be what you desire.
After adding all files to the staging area via
git add -u
typing git status
will suggest you to
git restore --staged main/dontcheckmein.txt
I use git add --patch
quite a bit and wanted something like this to avoid having to hit d all the time through the same files. I whipped up a very hacky couple of git aliases to get the job done:
[alias]
HELPER-CHANGED-FILTERED = "!f() { git status --porcelain | cut -c4- | ( [[ \"$1\" ]] && egrep -v \"$1\" || cat ); }; f"
ap = "!git add --patch -- $(git HELPER-CHANGED-FILTERED 'min.(js|css)$' || echo 'THIS_FILE_PROBABLY_DOESNT_EXIST' )"
In my case I just wanted to ignore certain minified files all the time, but you could make it use an environment variable like $GIT_EXCLUDE_PATTERN
for a more general use case.
Changes to be committed: (use "git reset HEAD ..." to unstage)
If you want to ignore a particular file every time there are three effective solutions that don't involve .gitignore
.
Add the file you want to ignore to
.git/info/exclude
. It works just like your.gitignore
, except that the configuration is specific to your machine.Reset the file you want to using a pre-commit git hook. For example:
$ echo 'git reset -- src/main/resources/log4j.properties' >> .git/hooks/pre-commit $ chmod +x .git/hooks/pre-commit
A pre-commit hook runs just before a commit. So your files can be automatically reset before each commit.
$ git status On branch CHANGE-137-notifications-support ... Changes not staged for commit: modified: Dockerfile modified: src/main/resources/log4j.properties $ git add . $ git status On branch CHANGE-137-notifications-support ... Changes to be committed: modified: Dockerfile modified: src/main/resources/log4j.properties $ git commit -m "Trivial change" Unstaged changes after reset: M src/main/resources/log4j.properties [CHANGE-137-notifications-support 97cfb3f] Trivial change 1 file changed, 3 insertions(+)
The third way is to update the index for a particular file.
$ git update-index --assume-unchanged src/main/resources/log4j.properties
You can try this: git add * && git reset main/dontcheckmein.txt
精彩评论