@@ -30,6 +30,11 @@ static const char git_attr__unknown[] = "(builtin)unknown";
3030#define DEBUG_ATTR 0
3131#endif
3232
33+ /*
34+ * NEEDSWORK: the global dictionary of the interned attributes
35+ * must stay a singleton even after we become thread-ready.
36+ * Access to these must be surrounded with mutex when it happens.
37+ */
3338struct git_attr {
3439 struct git_attr * next ;
3540 unsigned h ;
@@ -39,10 +44,19 @@ struct git_attr {
3944 char name [FLEX_ARRAY ];
4045};
4146static int attr_nr ;
47+ static struct git_attr * (git_attr_hash [HASHSIZE ]);
48+
49+ /*
50+ * NEEDSWORK: maybe-real, maybe-macro are not property of
51+ * an attribute, as it depends on what .gitattributes are
52+ * read. Once we introduce per git_attr_check attr_stack
53+ * and check_all_attr, the optimization based on them will
54+ * become unnecessary and can go away. So is this variable.
55+ */
4256static int cannot_trust_maybe_real ;
4357
58+ /* NEEDSWORK: This will become per git_attr_check */
4459static struct git_attr_check * check_all_attr ;
45- static struct git_attr * (git_attr_hash [HASHSIZE ]);
4660
4761const char * git_attr_name (const struct git_attr * attr )
4862{
@@ -102,6 +116,11 @@ static struct git_attr *git_attr_internal(const char *name, int len)
102116 a -> maybe_real = 0 ;
103117 git_attr_hash [pos ] = a ;
104118
119+ /*
120+ * NEEDSWORK: per git_attr_check check_all_attr
121+ * will be initialized a lot more lazily, not
122+ * like this, and not here.
123+ */
105124 REALLOC_ARRAY (check_all_attr , attr_nr );
106125 check_all_attr [a -> attr_nr ].attr = a ;
107126 check_all_attr [a -> attr_nr ].value = ATTR__UNKNOWN ;
@@ -318,6 +337,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
318337 * .gitignore file and info/excludes file as a fallback.
319338 */
320339
340+ /* NEEDSWORK: This will become per git_attr_check */
321341static struct attr_stack {
322342 struct attr_stack * prev ;
323343 char * origin ;
@@ -382,6 +402,24 @@ static struct attr_stack *read_attr_from_array(const char **list)
382402 return res ;
383403}
384404
405+ /*
406+ * NEEDSWORK: these two are tricky. The callers assume there is a
407+ * single, system-wide global state "where we read attributes from?"
408+ * and when the state is flipped by calling git_attr_set_direction(),
409+ * attr_stack is discarded so that subsequent attr_check will lazily
410+ * read from the right place. And they do not know or care who called
411+ * by them uses the attribute subsystem, hence have no knowledge of
412+ * existing git_attr_check instances or future ones that will be
413+ * created).
414+ *
415+ * Probably we need a thread_local that holds these two variables,
416+ * and a list of git_attr_check instances (which need to be maintained
417+ * by hooking into git_attr_check_alloc(), git_attr_check_initl(), and
418+ * git_attr_check_clear(). Then git_attr_set_direction() updates the
419+ * fields in that thread_local for these two variables, iterate over
420+ * all the active git_attr_check instances and discard the attr_stack
421+ * they hold. Yuck, but it sounds doable.
422+ */
385423static enum git_attr_direction direction ;
386424static struct index_state * use_index ;
387425
0 commit comments