]>
Commit | Line | Data |
---|---|---|
f96400cb JH |
1 | #include "cache.h" |
2 | #include "run-command.h" | |
3 | #include "sigchain.h" | |
4 | #include "connected.h" | |
5 | ||
6 | /* | |
7 | * If we feed all the commits we want to verify to this command | |
8 | * | |
9 | * $ git rev-list --verify-objects --stdin --not --all | |
10 | * | |
11 | * and if it does not error out, that means everything reachable from | |
12 | * these commits locally exists and is connected to some of our | |
13 | * existing refs. | |
14 | * | |
15 | * Returns 0 if everything is connected, non-zero otherwise. | |
16 | */ | |
17 | int check_everything_connected(sha1_iterate_fn fn, int quiet, void *cb_data) | |
18 | { | |
19 | struct child_process rev_list; | |
20 | const char *argv[] = {"rev-list", "--verify-objects", | |
21 | "--stdin", "--not", "--all", NULL, NULL}; | |
22 | char commit[41]; | |
23 | unsigned char sha1[20]; | |
24 | int err = 0; | |
25 | ||
26 | if (fn(cb_data, sha1)) | |
27 | return err; | |
28 | ||
29 | if (quiet) | |
30 | argv[5] = "--quiet"; | |
31 | ||
32 | memset(&rev_list, 0, sizeof(rev_list)); | |
33 | rev_list.argv = argv; | |
34 | rev_list.git_cmd = 1; | |
35 | rev_list.in = -1; | |
36 | rev_list.no_stdout = 1; | |
37 | rev_list.no_stderr = quiet; | |
38 | if (start_command(&rev_list)) | |
39 | return error(_("Could not run 'git rev-list'")); | |
40 | ||
41 | sigchain_push(SIGPIPE, SIG_IGN); | |
42 | ||
43 | commit[40] = '\n'; | |
44 | do { | |
45 | memcpy(commit, sha1_to_hex(sha1), 40); | |
46 | if (write_in_full(rev_list.in, commit, 41) < 0) { | |
47 | if (errno != EPIPE && errno != EINVAL) | |
48 | error(_("failed write to rev-list: %s"), | |
49 | strerror(errno)); | |
50 | err = -1; | |
51 | break; | |
52 | } | |
53 | } while (!fn(cb_data, sha1)); | |
54 | ||
55 | if (close(rev_list.in)) { | |
56 | error(_("failed to close rev-list's stdin: %s"), strerror(errno)); | |
57 | err = -1; | |
58 | } | |
59 | ||
60 | sigchain_pop(SIGPIPE); | |
61 | return finish_command(&rev_list) || err; | |
62 | } |