diff --git a/archive.c b/archive.c
index 1944ed4..2870f04 100644
--- a/archive.c
+++ b/archive.c
@@ -124,7 +124,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
path_without_prefix = path.buf + args->baselen;
setup_archive_check(check);
- if (!git_checkattr(path_without_prefix, ARRAY_SIZE(check), check)) {
+ if (!git_checkattr(path_without_prefix, ARRAY_SIZE(check), check, mode)) {
if (ATTR_TRUE(check[0].value))
return 0;
convert = ATTR_TRUE(check[1].value);diff --git a/attr.c b/attr.c
index 6aff695..c4481ac 100644
--- a/attr.c
+++ b/attr.c
@@ -708,7 +708,7 @@ static int macroexpand_one(int attr_nr, int rem)
return rem;
}
-int git_checkattr(const char *path, int num, struct git_attr_check *check)
+int git_checkattr(const char *path, int num, struct git_attr_check *check, unsigned short mode)
{
struct attr_stack *stk;
const char *cp;@@ -718,6 +718,9 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
for (i = 0; i < attr_nr; i++)
check_all_attr[i].value = ATTR__UNKNOWN;
+ if (S_ISLNK(mode))
+ path = prefix_filename("symlink:", strlen("symlink:"), path);
+ /* else if (IS_WHATEVER(mode)) do_what_you_feel_like */
pathlen = strlen(path);
cp = strrchr(path, '/');
if (!cp)diff --git a/attr.h b/attr.h
index 8b3f19b..1af0bd4 100644
--- a/attr.h
+++ b/attr.h
@@ -29,7 +29,7 @@ struct git_attr_check {
const char *value;
};
-int git_checkattr(const char *path, int, struct git_attr_check *);
+int git_checkattr(const char *path, int, struct git_attr_check *, unsigned short mode);
enum git_attr_direction {
GIT_ATTR_CHECKIN,diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 3016d29..30be2c2 100644
--- a/builtin/check-attr.c
+++ b/builtin/check-attr.c
@@ -24,7 +24,12 @@ static void check_attr(int cnt, struct git_attr_check *check,
const char** name, const char *file)
{
int j;
- if (git_checkattr(file, cnt, check))
+ unsigned int mode = 0;
+ struct stat st;
+
+ if (!lstat(file, &st))
+ mode = st.st_mode;
+ if (git_checkattr(file, cnt, check, mode))
die("git_checkattr died");
for (j = 0; j < cnt; j++) {
const char *value = check[j].value;diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index b0503b2..4e9ff68 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -633,7 +633,7 @@ static int no_try_delta(const char *path)
struct git_attr_check check[1];
setup_delta_attr_check(check);
- if (git_checkattr(path, ARRAY_SIZE(check), check))
+ if (git_checkattr(path, ARRAY_SIZE(check), check, 0))
return 0;
if (ATTR_FALSE(check->value))
return 1;
diff --git a/convert.c b/convert.c
index d5aebed..d5c2b9c 100644
--- a/convert.c
+++ b/convert.c
@@ -736,7 +736,7 @@ int convert_to_git(const char *path, const char *src, size_t len,
const char *filter = NULL;
setup_convert_check(check);
- if (!git_checkattr(path, ARRAY_SIZE(check), check)) {
+ if (!git_checkattr(path, ARRAY_SIZE(check), check, 0)) {
struct convert_driver *drv;
action = git_path_check_crlf(path, check + 4);
if (action == CRLF_GUESS)@@ -773,7 +773,7 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
const char *filter = NULL;
setup_convert_check(check);
- if (!git_checkattr(path, ARRAY_SIZE(check), check)) {
+ if (!git_checkattr(path, ARRAY_SIZE(check), check, 0)) {
struct convert_driver *drv;
action = git_path_check_crlf(path, check + 4);
if (action == CRLF_GUESS)diff --git a/diff.c b/diff.c
index 6640857..22b5d94 100644
--- a/diff.c
+++ b/diff.c
@@ -1784,8 +1784,7 @@ static void diff_filespec_load_driver(struct diff_filespec *one)
if (one->driver)
return;
- if (S_ISREG(one->mode))
- one->driver = userdiff_find_by_path(one->path);
+ one->driver = userdiff_find_by_path(one->path, one->mode);
/* Fallback to default settings */
if (!one->driver)
@@ -2683,7 +2682,7 @@ static void run_diff_cmd(const char *pgm,
if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL))
pgm = NULL;
else {
- struct userdiff_driver *drv = userdiff_find_by_path(attr_path);
+ struct userdiff_driver *drv = userdiff_find_by_path(attr_path, two->mode);
if (drv && drv->external)
pgm = drv->external;
}diff --git a/grep.c b/grep.c
index 63c4280..05a77fc 100644
--- a/grep.c
+++ b/grep.c
@@ -877,7 +877,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
memset(&xecfg, 0, sizeof(xecfg));
if (opt->funcname && !opt->unmatch_name_only && !opt->status_only &&
!opt->name_only && !binary_match_only && !collect_hits) {
- struct userdiff_driver *drv = userdiff_find_by_path(name);
+ struct userdiff_driver *drv = userdiff_find_by_path(name, 0);
if (drv && drv->funcname.pattern) {
const struct userdiff_funcname *pe = &drv->funcname;
xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);diff --git a/ll-merge.c b/ll-merge.c
index 6ce512e..3f351e3 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -330,7 +330,7 @@ static int git_path_check_merge(const char *path, struct git_attr_check check[2]
check[0].attr = git_attr("merge");
check[1].attr = git_attr("conflict-marker-size");
}
- return git_checkattr(path, 2, check);
+ return git_checkattr(path, 2, check, 0);
}
static void normalize_file(mmfile_t *mm, const char *path)@@ -387,7 +387,7 @@ int ll_merge_marker_size(const char *path)
if (!check.attr)
check.attr = git_attr("conflict-marker-size");
- if (!git_checkattr(path, 1, &check) && check.value) {
+ if (!git_checkattr(path, 1, &check, 0) && check.value) {
marker_size = atoi(check.value);
if (marker_size <= 0)
marker_size = DEFAULT_CONFLICT_MARKER_SIZE;diff --git a/userdiff.c b/userdiff.c
index 1ff4797..e5d0adf 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -245,7 +245,7 @@ struct userdiff_driver *userdiff_find_by_name(const char *name) {
return userdiff_find_by_namelen(name, len);
}
-struct userdiff_driver *userdiff_find_by_path(const char *path)
+struct userdiff_driver *userdiff_find_by_path(const char *path, unsigned short mode)
{
static struct git_attr *attr;
struct git_attr_check check;@@ -256,7 +256,7 @@ struct userdiff_driver *userdiff_find_by_path(const char *path)
if (!path)
return NULL;
- if (git_checkattr(path, 1, &check))
+ if (git_checkattr(path, 1, &check, mode))
return NULL;
if (ATTR_TRUE(check.value))
diff --git a/userdiff.h b/userdiff.h
index 942d594..e516f1d 100644
--- a/userdiff.h
+++ b/userdiff.h
@@ -21,6 +21,6 @@ struct userdiff_driver {
int userdiff_config(const char *k, const char *v);
struct userdiff_driver *userdiff_find_by_name(const char *name);
-struct userdiff_driver *userdiff_find_by_path(const char *path);
+struct userdiff_driver *userdiff_find_by_path(const char *path, unsigned short mode);
#endif /* USERDIFF */diff --git a/ws.c b/ws.c
index 9fb9b14..51929d3 100644
--- a/ws.c
+++ b/ws.c
@@ -88,7 +88,7 @@ unsigned whitespace_rule(const char *pathname)
struct git_attr_check attr_whitespace_rule;
setup_whitespace_attr_check(&attr_whitespace_rule);
- if (!git_checkattr(pathname, 1, &attr_whitespace_rule)) {
+ if (!git_checkattr(pathname, 1, &attr_whitespace_rule, 0)) {
const char *value;
value = attr_whitespace_rule.value;--
1.7.4.1.257.gb09fa