Skip to content

Commit 438ec45

Browse files
committed
Introduce helper to create symlinks that knows about index_state
On Windows, symbolic links actually have a type depending on the target: it can be a file or a directory. In certain circumstances, this poses problems, e.g. when a symbolic link is supposed to point into a submodule that is not checked out, so there is no way for Git to auto-detect the type. To help with that, we will add support over the course of the next commits to specify that symlink type via the Git attributes. This requires an index_state, though, something that Git for Windows' `symlink()` replacement cannot know about because the function signature is defined by the POSIX standard and not ours to change. So let's introduce a helper function to create symbolic links that *does* know about the index_state. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 0dc581d commit 438ec45

File tree

9 files changed

+20
-9
lines changed

9 files changed

+20
-9
lines changed

apply.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4394,7 +4394,7 @@ static int try_create_file(struct apply_state *state, const char *path,
43944394
/* Although buf:size is counted string, it also is NUL
43954395
* terminated.
43964396
*/
4397-
return !!symlink(buf, path);
4397+
return !!create_symlink(state && state->repo ? state->repo->index : NULL, buf, path);
43984398

43994399
fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);
44004400
if (fd < 0)

builtin/difftool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
524524
}
525525
add_path(&wtdir, wtdir_len, dst_path);
526526
if (symlinks) {
527-
if (symlink(wtdir.buf, rdir.buf)) {
527+
if (create_symlink(lstate.istate, wtdir.buf, rdir.buf)) {
528528
ret = error_errno("could not symlink '%s' to '%s'", wtdir.buf, rdir.buf);
529529
goto finish;
530530
}

compat/mingw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2925,7 +2925,7 @@ int link(const char *oldpath, const char *newpath)
29252925
return 0;
29262926
}
29272927

2928-
int symlink(const char *target, const char *link)
2928+
int mingw_create_symlink(struct index_state *index, const char *target, const char *link)
29292929
{
29302930
wchar_t wtarget[MAX_LONG_PATH], wlink[MAX_LONG_PATH];
29312931
int len;

compat/mingw.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,10 @@ int setitimer(int type, struct itimerval *in, struct itimerval *out);
218218
int sigaction(int sig, struct sigaction *in, struct sigaction *out);
219219
int link(const char *oldpath, const char *newpath);
220220
int uname(struct utsname *buf);
221-
int symlink(const char *target, const char *link);
222221
int readlink(const char *path, char *buf, size_t bufsiz);
222+
struct index_state;
223+
int mingw_create_symlink(struct index_state *index, const char *target, const char *link);
224+
#define create_symlink mingw_create_symlink
223225

224226
/*
225227
* replacements of existing functions

entry.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ static int write_entry(struct cache_entry *ce, char *path, struct conv_attrs *ca
313313
if (!has_symlinks || to_tempfile)
314314
goto write_file_entry;
315315

316-
ret = symlink(new_blob, path);
316+
ret = create_symlink(state->istate, new_blob, path);
317317
free(new_blob);
318318
if (ret)
319319
return error_errno("unable to create symlink %s", path);

git-compat-util.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,15 @@ static inline int git_has_dir_sep(const char *path)
595595
#define is_mount_point is_mount_point_via_stat
596596
#endif
597597

598+
#ifndef create_symlink
599+
struct index_state;
600+
static inline int git_create_symlink(struct index_state *index, const char *target, const char *link)
601+
{
602+
return symlink(target, link);
603+
}
604+
#define create_symlink git_create_symlink
605+
#endif
606+
598607
#ifndef query_user_email
599608
#define query_user_email() NULL
600609
#endif

merge-recursive.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,7 @@ static int update_file_flags(struct merge_options *opt,
10031003
char *lnk = xmemdupz(buf, size);
10041004
safe_create_leading_directories_const(path);
10051005
unlink(path);
1006-
if (symlink(lnk, path))
1006+
if (create_symlink(&opt->priv->orig_index, lnk, path))
10071007
ret = err(opt, _("failed to symlink '%s': %s"),
10081008
path, strerror(errno));
10091009
free(lnk);

refs/files-backend.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1890,7 +1890,7 @@ static int create_ref_symlink(struct ref_lock *lock, const char *target)
18901890
#ifndef NO_SYMLINK_HEAD
18911891
char *ref_path = get_locked_file_path(&lock->lk);
18921892
unlink(ref_path);
1893-
ret = symlink(target, ref_path);
1893+
ret = create_symlink(NULL, target, ref_path);
18941894
free(ref_path);
18951895

18961896
if (ret)

setup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,
17851785
if (strbuf_readlink(&lnk, template_path->buf,
17861786
st_template.st_size) < 0)
17871787
die_errno(_("cannot readlink '%s'"), template_path->buf);
1788-
if (symlink(lnk.buf, path->buf))
1788+
if (create_symlink(NULL, lnk.buf, path->buf))
17891789
die_errno(_("cannot symlink '%s' '%s'"),
17901790
lnk.buf, path->buf);
17911791
strbuf_release(&lnk);
@@ -2036,7 +2036,7 @@ static int create_default_files(const char *template_path,
20362036
path = git_path_buf(&buf, "tXXXXXX");
20372037
if (!close(xmkstemp(path)) &&
20382038
!unlink(path) &&
2039-
!symlink("testing", path) &&
2039+
!create_symlink(NULL, "testing", path) &&
20402040
!lstat(path, &st1) &&
20412041
S_ISLNK(st1.st_mode))
20422042
unlink(path); /* good */

0 commit comments

Comments
 (0)