mirror of
https://github.com/git/git.git
synced 2024-11-27 20:14:30 +08:00
f6d8942b1f
Code which split an argv_array call across multiple lines, like: argv_array_pushl(&args, "one argument", "another argument", "and more", NULL); was recently mechanically renamed to use strvec, which results in mis-matched indentation like: strvec_pushl(&args, "one argument", "another argument", "and more", NULL); Let's fix these up to align the arguments with the opening paren. I did this manually by sifting through the results of: git jump grep 'strvec_.*,$' and liberally applying my editor's auto-format. Most of the changes are of the form shown above, though I also normalized a few that had originally used a single-tab indentation (rather than our usual style of aligning with the open paren). I also rewrapped a couple of obvious cases (e.g., where previously too-long lines became short enough to fit on one), but I wasn't aggressive about it. In cases broken to three or more lines, the grouping of arguments is sometimes meaningful, and it wasn't worth my time or reviewer time to ponder each case individually. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
153 lines
4.3 KiB
C
153 lines
4.3 KiB
C
#include "cache.h"
|
|
#include "object-store.h"
|
|
#include "run-command.h"
|
|
#include "sigchain.h"
|
|
#include "connected.h"
|
|
#include "transport.h"
|
|
#include "packfile.h"
|
|
#include "promisor-remote.h"
|
|
|
|
/*
|
|
* If we feed all the commits we want to verify to this command
|
|
*
|
|
* $ git rev-list --objects --stdin --not --all
|
|
*
|
|
* and if it does not error out, that means everything reachable from
|
|
* these commits locally exists and is connected to our existing refs.
|
|
* Note that this does _not_ validate the individual objects.
|
|
*
|
|
* Returns 0 if everything is connected, non-zero otherwise.
|
|
*/
|
|
int check_connected(oid_iterate_fn fn, void *cb_data,
|
|
struct check_connected_options *opt)
|
|
{
|
|
struct child_process rev_list = CHILD_PROCESS_INIT;
|
|
struct check_connected_options defaults = CHECK_CONNECTED_INIT;
|
|
char commit[GIT_MAX_HEXSZ + 1];
|
|
struct object_id oid;
|
|
int err = 0;
|
|
struct packed_git *new_pack = NULL;
|
|
struct transport *transport;
|
|
size_t base_len;
|
|
const unsigned hexsz = the_hash_algo->hexsz;
|
|
|
|
if (!opt)
|
|
opt = &defaults;
|
|
transport = opt->transport;
|
|
|
|
if (fn(cb_data, &oid)) {
|
|
if (opt->err_fd)
|
|
close(opt->err_fd);
|
|
return err;
|
|
}
|
|
|
|
if (transport && transport->smart_options &&
|
|
transport->smart_options->self_contained_and_connected &&
|
|
transport->pack_lockfiles.nr == 1 &&
|
|
strip_suffix(transport->pack_lockfiles.items[0].string,
|
|
".keep", &base_len)) {
|
|
struct strbuf idx_file = STRBUF_INIT;
|
|
strbuf_add(&idx_file, transport->pack_lockfiles.items[0].string,
|
|
base_len);
|
|
strbuf_addstr(&idx_file, ".idx");
|
|
new_pack = add_packed_git(idx_file.buf, idx_file.len, 1);
|
|
strbuf_release(&idx_file);
|
|
}
|
|
|
|
if (has_promisor_remote()) {
|
|
/*
|
|
* For partial clones, we don't want to have to do a regular
|
|
* connectivity check because we have to enumerate and exclude
|
|
* all promisor objects (slow), and then the connectivity check
|
|
* itself becomes a no-op because in a partial clone every
|
|
* object is a promisor object. Instead, just make sure we
|
|
* received, in a promisor packfile, the objects pointed to by
|
|
* each wanted ref.
|
|
*
|
|
* Before checking for promisor packs, be sure we have the
|
|
* latest pack-files loaded into memory.
|
|
*/
|
|
reprepare_packed_git(the_repository);
|
|
do {
|
|
struct packed_git *p;
|
|
|
|
for (p = get_all_packs(the_repository); p; p = p->next) {
|
|
if (!p->pack_promisor)
|
|
continue;
|
|
if (find_pack_entry_one(oid.hash, p))
|
|
goto promisor_pack_found;
|
|
}
|
|
/*
|
|
* Fallback to rev-list with oid and the rest of the
|
|
* object IDs provided by fn.
|
|
*/
|
|
goto no_promisor_pack_found;
|
|
promisor_pack_found:
|
|
;
|
|
} while (!fn(cb_data, &oid));
|
|
return 0;
|
|
}
|
|
|
|
no_promisor_pack_found:
|
|
if (opt->shallow_file) {
|
|
strvec_push(&rev_list.args, "--shallow-file");
|
|
strvec_push(&rev_list.args, opt->shallow_file);
|
|
}
|
|
strvec_push(&rev_list.args,"rev-list");
|
|
strvec_push(&rev_list.args, "--objects");
|
|
strvec_push(&rev_list.args, "--stdin");
|
|
if (has_promisor_remote())
|
|
strvec_push(&rev_list.args, "--exclude-promisor-objects");
|
|
if (!opt->is_deepening_fetch) {
|
|
strvec_push(&rev_list.args, "--not");
|
|
strvec_push(&rev_list.args, "--all");
|
|
}
|
|
strvec_push(&rev_list.args, "--quiet");
|
|
strvec_push(&rev_list.args, "--alternate-refs");
|
|
if (opt->progress)
|
|
strvec_pushf(&rev_list.args, "--progress=%s",
|
|
_("Checking connectivity"));
|
|
|
|
rev_list.git_cmd = 1;
|
|
rev_list.env = opt->env;
|
|
rev_list.in = -1;
|
|
rev_list.no_stdout = 1;
|
|
if (opt->err_fd)
|
|
rev_list.err = opt->err_fd;
|
|
else
|
|
rev_list.no_stderr = opt->quiet;
|
|
|
|
if (start_command(&rev_list))
|
|
return error(_("Could not run 'git rev-list'"));
|
|
|
|
sigchain_push(SIGPIPE, SIG_IGN);
|
|
|
|
commit[hexsz] = '\n';
|
|
do {
|
|
/*
|
|
* If index-pack already checked that:
|
|
* - there are no dangling pointers in the new pack
|
|
* - the pack is self contained
|
|
* Then if the updated ref is in the new pack, then we
|
|
* are sure the ref is good and not sending it to
|
|
* rev-list for verification.
|
|
*/
|
|
if (new_pack && find_pack_entry_one(oid.hash, new_pack))
|
|
continue;
|
|
|
|
memcpy(commit, oid_to_hex(&oid), hexsz);
|
|
if (write_in_full(rev_list.in, commit, hexsz + 1) < 0) {
|
|
if (errno != EPIPE && errno != EINVAL)
|
|
error_errno(_("failed write to rev-list"));
|
|
err = -1;
|
|
break;
|
|
}
|
|
} while (!fn(cb_data, &oid));
|
|
|
|
if (close(rev_list.in))
|
|
err = error_errno(_("failed to close rev-list's stdin"));
|
|
|
|
sigchain_pop(SIGPIPE);
|
|
return finish_command(&rev_list) || err;
|
|
}
|