Skip to content

Commit

Permalink
Merge pull request #2091 from dscho/symlink-attr-extra
Browse files Browse the repository at this point in the history
Touch up symlink .gitattributes support
  • Loading branch information
dscho committed Feb 26, 2019
2 parents f6431eb + 74e71f1 commit 2481c4c
Show file tree
Hide file tree
Showing 9 changed files with 31 additions and 16 deletions.
2 changes: 1 addition & 1 deletion apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion builtin/difftool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions builtin/init-db.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
Expand Down
20 changes: 12 additions & 8 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion compat/mingw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 9 additions & 0 deletions git-compat-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion merge-recursive.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion refs/files-backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 2481c4c

Please sign in to comment.