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.
This commit is contained in:
Russell Belfer 2013-01-02 17:05:54 -08:00
parent 546d65a8da
commit 16a666d3d4

View File

@ -209,9 +209,9 @@ static int checkout_notify(
checkout_data *data, checkout_data *data,
git_checkout_notify_t why, git_checkout_notify_t why,
const git_diff_delta *delta, 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; const git_diff_file *baseline = NULL, *target = NULL, *workdir = NULL;
if (!data->opts.notify_cb) if (!data->opts.notify_cb)
@ -220,44 +220,41 @@ static int checkout_notify(
if ((why & data->opts.notify_flags) == 0) if ((why & data->opts.notify_flags) == 0)
return 0; return 0;
if (baseitem) { if (wditem) {
memset(&basefile, 0, sizeof(basefile)); memset(&wdfile, 0, sizeof(wdfile));
git_oid_cpy(&basefile.oid, &baseitem->oid); git_oid_cpy(&wdfile.oid, &wditem->oid);
basefile.path = baseitem->path; wdfile.path = wditem->path;
basefile.size = baseitem->file_size; wdfile.size = wditem->file_size;
basefile.flags = GIT_DIFF_FILE_VALID_OID; wdfile.flags = GIT_DIFF_FILE_VALID_OID;
basefile.mode = baseitem->mode; wdfile.mode = wditem->mode;
baseline = &basefile; workdir = &wdfile;
} }
if ((why & GIT_CHECKOUT__NOTIFY_CONFLICT_TREE) != 0) { if (delta) {
/* baseitem is a blob that conflicts with a tree in the workdir */
} else {
switch (delta->status) { switch (delta->status) {
case GIT_DELTA_UNMODIFIED: case GIT_DELTA_UNMODIFIED:
case GIT_DELTA_MODIFIED: case GIT_DELTA_MODIFIED:
case GIT_DELTA_TYPECHANGE: case GIT_DELTA_TYPECHANGE:
default: default:
target = &delta->old_file; baseline = &delta->old_file;
workdir = &delta->new_file; target = &delta->new_file;
break; break;
case GIT_DELTA_ADDED: case GIT_DELTA_ADDED:
case GIT_DELTA_IGNORED: case GIT_DELTA_IGNORED:
case GIT_DELTA_UNTRACKED: case GIT_DELTA_UNTRACKED:
workdir = &delta->new_file; target = &delta->new_file;
break; break;
case GIT_DELTA_DELETED: case GIT_DELTA_DELETED:
target = &delta->old_file; baseline = &delta->old_file;
break; break;
} }
} }
return data->opts.notify_cb( return data->opts.notify_cb(
why, delta->old_file.path, why, delta ? delta->old_file.path : wditem->path,
baseline, target, workdir, baseline, target, workdir, data->opts.notify_payload);
data->opts.notify_payload);
} }
static bool checkout_is_workdir_modified( static bool checkout_is_workdir_modified(
@ -653,6 +650,14 @@ static int checkout_get_actions(
counts[CHECKOUT_ACTION__CONFLICT]++; 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; counts[CHECKOUT_ACTION__REMOVE] += data->removes.length;
if (counts[CHECKOUT_ACTION__CONFLICT] > 0 && if (counts[CHECKOUT_ACTION__CONFLICT] > 0 &&