diff options
author | Junio C Hamano <gitster@pobox.com> | 2011-05-31 10:57:32 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2011-05-31 10:57:32 -0700 |
commit | 2d11f21c365821ccba1e093f22b99ad71b955f21 (patch) | |
tree | 1ecbe232f12904520838ab4adff6aa70d5ba6e80 /entry.c | |
parent | 28b9264dd6cbadcef8b3e48c24ffcb2893b668b3 (diff) | |
parent | 5b42477b59886a85d4b49a60313f9b9d4a0d576f (diff) | |
download | git-2d11f21c365821ccba1e093f22b99ad71b955f21.tar.gz |
Merge remote-tracking branch 'ko/maint' into jc/diff-index-quick-exit-early
* ko/maint: (4352 commits)
git-submodule.sh: separate parens by a space to avoid confusing some shells
Documentation/technical/api-diff.txt: correct name of diff_unmerge()
read_gitfile_gently: use ssize_t to hold read result
remove tests of always-false condition
rerere.c: diagnose a corrupt MERGE_RR when hitting EOF between TAB and '\0'
Git 1.7.5.3
init/clone: remove short option -L and document --separate-git-dir
do not read beyond end of malloc'd buffer
git-svn: Fix git svn log --show-commit
Git 1.7.5.2
provide a copy of the LGPLv2.1
test core.gitproxy configuration
copy_gecos: fix not adding nlen to len when processing "&"
Update draft release notes to 1.7.5.2
Documentation/git-fsck.txt: fix typo: unreadable -> unreachable
send-pack: avoid deadlock on git:// push with failed pack-objects
connect: let callers know if connection is a socket
connect: treat generic proxy processes like ssh processes
sideband_demux(): fix decl-after-stmt
t3503: test cherry picking and reverting root commits
...
Conflicts:
diff.c
Diffstat (limited to 'entry.c')
-rw-r--r-- | entry.c | 37 |
1 files changed, 27 insertions, 10 deletions
@@ -106,14 +106,14 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout case S_IFLNK: new = read_blob_entry(ce, &size); if (!new) - return error("git checkout-index: unable to read sha1 file of %s (%s)", + return error("unable to read sha1 file of %s (%s)", path, sha1_to_hex(ce->sha1)); if (ce_mode_s_ifmt == S_IFLNK && has_symlinks && !to_tempfile) { ret = symlink(new, path); free(new); if (ret) - return error("git checkout-index: unable to create symlink %s (%s)", + return error("unable to create symlink %s (%s)", path, strerror(errno)); break; } @@ -141,7 +141,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout } if (fd < 0) { free(new); - return error("git checkout-index: unable to create file %s (%s)", + return error("unable to create file %s (%s)", path, strerror(errno)); } @@ -155,16 +155,16 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout close(fd); free(new); if (wrote != size) - return error("git checkout-index: unable to write file %s", path); + return error("unable to write file %s", path); break; case S_IFGITLINK: if (to_tempfile) - return error("git checkout-index: cannot create temporary subproject %s", path); + return error("cannot create temporary subproject %s", path); if (mkdir(path, 0777) < 0) - return error("git checkout-index: cannot create subproject directory %s", path); + return error("cannot create subproject directory %s", path); break; default: - return error("git checkout-index: unknown file mode for %s", path); + return error("unknown file mode for %s in index", path); } if (state->refresh_cache) { @@ -175,6 +175,23 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout return 0; } +/* + * This is like 'lstat()', except it refuses to follow symlinks + * in the path, after skipping "skiplen". + */ +static int check_path(const char *path, int len, struct stat *st, int skiplen) +{ + const char *slash = path + len; + + while (path < slash && *slash != '/') + slash--; + if (!has_dirs_only_path(path, slash - path, skiplen)) { + errno = ENOENT; + return -1; + } + return lstat(path, st); +} + int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath) { static char path[PATH_MAX + 1]; @@ -188,13 +205,13 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t strcpy(path + len, ce->name); len += ce_namelen(ce); - if (!lstat(path, &st)) { - unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID); + if (!check_path(path, len, &st, state->base_dir_len)) { + unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE); if (!changed) return 0; if (!state->force) { if (!state->quiet) - fprintf(stderr, "git-checkout-index: %s already exists\n", path); + fprintf(stderr, "%s already exists, no checkout\n", path); return -1; } |