13
#include "dir.h"
14
#include "utf8.h"
15
#include "quote.h"
16
+#include "revision.h"
17
+#include "object-store.h"
18
#include "thread-utils.h"
19
20
const char git_attr__true[] = "(builtin)true";
731
return res;
732
}
733
732
-static struct attr_stack *read_attr_from_index(struct index_state *istate,
733
- const char *path,
734
- unsigned flags)
734
+static struct attr_stack *read_attr_from_buf(char *buf, const char *path,
735
+ unsigned flags)
736
{
737
struct attr_stack *res;
737
- char *buf, *sp;
738
+ char *sp;
739
int lineno = 0;
740
741
+ if (!buf)
742
+ return NULL;
743
+
744
+ CALLOC_ARRAY(res, 1);
745
+ for (sp = buf; *sp;) {
746
+ char *ep;
747
+ int more;
748
+
749
+ ep = strchrnul(sp, '\n');
750
+ more = (*ep == '\n');
751
+ *ep = '\0';
752
+ handle_attr_line(res, sp, path, ++lineno, flags);
753
+ sp = ep + more;
754
+ }
755
+ free(buf);
756
+
757
+ return res;
758
+}
759
+
760
+static struct attr_stack *read_attr_from_blob(struct index_state *istate,
761
+ const struct object_id *tree_oid,
762
+ const char *path, unsigned flags)
763
+{
764
+ struct object_id oid;
765
+ unsigned long sz;
766
+ enum object_type type;
767
+ void *buf;
768
+ unsigned short mode;
769
+
770
+ if (!tree_oid)
771
+ return NULL;
772
+
773
+ if (get_tree_entry(istate->repo, tree_oid, path, &oid, &mode))
774
+ return NULL;
775
+
776
+ buf = repo_read_object_file(istate->repo, &oid, &type, &sz);
777
+ if (!buf || type != OBJ_BLOB) {
778
+ free(buf);
779
+ return NULL;
780
+ }
781
+
782
+ return read_attr_from_buf(buf, path, flags);
783
+}
784
+
785
+static struct attr_stack *read_attr_from_index(struct index_state *istate,
786
+ const char *path, unsigned flags)
787
+{
788
+ char *buf;
789
+
790
if (!istate)
791
return NULL;
792
808
if (!buf)
809
return NULL;
810
761
- CALLOC_ARRAY(res, 1);
762
- for (sp = buf; *sp; ) {
763
- char *ep;
764
- int more;
765
-
766
- ep = strchrnul(sp, '\n');
767
- more = (*ep == '\n');
768
- *ep = '\0';
769
- handle_attr_line(res, sp, path, ++lineno, flags);
770
- sp = ep + more;
771
- }
772
- free(buf);
773
- return res;
811
+ return read_attr_from_buf(buf, path, flags);
812
}
813
814
static struct attr_stack *read_attr(struct index_state *istate,
815
+ const struct object_id *tree_oid,
816
const char *path, unsigned flags)
817
{
818
struct attr_stack *res = NULL;
819
820
if (direction == GIT_ATTR_INDEX) {
821
res = read_attr_from_index(istate, path, flags);
822
+ } else if (tree_oid) {
823
+ res = read_attr_from_blob(istate, tree_oid, path, flags);
824
} else if (!is_bare_repository()) {
825
if (direction == GIT_ATTR_CHECKOUT) {
826
res = read_attr_from_index(istate, path, flags);
880
}
881
882
static void bootstrap_attr_stack(struct index_state *istate,
883
+ const struct object_id *tree_oid,
884
struct attr_stack **stack)
885
{
886
struct attr_stack *e;
906
}
907
908
/* root directory */
867
- e = read_attr(istate, GITATTRIBUTES_FILE, flags | READ_ATTR_NOFOLLOW);
909
+ e = read_attr(istate, tree_oid, GITATTRIBUTES_FILE, flags | READ_ATTR_NOFOLLOW);
910
push_stack(stack, e, xstrdup(""), 0);
911
912
/* info frame */
920
}
921
922
static void prepare_attr_stack(struct index_state *istate,
923
+ const struct object_id *tree_oid,
924
const char *path, int dirlen,
925
struct attr_stack **stack)
926
{
942
* .gitattributes in deeper directories to shallower ones,
943
* and finally use the built-in set as the default.
944
*/
902
- bootstrap_attr_stack(istate, stack);
945
+ bootstrap_attr_stack(istate, tree_oid, stack);
946
947
/*
948
* Pop the "info" one that is always at the top of the stack.
997
strbuf_add(&pathbuf, path + pathbuf.len, (len - pathbuf.len));
998
strbuf_addf(&pathbuf, "/%s", GITATTRIBUTES_FILE);
999
957
- next = read_attr(istate, pathbuf.buf, READ_ATTR_NOFOLLOW);
1000
+ next = read_attr(istate, tree_oid, pathbuf.buf, READ_ATTR_NOFOLLOW);
1001
1002
/* reset the pathbuf to not include "/.gitattributes" */
1003
strbuf_setlen(&pathbuf, len);
1117
* Otherwise all attributes are collected.
1118
*/
1119
static void collect_some_attrs(struct index_state *istate,
1077
- const char *path,
1078
- struct attr_check *check)
1120
+ const struct object_id *tree_oid,
1121
+ const char *path, struct attr_check *check)
1122
{
1123
int pathlen, rem, dirlen;
1124
const char *cp, *last_slash = NULL;
1137
dirlen = 0;
1138
}
1139
1097
- prepare_attr_stack(istate, path, dirlen, &check->stack);
1140
+ prepare_attr_stack(istate, tree_oid, path, dirlen, &check->stack);
1141
all_attrs_init(&g_attr_hashmap, check);
1142
determine_macros(check->all_attrs, check->stack);
1143
1146
}
1147
1148
void git_check_attr(struct index_state *istate,
1106
- const char *path,
1149
+ const struct object_id *tree_oid, const char *path,
1150
struct attr_check *check)
1151
{
1152
int i;
1153
1111
- collect_some_attrs(istate, path, check);
1154
+ collect_some_attrs(istate, tree_oid, path, check);
1155
1156
for (i = 0; i < check->nr; i++) {
1157
size_t n = check->items[i].attr->attr_nr;
1162
}
1163
}
1164
1122
-void git_all_attrs(struct index_state *istate,
1165
+void git_all_attrs(struct index_state *istate, const struct object_id *tree_oid,
1166
const char *path, struct attr_check *check)
1167
{
1168
int i;
1169
1170
attr_check_reset(check);
1128
- collect_some_attrs(istate, path, check);
1171
+ collect_some_attrs(istate, tree_oid, path, check);
1172
1173
for (i = 0; i < check->all_attrs_nr; i++) {
1174
const char *name = check->all_attrs[i].attr->name;