summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-01-02 17:05:54 -0800
committerRussell Belfer <rb@github.com>2013-01-04 15:47:43 -0800
commit16a666d3d421fcbffabc861646b02e22c63d9ad9 (patch)
treea5194000f851043fc1f0e7f1441808531ec57c7c /src
parent546d65a8dae8a7af7288163a580c08c827ebda1d (diff)
downloadlibgit2-16a666d3d421fcbffabc861646b02e22c63d9ad9.tar.gz
Fix workdir notifications and removals
The notifications were broken from the various iterations over this code and were not returning working dir item data correctly. Also, workdir items that were alphabetically after the last item in diff were not being processed.
Diffstat (limited to 'src')
-rw-r--r--src/checkout.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/src/checkout.c b/src/checkout.c
index 76119c6e9..962250e4e 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -209,9 +209,9 @@ static int checkout_notify(
checkout_data *data,
git_checkout_notify_t why,
const git_diff_delta *delta,
- const git_index_entry *baseitem)
+ const git_index_entry *wditem)
{
- git_diff_file basefile;
+ git_diff_file wdfile;
const git_diff_file *baseline = NULL, *target = NULL, *workdir = NULL;
if (!data->opts.notify_cb)
@@ -220,44 +220,41 @@ static int checkout_notify(
if ((why & data->opts.notify_flags) == 0)
return 0;
- if (baseitem) {
- memset(&basefile, 0, sizeof(basefile));
+ if (wditem) {
+ memset(&wdfile, 0, sizeof(wdfile));
- git_oid_cpy(&basefile.oid, &baseitem->oid);
- basefile.path = baseitem->path;
- basefile.size = baseitem->file_size;
- basefile.flags = GIT_DIFF_FILE_VALID_OID;
- basefile.mode = baseitem->mode;
+ git_oid_cpy(&wdfile.oid, &wditem->oid);
+ wdfile.path = wditem->path;
+ wdfile.size = wditem->file_size;
+ wdfile.flags = GIT_DIFF_FILE_VALID_OID;
+ wdfile.mode = wditem->mode;
- baseline = &basefile;
+ workdir = &wdfile;
}
- if ((why & GIT_CHECKOUT__NOTIFY_CONFLICT_TREE) != 0) {
- /* baseitem is a blob that conflicts with a tree in the workdir */
- } else {
+ if (delta) {
switch (delta->status) {
case GIT_DELTA_UNMODIFIED:
case GIT_DELTA_MODIFIED:
case GIT_DELTA_TYPECHANGE:
default:
- target = &delta->old_file;
- workdir = &delta->new_file;
+ baseline = &delta->old_file;
+ target = &delta->new_file;
break;
case GIT_DELTA_ADDED:
case GIT_DELTA_IGNORED:
case GIT_DELTA_UNTRACKED:
- workdir = &delta->new_file;
+ target = &delta->new_file;
break;
case GIT_DELTA_DELETED:
- target = &delta->old_file;
+ baseline = &delta->old_file;
break;
}
}
return data->opts.notify_cb(
- why, delta->old_file.path,
- baseline, target, workdir,
- data->opts.notify_payload);
+ why, delta ? delta->old_file.path : wditem->path,
+ baseline, target, workdir, data->opts.notify_payload);
}
static bool checkout_is_workdir_modified(
@@ -653,6 +650,14 @@ static int checkout_get_actions(
counts[CHECKOUT_ACTION__CONFLICT]++;
}
+ while (wditem != NULL) {
+ error = checkout_action_wd_only(data, workdir, wditem, &pathspec);
+ if (!error)
+ error = git_iterator_advance(workdir, &wditem);
+ if (error < 0)
+ goto fail;
+ }
+
counts[CHECKOUT_ACTION__REMOVE] += data->removes.length;
if (counts[CHECKOUT_ACTION__CONFLICT] > 0 &&