summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-05-15 14:52:12 -0700
committerRussell Belfer <rb@github.com>2013-05-15 14:52:12 -0700
commit55d3a39098bfc513b12ad6cb56658cb2f87e6a91 (patch)
tree5461ad730b177853cf430045d58bf49539069e6f
parent79ef3be449c9d81dd0b37a30999563aa92e4679e (diff)
downloadlibgit2-55d3a39098bfc513b12ad6cb56658cb2f87e6a91.tar.gz
Remove old symlinks before updating
Unlike blob updates, symlink updates cannot be done "in place" writing over an old symlink. This means that in checkout when we realize that we can safely update a symlink, we still need to remove the old one before writing the new.
-rw-r--r--src/checkout.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/checkout.c b/src/checkout.c
index 68028dfef..4d019dbd1 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -189,6 +189,10 @@ static int checkout_action_common(
action = (action & ~CHECKOUT_ACTION__UPDATE_BLOB) |
CHECKOUT_ACTION__UPDATE_SUBMODULE;
+ /* to "update" a symlink, we must remove the old one first */
+ if (delta->new_file.mode == GIT_FILEMODE_LINK && wd != NULL)
+ action |= CHECKOUT_ACTION__REMOVE;
+
notify = GIT_CHECKOUT_NOTIFY_UPDATED;
}
@@ -764,20 +768,24 @@ cleanup:
}
static int blob_content_to_link(
- struct stat *st, git_blob *blob, const char *path, mode_t dir_mode, int can_symlink)
+ struct stat *st,
+ git_blob *blob,
+ const char *path,
+ mode_t dir_mode,
+ int can_symlink)
{
git_buf linktarget = GIT_BUF_INIT;
int error;
if ((error = git_futils_mkpath2file(path, dir_mode)) < 0)
return error;
-
+
if ((error = git_blob__getbuf(&linktarget, blob)) < 0)
return error;
if (can_symlink) {
if ((error = p_symlink(git_buf_cstr(&linktarget), path)) < 0)
- giterr_set(GITERR_CHECKOUT, "Could not create symlink %s\n", path);
+ giterr_set(GITERR_OS, "Could not create symlink %s\n", path);
} else {
error = git_futils_fake_symlink(git_buf_cstr(&linktarget), path);
}