Add all files to a commit except a single file?

泪湿孤枕 提交于 2019-11-27 09:55:49
git add -u
git reset -- main/dontcheckmein.txt
Aquarius Power

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"

check here

2) To completely ignore a specific single file preventing it from being created at repository

First look at this Git global ignore not working

and at .gitignore add the relative path to the file without leading ./

so if your file is at MyProject/MyFolder/myfile.txt (where .git is also at MyProject), at .gitignore you put just this MyFolder/myfile.txt

you can confirm what rule is related to the ignore with git check-ignore "MyFolder/myfile.txt"

About global ignore

That link speaks about ~/.gitignore_global; but the file is related to your project; so, if you put the exclude pattern MyFolder/myfile.txt at ~/.gitignore_global, it will work but will not make much sense...

In the other hand, if you setup your project with git config core.excludesfile .gitignore where .gitignore is at MyProject; that setup will override ~/.gitignore_global that can have very useful rules...

So, for now, I think the best is 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 on the repository, this method will not work unless you do this: git rm "MyFolder/myfile.txt", but backup it 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/*

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/*

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.

Try this:

git checkout -- 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

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

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.

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.

Changes to be committed: (use "git reset HEAD ..." to unstage)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!