-1
~/rails_projects/sample_app2 $ git branch
* master

~/rails_projects/sample_app2$ cat .gitignore
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
#   git config --global core.excludesfile '~/.gitignore_global'

# Ignore bundler config.
/.bundle

# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal

# Ignore all logfiles and tempfiles.
/log/*.log
/tmp

# Ignore other unneeded files.
database.yml
doc/
.*.s[a-w][a-z]  #all swap files
.*.*.s[a-w][a-z]
.*.*.*.s[a-w][a-z]
*~
.project
.DS_Store
.idea
.secret

~/rails_projects/sample_app2$ touch .gitignore.swp

~/rails_projects/sample_app2$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 15 commits.
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   .gitignore.swp
nothing added to commit but untracked files present (use "git add" to track)

~/rails_projects/sample_app2$ git add .
~/rails_projects/sample_app2$ git commit -m "Add swap file"
[master 364570c] Add swap file
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 .gitignore.swp

~/rails_projects/sample_app2$ git rm --cached .gitignore.swp
rm '.gitignore.swp'

~/rails_projects/sample_app2$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 16 commits.
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    .gitignore.swp
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   .gitignore.swp


~/rails_projects/sample_app2$ git commit -m "Remove swap file"
[master 485217f] Remove swap file
 0 files changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 .gitignore.swp

~/rails_projects/sample_app2$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 17 commits.
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   .gitignore.swp
nothing added to commit but untracked files present (use "git add" to track)

~/rails_projects/sample_app2$ $ git add .

~/rails_projects/sample_app2$ git commit -m "Trying NOT to add swap files"
[master d743282] Trying NOT to add swap files
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 .gitignore.swp

And on and on and on. Swap files keep showing up in the untracked files list when I do:

$ git status

Therefore when I do my next commit, the swap files get added to the files that git is tracking. How do I make git ignore all swap files?

This seems like such a common problem that there should be a command:

$ git ignore --all-swap-files

Response to one of the comments:

~/rails_projects$ mkdir test_gitignore
~/rails_projects$ cd test_gitignore/
~/rails_projects/test_gitignore$ touch .gitignore
~/rails_projects/test_gitignore$ echo '.*.s[a-w][a-z]' > .gitignore
~/rails_projects/test_gitignore$ git init
Initialized empty Git repository in /Users/7stud/rails_projects/test_gitignore/.git/
~/rails_projects/test_gitignore$ touch file1.txt .file1.swp
~/rails_projects/test_gitignore$ mkdir subdir
~/rails_projects/test_gitignore$ touch subdir/.file2.swp
~/rails_projects/test_gitignore$ ls -al
total 8
drwxr-xr-x   7 7stud  staff  238 Sep 14 10:41 .
drwxr-xr-x  19 7stud  staff  646 Sep 14 10:38 ..
-rw-r--r--   1 7stud  staff    0 Sep 14 10:40 .file1.swp
drwxr-xr-x  10 7stud  staff  340 Sep 14 10:40 .git
-rw-r--r--   1 7stud  staff   15 Sep 14 10:40 .gitignore
-rw-r--r--   1 7stud  staff    0 Sep 14 10:40 file1.txt
drwxr-xr-x   3 7stud  staff  102 Sep 14 10:41 subdir
~/rails_projects/test_gitignore$ ls -al subdir
total 0
drwxr-xr-x  3 7stud  staff  102 Sep 14 10:41 .
drwxr-xr-x  7 7stud  staff  238 Sep 14 10:41 ..
-rw-r--r--  1 7stud  staff    0 Sep 14 10:41 .file2.swp

~/rails_projects/test_gitignore$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   .gitignore
#   file1.txt
nothing added to commit but untracked files present (use "git add" to track)
~/rails_projects/test_gitignore$ 
7stud
  • 42,113
  • 12
  • 85
  • 111
  • possible duplicate of [git ignore vim temporary files](http://stackoverflow.com/questions/4824188/git-ignore-vim-temporary-files) – meager Sep 13 '14 at 03:31
  • @meager, How much time did you spend reading that "duplicate" and comparing the answers to the things I am doing? – 7stud Sep 13 '14 at 03:38
  • Not long, it's pretty obvious. – meager Sep 13 '14 at 03:39
  • 1
    I've rolled back the question since you've edited it significantly (in particular, the changes suggested in my answer were incorporated, and other stuff was changed). Please [ask a new question](http://stackoverflow.com/questions/ask) - don't worry, questions are free, so you can (within reason) ask as many as you want! – phihag Sep 13 '14 at 04:09
  • 1
    Yes, I was trying to show that your solution doesn't work. – 7stud Sep 13 '14 at 04:25

2 Answers2

3

Here is what is happening: Your .gitignore rules have extra spaces at the end of them. Git treats each entry within the gitignore as a ignore rule in entirety, it is precisely for the same reason you shouldn't have that comment in your gitignore - the pattern changes.

So, .*.s[a-w][a-z], though looks all right visibly in your .gitignore, happens to be the string ".*.s[a-w][a-z] "

Hence git ignore is unable to match the swap files.

As an aside, you can do away with the three swap ingore rules and use a single one instead

*.s[a-w][a-z]

And here is a sample python snippet to test what exactly the new pattern is matching (or not matching)

In [1]: import fnmatch

In [2]: pattern = "*.s[a-w][a-z]"

In [3]: filenames = [".file.swp", "folder/.file.swp", "folder/subfolder/.file.swp", ".f.i.l.e.swp", "folder/.f.i.l.e.swp"]

In [4]: for filename in filenames:
   ...:     print filename, fnmatch.fnmatch(filename, pattern)
   ...:     
.file.swp True
folder/.file.swp True
folder/subfolder/.file.swp True
.f.i.l.e.swp True
folder/.f.i.l.e.swp True

In [5]: pattern = ".*.s[a-w][a-z]"

In [6]: for filename in filenames:
    print filename, fnmatch.fnmatch(filename, pattern)
   ...:     
.file.swp True
folder/.file.swp False
folder/subfolder/.file.swp False
.f.i.l.e.swp True
folder/.f.i.l.e.swp False
Anshul Goyal
  • 61,070
  • 31
  • 133
  • 163
  • Thanks for wading through all the noise and helping me solve my problem. There were two spaces after my first pattern. You deserve many more points than I'm allowed to award you. Unfortunately, simple, idiotic answers get 60 points in 5 minutes on SO, but the answers for tricky problems never get much credit. – 7stud Sep 13 '14 at 17:16
  • **you can do away with the three swap ingore rules and use a single one instead** They are not equivalent, which I am sure upon further reflection you will realize. This issue was previously discussed under another answer, but falsetru deleted their answer. But in my comments, I posted a quote from a source I found that said, "No glob pattern will match a period. You have to explicitly specify a period.", which your very nice python example and my tests show is patently false. So if globs are greedy, then I only need `.*.s[a-w][a-z]` – 7stud Sep 13 '14 at 18:03
  • And my tests show that in both python and a bash shell, the `*` is greedy. – 7stud Sep 13 '14 at 18:03
  • @7stud Yeah, I understand they are not equivalent - I guess the deleted discussion was missing, so definitely had no idea that was the reason you were doing so, and hence thought to bring out a simplification to your notice. Anyway, good to know that its resolved :) – Anshul Goyal Sep 13 '14 at 18:48
  • @7stud Just gave it a thought to the pattern you mention in your comments, it might fail in some cases, though i'm not sure if you wanted to ignore them in the first place or not (ignoring swap files in subdirectories). Check edits in my answer. – Anshul Goyal Sep 14 '14 at 06:05
  • .gitignore works differently than python's fnmatch() and globs in general. The patterns listed in .gitignore are applied to files in the project directory and all subdirectories. I'll add an example at the bottom of my question. – 7stud Sep 14 '14 at 17:13
1

The problem is quite simple, it's the line

.*.s[a-w][a-z]  #all swap files

In a .gitignore file, comments can only be at the start of the line. Change this to

#all swap files
.*.s[a-w][a-z]

and it will work as intended:

$ /bin/echo -e '.*.s[a-w][a-z] # swap' > .gitignore 
$ touch .gitignore.swp
$ touch .x.swp
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   .gitignore

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        .gitignore.swp
        .x.swp

no changes added to commit (use "git add" and/or "git commit -a")
$ /bin/echo -e '.*.s[a-w][a-z]\n# swap' > .gitignore 
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   .gitignore

no changes added to commit (use "git add" and/or "git commit -a")
phihag
  • 245,801
  • 63
  • 407
  • 443
  • @7stud First of all, please keep some manners. Why are you being so rude? Secondly, please don't edit your question to reflect changes in an answer, that makes it hard to track the problem down. I've added the output of a shell session that demonstrates the problem. – phihag Sep 13 '14 at 04:07
  • My .gitignore doesn't have a comment where you say it does. Quit editing my question. – 7stud Sep 13 '14 at 04:09
  • @7stud It does, in line 25 of [your question before you edited it](http://stackoverflow.com/revisions/d202450b-e354-4bc5-86d9-16e92dfb0be4/view-source). – phihag Sep 13 '14 at 04:11
  • You said the problem was that my glob started with a period--*then you deleted your downvoted answer.* If you can edit/delete your answer, I can edit my question. – 7stud Sep 13 '14 at 04:13
  • Huh? You're probably confusing me with [falsetru](http://stackoverflow.com/users/2225682/falsetru). There are just two answers here, and only one (ID 25819568) is from me!? – phihag Sep 13 '14 at 04:14
  • I posted two comments under your answer, where did they go? – 7stud Sep 13 '14 at 04:15
  • @7stud, It's me who deleted the answer, not phihag. – falsetru Sep 13 '14 at 04:17
  • 1
    Please, before you do anything else, please take a step back and re-read what you wrote. You're coming off as way too aggressive and obnoxious, and i believe that that's not representative of you as a stackoverflow user. There is a second answer that got deleted. It is visible with [sufficient privileges](http://stackoverflow.com/help/privileges/moderator-tools). [Here is a screenshot](https://phihag.de/2014/so_deleted.png) – phihag Sep 13 '14 at 04:18
  • I want to delete my question and repost it. None of the proposed solutions work, and you guys and meager have messed up my question by rolling it back. The software won't let me delete it. Please delete my question so that I can repost it. – 7stud Sep 13 '14 at 04:21
  • @7stud Please don't delete answers. The value of stackoverflow is that questions and answers help others as soon as they are entered. As I wrote before, you are certainly free to ask if the problem persists with a corrected gitignore. But you seem overly angry, so maybe the best step towards solving this problem is taking a break and then re-analyzing it. For one, how do you explain that the shell session in this answer shows the exact same symptoms as your problem? – phihag Sep 13 '14 at 04:25