Skip to content

Commit 54e4040

Browse files
dschoGit for Windows Build Agent
authored andcommitted
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 c71f322 commit 54e4040

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
@@ -4341,7 +4341,7 @@ static int try_create_file(struct apply_state *state, const char *path,
43414341
/* Although buf:size is counted string, it also is NUL
43424342
* terminated.
43434343
*/
4344-
return !!symlink(buf, path);
4344+
return !!create_symlink(state && state->repo ? state->repo->index : NULL, buf, path);
43454345

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

builtin/difftool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
505505
}
506506
add_path(&wtdir, wtdir_len, dst_path);
507507
if (symlinks) {
508-
if (symlink(wtdir.buf, rdir.buf)) {
508+
if (create_symlink(lstate.istate, wtdir.buf, rdir.buf)) {
509509
ret = error_errno("could not symlink '%s' to '%s'", wtdir.buf, rdir.buf);
510510
goto finish;
511511
}

builtin/init-db.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,
7676
if (strbuf_readlink(&lnk, template_path->buf,
7777
st_template.st_size) < 0)
7878
die_errno(_("cannot readlink '%s'"), template_path->buf);
79-
if (symlink(lnk.buf, path->buf))
79+
if (create_symlink(NULL, lnk.buf, path->buf))
8080
die_errno(_("cannot symlink '%s' '%s'"),
8181
lnk.buf, path->buf);
8282
strbuf_release(&lnk);
@@ -280,7 +280,7 @@ static int create_default_files(const char *template_path,
280280
path = git_path_buf(&buf, "tXXXXXX");
281281
if (!close(xmkstemp(path)) &&
282282
!unlink(path) &&
283-
!symlink("testing", path) &&
283+
!create_symlink(NULL, "testing", path) &&
284284
!lstat(path, &st1) &&
285285
S_ISLNK(st1.st_mode))
286286
unlink(path); /* good */

compat/mingw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2710,7 +2710,7 @@ int link(const char *oldpath, const char *newpath)
27102710
return 0;
27112711
}
27122712

2713-
int symlink(const char *target, const char *link)
2713+
int mingw_create_symlink(struct index_state *index, const char *target, const char *link)
27142714
{
27152715
wchar_t wtarget[MAX_LONG_PATH], wlink[MAX_LONG_PATH];
27162716
int len;

compat/mingw.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,10 @@ int setitimer(int type, struct itimerval *in, struct itimerval *out);
213213
int sigaction(int sig, struct sigaction *in, struct sigaction *out);
214214
int link(const char *oldpath, const char *newpath);
215215
int uname(struct utsname *buf);
216-
int symlink(const char *target, const char *link);
217216
int readlink(const char *path, char *buf, size_t bufsiz);
217+
struct index_state;
218+
int mingw_create_symlink(struct index_state *index, const char *target, const char *link);
219+
#define create_symlink mingw_create_symlink
218220

219221
/*
220222
* replacements of existing functions

entry.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ static int write_entry(struct cache_entry *ce,
289289
if (!has_symlinks || to_tempfile)
290290
goto write_file_entry;
291291

292-
ret = symlink(new_blob, path);
292+
ret = create_symlink(state->istate, new_blob, path);
293293
free(new_blob);
294294
if (ret)
295295
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
@@ -395,6 +395,15 @@ static inline char *git_find_last_dir_sep(const char *path)
395395
#define is_mount_point is_mount_point_via_stat
396396
#endif
397397

398+
#ifndef create_symlink
399+
struct index_state;
400+
static inline int git_create_symlink(struct index_state *index, const char *target, const char *link)
401+
{
402+
return symlink(target, link);
403+
}
404+
#define create_symlink git_create_symlink
405+
#endif
406+
398407
#ifndef query_user_email
399408
#define query_user_email() NULL
400409
#endif

merge-recursive.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ static int update_file_flags(struct merge_options *opt,
986986
char *lnk = xmemdupz(buf, size);
987987
safe_create_leading_directories_const(path);
988988
unlink(path);
989-
if (symlink(lnk, path))
989+
if (create_symlink(&opt->priv->orig_index, lnk, path))
990990
ret = err(opt, _("failed to symlink '%s': %s"),
991991
path, strerror(errno));
992992
free(lnk);

refs/files-backend.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1792,7 +1792,7 @@ static int create_ref_symlink(struct ref_lock *lock, const char *target)
17921792
#ifndef NO_SYMLINK_HEAD
17931793
char *ref_path = get_locked_file_path(&lock->lk);
17941794
unlink(ref_path);
1795-
ret = symlink(target, ref_path);
1795+
ret = create_symlink(NULL, target, ref_path);
17961796
free(ref_path);
17971797

17981798
if (ret)

0 commit comments

Comments
 (0)