"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: got diff vs .gitignore
To:
Omar Polo <op@omarpolo.com>
Cc:
gameoftrees@openbsd.org
Date:
Thu, 10 Feb 2022 16:49:36 +0100

Download raw body.

Thread
On Thu, Feb 10, 2022 at 03:58:15PM +0100, Omar Polo wrote:
> Hello,
> 
> I noticed that `got diff' and .gitignore have a strange relationship.
> 
> I was working in an autotools project, my .gitignore had "**/Makefile"
> in it; one sub-directory thought has plain Makefile that was properly
> added to the repository.  `got diff' showed the diff for it, but `got
> diff path/to/Makefile' didn't!
> 
> Patch below adds a test case and fixes the isuse for me.  Regress is
> passing, but I'm not 100% sure that the patch is correct.
> got_worktree_status takes a flag `no_ignores'; i'm merely switching it
> to don't skip ignored files.

A big problem with your fix is that the status crawl will no longer
skip ignored subdirs. For instance, if you are inside a /usr/ports
work tree with a pobj/ dir that contains lots of stuff, you don't
want got status to crawl the ignored pobj/ dir while diffing things.
Crawling pobj/ would just be a waste of time for no gain.

The patch below seems like a better fix to me.
The bug is that report_single_file_status() matches paths against ignore
patterns before doing anything else. This forgets to take into account
that only unversioned files should be affected by ignores. Any already
versioned file should be processed as usual even if it happens to match
an ignore pattern. Yet this function skips such files.

This patch makes your test pass and does not break any others.

ok?

diff 5a20d08d6546fa260cd5ce2ed01e438f5ec35f41 bb10ea6a88e34392660ce4081898b737955d702e
blob - 610c0eb85518f221f5f8ae1907397ddd07bea422
blob + 0b4571401cfdddef043be11cce960c58beae2802
--- lib/worktree.c
+++ lib/worktree.c
@@ -3560,9 +3560,6 @@ report_single_file_status(const char *path, const char
 	struct got_fileindex_entry *ie;
 	struct stat sb;
 
-	if (!no_ignores && match_ignores(ignores, path))
-		return NULL;
-
 	ie = got_fileindex_entry_get(fileindex, path, strlen(path));
 	if (ie)
 		return report_file_status(ie, ondisk_path, -1, NULL,
@@ -3575,6 +3572,9 @@ report_single_file_status(const char *path, const char
 		    GOT_STATUS_NO_CHANGE, path, NULL, NULL, NULL, -1, NULL);
 	}
 
+	if (!no_ignores && match_ignores(ignores, path))
+		return NULL;
+
 	if (S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode))
 		return (*status_cb)(status_arg, GOT_STATUS_UNVERSIONED,
 		    GOT_STATUS_NO_CHANGE, path, NULL, NULL, NULL, -1, NULL);