Add all files to a commit except a single file?

463,824

Solution 1

git add -u
git reset -- main/dontcheckmein.txt

Note: Git has subsequently added special syntax for this, which is explained in other answers.

Solution 2

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

Solution 3

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...

Solution 4

For a File

git add -u
git reset -- main/dontcheckmein.txt

For a folder

git add -u
git reset -- main/*

Solution 5

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.

Share:
463,824
user291701
Author by

user291701

Updated on May 07, 2022

Comments

  • user291701
    user291701 almost 2 years

    I have a bunch 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
    
    • Saad Abbasi
      Saad Abbasi over 3 years
      what is the purpose of -u flag it's working without -u
    • Simeon
      Simeon about 3 years
      From man git add: -u, --update "Update the index just where it already has an entry matching <pathspec>. This removes as well as modifies index entries to match the working tree, but adds no new files. ..."
    • Simeon
      Simeon about 3 years
      @SaadAbbasi Maybe this table from github.com/git-guides/git-add is even better to tell what -u does: git add -u: stages new and modified files only, NOT deleted files
    • Simeon
      Simeon about 3 years
      if you have untracked files, the -u option takes care that those untracked files are not added. git add --all would add those files as well.
  • Alan Coromano
    Alan Coromano over 10 years
    how do I exclude the whole folder? -- main or main/ or main/* ?
  • Anthony Naddeo
    Anthony Naddeo over 10 years
    I didn't know what -- was until your comment. According to the man pages, its optional and doesn't change the result of the command (at least in this case). This question seems to support that, stackoverflow.com/questions/17800994/…. Correct me if I'm wrong, but it seems that it means "treat anything after -- as arguments, not options / switches"
  • Bob Barbara
    Bob Barbara over 10 years
    Nice use of -- in git checkout I see in that question. I didn't know what the double dash was until this exchange of ours, too. I wonder if the git checkout ambiguity between branches and files could affect, in this or a different form, git reset also.
  • Dennis van der Schagt
    Dennis van der Schagt over 9 years
    You can use git rm --cached MyFolder/myyfile.txt to remove the file from the repository but keep it locally. Explanation on help.github.com
  • Dennis van der Schagt
    Dennis van der Schagt over 9 years
    @MariusKavansky You can use all of these forms. If you use main/* it is necessary to add -- in front of it to let git know that it is a path. The other two variants work without including the two dashes. (Tested in command prompt on Windows 7 with msysGit)
  • Michael Trouw
    Michael Trouw almost 9 years
    If you have some folders you want to exclude that contain a huge amount of files or other folders: temporarily add them to your gitignore. performing a git reset for those folders afterwards will still work, but it will take git a long while to add the big folders.
  • BroVic
    BroVic almost 6 years
    So, there's no one-liner?
  • Admin
    Admin over 5 years
    why is the -u necessary? why not git add . && git reset -- main/*?
  • ed1nh0
    ed1nh0 over 5 years
    @Ben Jackson would be nice to comment each line, don't you think?
  • Farhad Mammadli
    Farhad Mammadli over 5 years
    The -u option updates the index just where it already has an entry matching <pathspec>. This removes as well as modifies index entries to match the working tree, but adds no new files. If no <pathspec> is given when -u option is used, all tracked files in the entire working tree are updated (old versions of Git used to limit the update to the current directory and its subdirectories).
  • Martin_W
    Martin_W over 5 years
    This is excellent! Note that on Linux, you need to quote the :!... clauses to keep the shell from complaining. So, for example: git add --all -- ':!path/to/file1' ':!path/to/file2' ':!path/to/folder1/*'.
  • seeker_of_bacon
    seeker_of_bacon almost 5 years
    Is there something like :!/path/to/(file1|file2)?
  • gsumk
    gsumk almost 5 years
    this will undo all the changes main/dontcheckmein.txt.
  • Patrick
    Patrick over 4 years
    Can anyone explain why the -u is necessary in language that non-git pros will understand?
  • Pepeng Hapon
    Pepeng Hapon over 4 years
    -u is used to reference your current branch you're pushing to. You will no longer need to type git push origin master in your next push, just git push and git will know that is it in master branch. Hope it helps.
  • Merlin
    Merlin over 4 years
    This collides with something in zsh, doesn't work for me on macOS and latest git.
  • Dhanapal
    Dhanapal about 4 years
    stackoverflow.com/questions/41101998/… This will undo the changes
  • Naveen Kumar V
    Naveen Kumar V about 4 years
    Worked fine for me :)
  • luckyguy73
    luckyguy73 almost 4 years
    @Merlin i had same problem with mac until i used the quotes as mentioned by Martin_W comment, then it worked for me
  • Nuhman
    Nuhman almost 4 years
    Without the quotes around the :!..., I was getting event not found error in windows 10 git bash as well. Look @Martin_W's comment
  • Paul
    Paul over 3 years
    Note that the path is relative to the current directory! i.e. if you're in ./path/, use just git add --all -- ':!to/file1'
  • jolammi
    jolammi about 3 years
    This is the best answer. If it ts needed to exclude a large folder with a lot of files, adding and resetting takes ages. git add -- . ':!<path>' is way faster.
  • Simeon
    Simeon about 3 years
    After adding all files to the staging area via git add . typing git status will suggest you to git restore --staged main/dontcheckmein.txt Why did @gsumk suggest reset instead?
  • Simeon
    Simeon about 3 years
    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 Why did @BenJackson suggest reset instead?
  • Ben Jackson
    Ben Jackson about 3 years
    @Simeon git reset always did two things (switching branches, and restoring files). When this answer was written 10 years ago, git restore didn't exist (it was added in 2019). Now you could also write this answer in terms of git restore because it does some of the same things as reset
  • CodeFinity
    CodeFinity almost 3 years
    So, there's not really a way to do it then. Just add all the things and then remove 🔥 😃
  • SagarM
    SagarM almost 3 years
    How do I add the files back again?
  • Matt
    Matt almost 3 years
    Would git add . --:!path/to/file work too? Is there a distinction between git add . and git add -- .? Are the first -- before the . needed?
  • Matt
    Matt almost 3 years
    @jolammi I also see that you have the -- only before the ., but not before the excluded path? I'm just trying to understand where the --are redundant, and where they're actually required.
  • MaXi32
    MaXi32 almost 3 years
    I'm wondering where this command git update-index --assume-unchanged "main/dontcheckmein.txt" is stored in git folder structure
  • Richard Whitehead
    Richard Whitehead over 2 years
    I had to escape the exclamation mark, otherwise it failed with "event not found". git add -- . :\!main/dontcheckmein.txt
  • Marko
    Marko almost 2 years
    @cateyes answer should be accepted. This gives the same result but doesn't really do what the question asks. For example, when adding a large file this answer will still need a lot of time to add the large file, just to remove it later.
  • Dan Rosenstark
    Dan Rosenstark almost 2 years
    "which is explained in other answers" of which there are 22, so can you update to give us a hint, please? Thanks!