Skip to content

Commit

Permalink
Improve documentation and comments regarding directory traversal API
Browse files Browse the repository at this point in the history
traversal API has a few potentially confusing properties.  These
comments clarify a few key aspects and will hopefully make it easier
to understand for other newcomers in the future.

Signed-off-by: Adam Spiers <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
aspiers authored and gitster committed Dec 28, 2012
1 parent f1a7082 commit 95a6834
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
9 changes: 6 additions & 3 deletions Documentation/technical/api-directory-listing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ Data structure
--------------

`struct dir_struct` structure is used to pass directory traversal
options to the library and to record the paths discovered. The notable
options are:
options to the library and to record the paths discovered. A single
`struct dir_struct` is used regardless of whether or not the traversal
recursively descends into subdirectories.

The notable options are:

`exclude_per_dir`::

Expand Down Expand Up @@ -39,7 +42,7 @@ options are:
If set, recurse into a directory that looks like a git
directory. Otherwise it is shown as a directory.

The result of the enumeration is left in these fields::
The result of the enumeration is left in these fields:

`entries[]`::

Expand Down
8 changes: 7 additions & 1 deletion dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* This handles recursive filename detection with exclude
* files, index knowledge etc..
*
* See Documentation/technical/api-directory-listing.txt
*
* Copyright (C) Linus Torvalds, 2005-2006
* Junio Hamano, 2005-2006
*/
Expand Down Expand Up @@ -476,6 +478,10 @@ void add_excludes_from_file(struct dir_struct *dir, const char *fname)
die("cannot use %s as an exclude file", fname);
}

/*
* Loads the per-directory exclude list for the substring of base
* which has a char length of baselen.
*/
static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
{
struct exclude_list *el;
Expand All @@ -486,7 +492,7 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
(baselen + strlen(dir->exclude_per_dir) >= PATH_MAX))
return; /* too long a path -- ignore */

/* Pop the ones that are not the prefix of the path being checked. */
/* Pop the directories that are not the prefix of the path being checked. */
el = &dir->exclude_list[EXC_DIRS];
while ((stk = dir->exclude_stack) != NULL) {
if (stk->baselen <= baselen &&
Expand Down
26 changes: 24 additions & 2 deletions dir.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef DIR_H
#define DIR_H

/* See Documentation/technical/api-directory-listing.txt */

#include "strbuf.h"

struct dir_entry {
Expand All @@ -13,6 +15,12 @@ struct dir_entry {
#define EXC_FLAG_MUSTBEDIR 8
#define EXC_FLAG_NEGATIVE 16

/*
* Each .gitignore file will be parsed into patterns which are then
* appended to the relevant exclude_list (either EXC_DIRS or
* EXC_FILE). exclude_lists are also used to represent the list of
* --exclude values passed via CLI args (EXC_CMDL).
*/
struct exclude_list {
int nr;
int alloc;
Expand All @@ -26,9 +34,15 @@ struct exclude_list {
} **excludes;
};

/*
* The contents of the per-directory exclude files are lazily read on
* demand and then cached in memory, one per exclude_stack struct, in
* order to avoid opening and parsing each one every time that
* directory is traversed.
*/
struct exclude_stack {
struct exclude_stack *prev;
char *filebuf;
struct exclude_stack *prev; /* the struct exclude_stack for the parent directory */
char *filebuf; /* remember pointer to per-directory exclude file contents so we can free() */
int baselen;
int exclude_ix;
};
Expand Down Expand Up @@ -59,6 +73,14 @@ struct dir_struct {
#define EXC_DIRS 1
#define EXC_FILE 2

/*
* Temporary variables which are used during loading of the
* per-directory exclude lists.
*
* exclude_stack points to the top of the exclude_stack, and
* basebuf contains the full path to the current
* (sub)directory in the traversal.
*/
struct exclude_stack *exclude_stack;
char basebuf[PATH_MAX];
};
Expand Down

0 comments on commit 95a6834

Please sign in to comment.