Home > front end >  how to omit the "-f" for "git add", if the previous version is already in git?
how to omit the "-f" for "git add", if the previous version is already in git?

Time:08-31

I would like to track only a very restricted set of files, explicitly added to the repository using "git add -f". But how can I avoid having to use the "-f" again and again for files that are already in?

Sample:

% cat .gitignore 
/*

% git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   playlists/README

% git add playlists/README
The following paths are ignored by one of your .gitignore files:
playlists
hint: Use -f if you really want to add them.
hint: Turn this message off by running
hint: "git config advice.addIgnoredFile false"

% git check-ignore -v playlists/README
% echo $?
1

% git commit -a -m "fixed some typo"
[master 039d616] fixed some typo
 1 file changed, 1 deletion(-)

% git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

% git version
git version 2.37.2

The playlists/README was explicitly mentioned on the command line, and yet I have to use "-f"? git commit wasn't so picky.

Of course I checked the man page. It says

   A gitignore file specifies intentionally untracked files that Git should
   ignore. Files already tracked by Git are not affected; see the NOTES
   below for details.

But the "NOTES below" didn't tell. playlists/README is already tracked, and yet it was affected. Please excuse if I am too blind to see.

Every insightful comment is highly appreciated

CodePudding user response:

(Not an answer, I'm abusing the answer box to provide a formatted comment). Upd: reproduced. Shell script:

#! /bin/sh
set -e

git --version
git init test-add-gitignore-repo
cd test-add-gitignore-repo

echo
echo stage 1
mkdir testdir
echo test >testdir/test.txt
echo "/*" >.gitignore
git status

echo
echo stage 2
git add -f testdir/test.txt
git commit -m Test
git status

echo
echo stage 3
echo test2 >testdir/test.txt
git status

echo
echo stage 4
git add testdir/test.txt || :
git status

cd ..
rm -rf test-add-gitignore-repo

Output:

git version 2.30.2
Initialized empty Git repository in /home/phd/tmp/test-add-gitignore-repo/.git/

stage 1
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

stage 2
[master (root-commit) 9ca248a] Test
 1 file changed, 1 insertion( )
 create mode 100644 testdir/test.txt
On branch master
nothing to commit, working tree clean

stage 3
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   testdir/test.txt

no changes added to commit (use "git add" and/or "git commit -a")

stage 4
The following paths are ignored by one of your .gitignore files:
testdir
hint: Use -f if you really want to add them.
hint: Turn this message off by running
hint: "git config advice.addIgnoredFile false"
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   testdir/test.txt

CodePudding user response:

I think you get this repeated warning because /* rule instructs git to ignore the complete playlist/ directory, and even the presence of a tracked file inside that directory isn't accounted as a known exception to this rule (git doesn't track directories, and I think a directory has no existence in the index).

The behavior on directories is hinted at by the documentation on .gitignore rules (emphasis mine) :

  • An optional prefix "!" which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined. [...]

To have the "ignore everything except the files I explicitly added with -f (at any directory level)" behavior, try the following gitignore file :

# ignore all files, but keep going down in directories
*
!*/

Another way to avoid the warning with a specific target on the playlist/ directory could be :

/*
!/playlist
/playlist/*
  • Related