简体   繁体   中英

How do I get git to track and commit files according to .gitignore (from the beginning)?

Edit :
The detail in my question hides the true nature of the problem. However, as this is how the problem is likely to manifest to others, I've decided to keep it as is and just add this edit, and the answer below.


I am completely new to git.

I'm working on a PHP-based website and would like to track only my files:
ie only files in /plugins/my-plugins/ and /themes/my-theme/ .

Having failed to get this to work I decide to create and play with a minimum working example.

According to https://git-scm.com/docs/gitignore :

Example to exclude everything except a specific directory foo/bar (note the /* - without the slash, the wildcard would also exclude everything within foo/bar):
$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar

So, I created files/folders to match:

alan@lamp ~/GitPlay$ tree -a
.
|-- .gitignore
|-- README.md
|-- foo
|   |-- bar
|   |   -- shouldNOTbeExcluded_bar.txt
|   -- shouldBeExcluded_foo.txt
-- shouldBeExcluded.txt

2 directories, 4 files
alan@lamp ~/GitPlay$ 

According to https://dzone.com/refcardz/getting-started-git :

...initialize the directory as a Git repository by typing the following commands:
git init
git add .
git commit –m 'The first commit'

Before git add. :

alan@lamp ~/GitPlay$ git status
On branch master

Initial commit

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

    .gitignore
    README.md
    foo/
    shouldBeExcluded.txt

nothing added to commit but untracked files present (use "git add" to track)
alan@lamp ~/GitPlay$ 

So, it's not tracking the files it shouldn't track. Which suggests it is tracking the files it should track.
So maybe I can just commit what is, apparently, being tracked:

alan@lamp ~/GitPlay$ git commit -m 'Very first commit after git init'
On branch master

Initial commit

Untracked files:
    .gitignore
    README.md
    foo/
    shouldBeExcluded.txt

nothing added to commit but untracked files present
alan@lamp ~/GitPlay$ 

"nothing added to commit".

OK, let's add something:

alan@lamp ~/GitPlay$ git add .

And now see what happened:

alan@lamp ~/GitPlay$ git status
On branch master

Initial commit

    Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   .gitignore
    new file:   README.md
    new file:   foo/bar/shouldNOTbeExcluded_bar.txt
    new file:   foo/shouldBeExcluded_foo.txt
    new file:   shouldBeExcluded.txt

alan@lamp ~/GitPlay$ 

Now it's planning to add everything in the next commit. Which is not what I want.

Lets' see what actually happens:

alan@lamp ~/GitPlay$ git commit -m 'Very first commit after git init'
[master (root-commit) dca0c49] Very first commit after git init
 5 files changed, 37 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 README.md
 create mode 100644 foo/bar/shouldNOTbeExcluded_bar.txt
 create mode 100644 foo/shouldBeExcluded_foo.txt
 create mode 100644 shouldBeExcluded.txt
alan@lamp ~/GitPlay$ 

As I suspected, everything is committed.

So, my question:
How do I get git to track and commit files according to .gitignore from the beginning?

Or am I missing something fundamental?
Is the 'correct' procedure
to commit EVERYTHING in the very first commit regardless of .gitignore ,
and then git will track changes according to .gitignore from the next git add . / git commit ... onwards?


According to git add all except ignoring files in .gitignore file

I think you mean git add . which will add all of the files to the repo that AREN'T specified in the .gitignore - you can see these changes by typing git status

git add .
This will add all paths and ignore matches from .gitignore

Which doesn't match my experience: git add . adds ALL files and ignores .gitignore .

According to
Git add . ignores .gitignore

.gitignore is taking into consideration only for new files.

Which does fit what I'm finding.


Further play

Immediately following the first commit:

alan@lamp ~/GitPlay$ git status
On branch master
nothing to commit, working tree clean

So I thought, maybe clearing the staging cache will fix the problem:

alan@lamp ~/GitPlay$ git rm -r --cached .
rm '.gitignore'
rm 'README.md'
rm 'foo/bar/shouldNOTbeExcluded_bar.txt'
rm 'foo/shouldBeExcluded_foo.txt'
rm 'shouldBeExcluded.txt'

alan@lamp ~/GitPlay$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    .gitignore
    deleted:    README.md
    deleted:    foo/bar/shouldNOTbeExcluded_bar.txt
    deleted:    foo/shouldBeExcluded_foo.txt
    deleted:    shouldBeExcluded.txt

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

    .gitignore
    README.md
    foo/
    shouldBeExcluded.txt

alan@lamp ~/GitPlay$ git rm -r --cached .
fatal: pathspec '.' did not match any files

alan@lamp ~/GitPlay$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    .gitignore
    deleted:    README.md
    deleted:    foo/bar/shouldNOTbeExcluded_bar.txt
    deleted:    foo/shouldBeExcluded_foo.txt
    deleted:    shouldBeExcluded.txt

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

    .gitignore
    README.md
    foo/
    shouldBeExcluded.txt

alan@lamp ~/GitPlay$ git add .

alan@lamp ~/GitPlay$ git commit -m 'First commit'
On branch master
nothing to commit, working tree clean

alan@lamp ~/GitPlay$ git status
On branch master
nothing to commit, working tree clean

alan@lamp ~/GitPlay$ ll
total 24
drwxr-xr-x 4 alan alan 4096 Jul  3 15:08 ./
drwxr-xr-x 8 alan alan 4096 Jul  3 16:05 ../
drwxr-xr-x 8 alan alan 4096 Jul  3 17:16 .git/
-rw-r--r-- 1 alan alan  139 Jul  3 15:03 .gitignore
-rw-r--r-- 1 alan alan  588 Jul  3 14:47 README.md
drwxr-xr-x 3 alan alan 4096 Jul  3 15:09 foo/
-rw-r--r-- 1 alan alan    0 Jul  3 15:08 shouldBeExcluded.txt

alan@lamp ~/GitPlay$ git add -f .

alan@lamp ~/GitPlay$ git status
On branch master
nothing to commit, working tree clean

So now I can't stage and commit anything.

While you have a .gitignore file, you haven't told git about it. You need to track it first:

git add .gitignore

Once you've done that, then the files that you want ignored will be ignored.

The reason that running git add . didn't work is because .gitignore only works for untracked files. Adding all files makes everything tracked (even the files you want ignored), so at that point .gitignore isn't used.

This question could have been simply
How do I get git to track and commit files according to .gitignore?
Which, as @acsrujan pointed out in the question comments, has been answered by git add all except ignoring files in .gitignore file .

However, what my question did not show,
-- due to a markdown artefact, " Indent four spaces to create an escaped <pre> <code> block " --
is that my copy/paste of a .gitignore file from Git - gitignore documentation , introduced leading white space to each pattern line of my .gitignore file.

This seems to have the same effect as beginning lines with # -- " A line starting with # serves as a comment. " -- or possibly git treats such lines as blank lines -- " A blank line matches no files, so it can serve as a separator for readability. " Quotes from Git - gitignore documentation .

Removing the leading spaces solves the problem and the .gitignore file works as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM