summaryrefslogtreecommitdiff
path: root/src/checkout.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2019-07-11 15:30:51 +0200
committerPatrick Steinhardt <ps@pks.im>2019-07-20 19:11:20 +0200
commit6be5ac2351d7ff2589e3a9c7ee3fefc99da48500 (patch)
tree32a720db4e5fde9adc5ed75930441b09ac386b8e /src/checkout.c
parent50194dcda14a515bc3bbddee68c4092ca778d4dd (diff)
downloadlibgit2-6be5ac2351d7ff2589e3a9c7ee3fefc99da48500.tar.gz
checkout: postpone creation of symlinks to the end
On most platforms it's fine to create symlinks to nonexisting files. Not so on Windows, where the type of a symlink (file or directory) needs to be set at creation time. So depending on whether the target file exists or not, we may end up with different symlink types. This creates a problem when performing checkouts, where we simply iterate over all blobs that need to be updated without treating symlinks any special. If the target file of the symlink is going to be checked out after the symlink itself, then the symlink will be created as directory symlink and not as file symlink. Fix the issue by iterating over blobs twice: once to perform postponed deletions and updates to non-symlink blobs, and once to perform updates to symlink blobs.
Diffstat (limited to 'src/checkout.c')
-rw-r--r--src/checkout.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/checkout.c b/src/checkout.c
index 730ec626e..d618e3dfa 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -1893,11 +1893,18 @@ static int checkout_create_the_new(
return error;
}
- if (actions[i] & CHECKOUT_ACTION__UPDATE_BLOB) {
- error = checkout_blob(data, &delta->new_file);
- if (error < 0)
+ if (actions[i] & CHECKOUT_ACTION__UPDATE_BLOB && !S_ISLNK(delta->new_file.mode)) {
+ if ((error = checkout_blob(data, &delta->new_file)) < 0)
return error;
+ data->completed_steps++;
+ report_progress(data, delta->new_file.path);
+ }
+ }
+ git_vector_foreach(&data->diff->deltas, i, delta) {
+ if (actions[i] & CHECKOUT_ACTION__UPDATE_BLOB && S_ISLNK(delta->new_file.mode)) {
+ if ((error = checkout_blob(data, &delta->new_file)) < 0)
+ return error;
data->completed_steps++;
report_progress(data, delta->new_file.path);
}