Skip to content
Permalink
Browse files

Merge pull request #2091 from dscho/symlink-attr-extra

Touch up symlink .gitattributes support
  • Loading branch information...
dscho committed Feb 26, 2019
2 parents f6431eb + 74e71f1 commit 2481c4cbe949856f270a3ee80c802f5dd89381aa
Showing with 31 additions and 16 deletions.
  1. +1 −1 apply.c
  2. +1 −1 builtin/difftool.c
  3. +2 −2 builtin/init-db.c
  4. +12 −8 compat/mingw.c
  5. +3 −1 compat/mingw.h
  6. +1 −1 entry.c
  7. +9 −0 git-compat-util.h
  8. +1 −1 merge-recursive.c
  9. +1 −1 refs/files-backend.c
@@ -4346,7 +4346,7 @@ static int try_create_file(struct apply_state *state, const char *path,
/* Although buf:size is counted string, it also is NUL
* terminated.
*/
return !!symlink(buf, path);
return !!create_symlink(state && state->repo ? state->repo->index : NULL, buf, path);

fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);
if (fd < 0)
@@ -505,7 +505,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
}
add_path(&wtdir, wtdir_len, dst_path);
if (symlinks) {
if (symlink(wtdir.buf, rdir.buf)) {
if (create_symlink(lstate.istate, wtdir.buf, rdir.buf)) {
ret = error_errno("could not symlink '%s' to '%s'", wtdir.buf, rdir.buf);
goto finish;
}
@@ -76,7 +76,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,
if (strbuf_readlink(&lnk, template_path->buf,
st_template.st_size) < 0)
die_errno(_("cannot readlink '%s'"), template_path->buf);
if (symlink(lnk.buf, path->buf))
if (create_symlink(NULL, lnk.buf, path->buf))
die_errno(_("cannot symlink '%s' '%s'"),
lnk.buf, path->buf);
strbuf_release(&lnk);
@@ -278,7 +278,7 @@ static int create_default_files(const char *template_path,
path = git_path_buf(&buf, "tXXXXXX");
if (!close(xmkstemp(path)) &&
!unlink(path) &&
!symlink("testing", path) &&
!create_symlink(NULL, "testing", path) &&
!lstat(path, &st1) &&
S_ISLNK(st1.st_mode))
unlink(path); /* good */
@@ -2573,28 +2573,32 @@ enum symlink_type {
SYMLINK_TYPE_DIRECTORY,
};

static enum symlink_type check_symlink_attr(const char *link)
static enum symlink_type check_symlink_attr(struct index_state *index, const char *link)
{
static struct attr_check *check;
const char *value;

if (!index)
return SYMLINK_TYPE_UNSPECIFIED;

if (!check)
check = attr_check_initl("symlink", NULL);

git_check_attr(the_repository->index, link, check);
git_check_attr(index, link, check);

value = check->items[0].value;
if (value == NULL)
;
else if (!strcmp(value, "file"))
if (ATTR_UNSET(value))
return SYMLINK_TYPE_UNSPECIFIED;
if (!strcmp(value, "file"))
return SYMLINK_TYPE_FILE;
else if (!strcmp(value, "dir"))
if (!strcmp(value, "dir") || !strcmp(value, "directory"))
return SYMLINK_TYPE_DIRECTORY;

warning(_("ignoring invalid symlink type '%s' for '%s'"), value, link);
return SYMLINK_TYPE_UNSPECIFIED;
}

int symlink(const char *target, const char *link)
int mingw_create_symlink(struct index_state *index, const char *target, const char *link)
{
wchar_t wtarget[MAX_LONG_PATH], wlink[MAX_LONG_PATH];
int len;
@@ -2614,7 +2618,7 @@ int symlink(const char *target, const char *link)
if (wtarget[len] == '/')
wtarget[len] = '\\';

switch (check_symlink_attr(link)) {
switch (check_symlink_attr(index, link)) {
case SYMLINK_TYPE_UNSPECIFIED:
/* Create a phantom symlink: it is initially created as a file
* symlink, but may change to a directory symlink later if/when
@@ -214,8 +214,10 @@ int setitimer(int type, struct itimerval *in, struct itimerval *out);
int sigaction(int sig, struct sigaction *in, struct sigaction *out);
int link(const char *oldpath, const char *newpath);
int uname(struct utsname *buf);
int symlink(const char *target, const char *link);
int readlink(const char *path, char *buf, size_t bufsiz);
struct index_state;
int mingw_create_symlink(struct index_state *index, const char *target, const char *link);
#define create_symlink mingw_create_symlink

/*
* replacements of existing functions
@@ -289,7 +289,7 @@ static int write_entry(struct cache_entry *ce,
if (!has_symlinks || to_tempfile)
goto write_file_entry;

ret = symlink(new_blob, path);
ret = create_symlink(state ? state->istate : NULL, new_blob, path);
free(new_blob);
if (ret)
return error_errno("unable to create symlink %s", path);
@@ -405,6 +405,15 @@ static inline char *git_find_last_dir_sep(const char *path)
#define find_last_dir_sep git_find_last_dir_sep
#endif

#ifndef create_symlink
struct index_state;
static inline int git_create_symlink(struct index_state *index, const char *target, const char *link)
{
return symlink(target, link);
}
#define create_symlink git_create_symlink
#endif

#ifndef query_user_email
#define query_user_email() NULL
#endif
@@ -1011,7 +1011,7 @@ static int update_file_flags(struct merge_options *o,
char *lnk = xmemdupz(buf, size);
safe_create_leading_directories_const(path);
unlink(path);
if (symlink(lnk, path))
if (create_symlink(&o->orig_index, lnk, path))
ret = err(o, _("failed to symlink '%s': %s"),
path, strerror(errno));
free(lnk);
@@ -1786,7 +1786,7 @@ static int create_ref_symlink(struct ref_lock *lock, const char *target)
#ifndef NO_SYMLINK_HEAD
char *ref_path = get_locked_file_path(&lock->lk);
unlink(ref_path);
ret = symlink(target, ref_path);
ret = create_symlink(NULL, target, ref_path);
free(ref_path);

if (ret)

0 comments on commit 2481c4c

Please sign in to comment.
You can’t perform that action at this time.