Merge branch 'ls/filter-process-delayed'
Bugfixes to an already graduated series. * ls/filter-process-delayed: write_entry: untangle symlink and regular-file cases write_entry: avoid reading blobs in CE_RETRY case write_entry: fix leak when retrying delayed filter entry.c: check if file exists after checkout entry.c: update cache entry only for existing filesmaint
commit
6909bf6bd9
90
entry.c
90
entry.c
|
@ -253,6 +253,7 @@ static int write_entry(struct cache_entry *ce,
|
||||||
char *path, const struct checkout *state, int to_tempfile)
|
char *path, const struct checkout *state, int to_tempfile)
|
||||||
{
|
{
|
||||||
unsigned int ce_mode_s_ifmt = ce->ce_mode & S_IFMT;
|
unsigned int ce_mode_s_ifmt = ce->ce_mode & S_IFMT;
|
||||||
|
struct delayed_checkout *dco = state->delayed_checkout;
|
||||||
int fd, ret, fstat_done = 0;
|
int fd, ret, fstat_done = 0;
|
||||||
char *new;
|
char *new;
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
@ -273,55 +274,65 @@ static int write_entry(struct cache_entry *ce,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ce_mode_s_ifmt) {
|
switch (ce_mode_s_ifmt) {
|
||||||
case S_IFREG:
|
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
new = read_blob_entry(ce, &size);
|
new = read_blob_entry(ce, &size);
|
||||||
if (!new)
|
if (!new)
|
||||||
return error("unable to read sha1 file of %s (%s)",
|
return error("unable to read sha1 file of %s (%s)",
|
||||||
path, oid_to_hex(&ce->oid));
|
path, oid_to_hex(&ce->oid));
|
||||||
|
|
||||||
if (ce_mode_s_ifmt == S_IFLNK && has_symlinks && !to_tempfile) {
|
/*
|
||||||
ret = symlink(new, path);
|
* We can't make a real symlink; write out a regular file entry
|
||||||
free(new);
|
* with the symlink destination as its contents.
|
||||||
if (ret)
|
*/
|
||||||
return error_errno("unable to create symlink %s",
|
if (!has_symlinks || to_tempfile)
|
||||||
path);
|
goto write_file_entry;
|
||||||
break;
|
|
||||||
|
ret = symlink(new, path);
|
||||||
|
free(new);
|
||||||
|
if (ret)
|
||||||
|
return error_errno("unable to create symlink %s", path);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_IFREG:
|
||||||
|
/*
|
||||||
|
* We do not send the blob in case of a retry, so do not
|
||||||
|
* bother reading it at all.
|
||||||
|
*/
|
||||||
|
if (dco && dco->state == CE_RETRY) {
|
||||||
|
new = NULL;
|
||||||
|
size = 0;
|
||||||
|
} else {
|
||||||
|
new = read_blob_entry(ce, &size);
|
||||||
|
if (!new)
|
||||||
|
return error("unable to read sha1 file of %s (%s)",
|
||||||
|
path, oid_to_hex(&ce->oid));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert from git internal format to working tree format
|
* Convert from git internal format to working tree format
|
||||||
*/
|
*/
|
||||||
if (ce_mode_s_ifmt == S_IFREG) {
|
if (dco && dco->state != CE_NO_DELAY) {
|
||||||
struct delayed_checkout *dco = state->delayed_checkout;
|
ret = async_convert_to_working_tree(ce->name, new,
|
||||||
if (dco && dco->state != CE_NO_DELAY) {
|
size, &buf, dco);
|
||||||
/* Do not send the blob in case of a retry. */
|
if (ret && string_list_has_string(&dco->paths, ce->name)) {
|
||||||
if (dco->state == CE_RETRY) {
|
|
||||||
new = NULL;
|
|
||||||
size = 0;
|
|
||||||
}
|
|
||||||
ret = async_convert_to_working_tree(
|
|
||||||
ce->name, new, size, &buf, dco);
|
|
||||||
if (ret && string_list_has_string(&dco->paths, ce->name)) {
|
|
||||||
free(new);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
ret = convert_to_working_tree(
|
|
||||||
ce->name, new, size, &buf);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
free(new);
|
free(new);
|
||||||
new = strbuf_detach(&buf, &newsize);
|
goto delayed;
|
||||||
size = newsize;
|
|
||||||
}
|
}
|
||||||
/*
|
} else
|
||||||
* No "else" here as errors from convert are OK at this
|
ret = convert_to_working_tree(ce->name, new, size, &buf);
|
||||||
* point. If the error would have been fatal (e.g.
|
|
||||||
* filter is required), then we would have died already.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
free(new);
|
||||||
|
new = strbuf_detach(&buf, &newsize);
|
||||||
|
size = newsize;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* No "else" here as errors from convert are OK at this
|
||||||
|
* point. If the error would have been fatal (e.g.
|
||||||
|
* filter is required), then we would have died already.
|
||||||
|
*/
|
||||||
|
|
||||||
|
write_file_entry:
|
||||||
fd = open_output_fd(path, ce, to_tempfile);
|
fd = open_output_fd(path, ce, to_tempfile);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
free(new);
|
free(new);
|
||||||
|
@ -336,6 +347,7 @@ static int write_entry(struct cache_entry *ce,
|
||||||
if (wrote < 0)
|
if (wrote < 0)
|
||||||
return error("unable to write file %s", path);
|
return error("unable to write file %s", path);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_IFGITLINK:
|
case S_IFGITLINK:
|
||||||
if (to_tempfile)
|
if (to_tempfile)
|
||||||
return error("cannot create temporary submodule %s", path);
|
return error("cannot create temporary submodule %s", path);
|
||||||
|
@ -347,6 +359,7 @@ static int write_entry(struct cache_entry *ce,
|
||||||
NULL, oid_to_hex(&ce->oid),
|
NULL, oid_to_hex(&ce->oid),
|
||||||
state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
|
state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return error("unknown file mode for %s in index", path);
|
return error("unknown file mode for %s in index", path);
|
||||||
}
|
}
|
||||||
|
@ -355,11 +368,14 @@ finish:
|
||||||
if (state->refresh_cache) {
|
if (state->refresh_cache) {
|
||||||
assert(state->istate);
|
assert(state->istate);
|
||||||
if (!fstat_done)
|
if (!fstat_done)
|
||||||
lstat(ce->name, &st);
|
if (lstat(ce->name, &st) < 0)
|
||||||
|
return error_errno("unable to stat just-written file %s",
|
||||||
|
ce->name);
|
||||||
fill_stat_cache_info(ce, &st);
|
fill_stat_cache_info(ce, &st);
|
||||||
ce->ce_flags |= CE_UPDATE_IN_BASE;
|
ce->ce_flags |= CE_UPDATE_IN_BASE;
|
||||||
state->istate->cache_changed |= CE_ENTRY_CHANGED;
|
state->istate->cache_changed |= CE_ENTRY_CHANGED;
|
||||||
}
|
}
|
||||||
|
delayed:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue