Skip to content

Touch up symlink .gitattributes support #2091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -2388,28 +2388,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 @@ -2429,7 +2433,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