summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2015-03-31 16:28:13 -0400
committerEdward Thomson <ethomson@edwardthomson.com>2015-05-04 07:18:27 -0500
commit05f690122e9927eece61afb17c1595a136d119b2 (patch)
tree40bb725acb3d51e816dd57583182431425182fad /src
parent3520c97057a2e4236779d24ec6fece0d11514319 (diff)
downloadlibgit2-05f690122e9927eece61afb17c1595a136d119b2.tar.gz
checkout: remove blocking dir when FORCEd
Diffstat (limited to 'src')
-rw-r--r--src/checkout.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/src/checkout.c b/src/checkout.c
index b70ea1892..dd10732b5 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -409,6 +409,14 @@ static bool submodule_is_config_only(
return rval;
}
+static bool checkout_is_empty_dir(checkout_data *data, const char *path)
+{
+ git_buf_truncate(&data->path, data->workdir_len);
+ if (git_buf_puts(&data->path, path) < 0)
+ return false;
+ return git_path_is_empty_dir(data->path.ptr);
+}
+
static int checkout_action_with_wd(
int *action,
checkout_data *data,
@@ -526,6 +534,7 @@ static int checkout_action_with_wd_dir(
checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, NULL));
GITERR_CHECK_ERROR(
checkout_notify(data, GIT_CHECKOUT_NOTIFY_UNTRACKED, NULL, wd));
+ *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, NONE);
break;
case GIT_DELTA_ADDED:/* case 4 (and 7 for dir) */
case GIT_DELTA_MODIFIED: /* case 20 (or 37 but not really) */
@@ -550,8 +559,6 @@ static int checkout_action_with_wd_dir(
* dir and it will succeed if no children are left.
*/
*action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
- if (*action != CHECKOUT_ACTION__NONE)
- *action |= CHECKOUT_ACTION__DEFER_REMOVE;
}
else if (delta->new_file.mode != GIT_FILEMODE_TREE)
/* For typechange to dir, dir is already created so no action */
@@ -564,6 +571,20 @@ static int checkout_action_with_wd_dir(
return checkout_action_common(action, data, delta, wd);
}
+static int checkout_action_with_wd_dir_empty(
+ int *action,
+ checkout_data *data,
+ const git_diff_delta *delta)
+{
+ int error = checkout_action_no_wd(action, data, delta);
+
+ /* We can always safely remove an empty directory. */
+ if (error == 0 && *action != CHECKOUT_ACTION__NONE)
+ *action |= CHECKOUT_ACTION__REMOVE;
+
+ return error;
+}
+
static int checkout_action(
int *action,
checkout_data *data,
@@ -653,7 +674,9 @@ static int checkout_action(
}
}
- return checkout_action_with_wd_dir(action, data, delta, workdir, wd);
+ return checkout_is_empty_dir(data, wd->path) ?
+ checkout_action_with_wd_dir_empty(action, data, delta) :
+ checkout_action_with_wd_dir(action, data, delta, workdir, wd);
}
/* case 6 - wd is after delta */