bool find_head_msg() { printf("+ finding last message on HEAD\n"); if ((cmd_pipe = popen("git log -n 1 --pretty=\"format:%s%n%n%b\"", "r")) == NULL) return false; int poz = 0; while (poz < 16384 - 1 && EOF != (head_message[poz++] = fgetc(cmd_pipe))); head_message[poz - 1] = '\0'; pclose(cmd_pipe); if (int head_rev = get_rev(head_message)) { if (!allow_replace) { printf("Last commit on HEAD is " GIT_REV_FORMAT ". Use -r to replace it with " GIT_REV_FORMAT ".\n", head_rev, rev); return false; } // skip the rev number in the commit char* p = strchr(head_message, ']'), *q = head_message; assert(p && *(p + 1)); p += 2; while (*p) *q = *p, p++, q++; *q = 0; return true; } return true; }
int main() { t_glist *lst; t_glist *clone; t_glist *rev; /* t_elem elem; */ /* srand(time(0)); */ /* elem.id = rand() % 10; */ lst = init_list(); printf("[+] Init list...\n"); put_elements(lst, 10); show_list_content(lst); printf("[+] Sorting...\n"); sort_list(lst, data_cmp); show_list_content(lst); printf("[+] Sorting opposite...\n"); sort_list(lst, data_cmp_opp); show_list_content(lst); printf("[+] Will clone list...\n"); clone = clone_list(lst); show_list_content(clone); printf("[+] Will rev list...\n"); rev = get_rev(lst); show_list_content(rev); printf("[+] Will rm last elem from clone...\n"); rm_last(clone); show_list_content(clone); printf("[+] Will rm first elem from clone...\n"); rm_first(clone); show_list_content(clone); printf("[+] Will show list from end to start...\n"); end_to_start(clone); return (0x0); }
bool find_rev() { printf("+ finding next revision number\n"); // find the highest rev number on either of the remotes for (int i = 0; i < NUM_REMOTES; i++) { if (!local && !origins[i][0]) continue; if (local) snprintf(cmd, MAX_CMD, "git log HEAD --pretty=\"format:%%s\""); else sprintf(cmd, "git log %s/%s --pretty=\"format:%%s\"", origins[i], remote_branch); if ((cmd_pipe = popen(cmd, "r")) == NULL) continue; int nr; while (fgets(buffer, MAX_BUF, cmd_pipe)) { nr = get_rev(buffer); if (nr >= rev) rev = nr + 1; } pclose(cmd_pipe); } if (rev > 0) printf("Found " GIT_REV_FORMAT ".\n", rev); return rev > 0; }
bool find_rev() { printf("+ finding next revision number\n"); // find the highest rev number on either of the remotes for(int i = 0; i < NUM_REMOTES; i++) { if(!local && !origins[i][0]) continue; char cmd[512]; if(local) sprintf(cmd, "git log HEAD --pretty=\"format:%%s\""); else sprintf(cmd, "git log %s/master --pretty=\"format:%%s\"", origins[i]); if( (cmd_pipe = popen( cmd, "r" )) == NULL ) continue; int nr; while(fgets(buffer, 256, cmd_pipe)) { nr = get_rev(buffer); if(nr >= rev) rev = nr+1; } pclose(cmd_pipe); } if(rev > 0) printf("Found [%d].\n", rev); return rev > 0; }
bool find_rev() { // find the highest rev number on either of the remotes for (int i = 0; i < NUM_REMOTES; i++) { if (!origins[i][0]) continue; sprintf(cmd, "git log %s/%s --pretty=\"format:%%s\"", origins[i], remote_branch); if ((cmd_pipe = popen(cmd, "r")) == NULL) continue; int nr; while (fgets(buffer, MAX_BUF, cmd_pipe)) { nr = get_rev(buffer); if (nr >= rev) rev = nr + 1; } pclose(cmd_pipe); } return rev > 0; }
static int add_haves(struct strbuf *req_buf, int *haves_to_send, int *in_vain) { int ret = 0; int haves_added = 0; const struct object_id *oid; while ((oid = get_rev())) { packet_buf_write(req_buf, "have %s\n", oid_to_hex(oid)); if (++haves_added >= *haves_to_send) break; } *in_vain += haves_added; if (!haves_added || *in_vain >= MAX_IN_VAIN) { /* Send Done */ packet_buf_write(req_buf, "done\n"); ret = 1; } /* Increase haves to send on next round */ *haves_to_send = next_flush(1, *haves_to_send); return ret; }
static int find_common(struct fetch_pack_args *args, int fd[2], unsigned char *result_sha1, struct ref *refs) { int fetching; int count = 0, flushes = 0, flush_at = INITIAL_FLUSH, retval; const unsigned char *sha1; unsigned in_vain = 0; int got_continue = 0; int got_ready = 0; struct strbuf req_buf = STRBUF_INIT; size_t state_len = 0; if (args->stateless_rpc && multi_ack == 1) die("--stateless-rpc requires multi_ack_detailed"); if (marked) for_each_ref(clear_marks, NULL); marked = 1; for_each_ref(rev_list_insert_ref, NULL); for_each_alternate_ref(insert_one_alternate_ref, NULL); fetching = 0; for ( ; refs ; refs = refs->next) { unsigned char *remote = refs->old_sha1; const char *remote_hex; struct object *o; /* * If that object is complete (i.e. it is an ancestor of a * local ref), we tell them we have it but do not have to * tell them about its ancestors, which they already know * about. * * We use lookup_object here because we are only * interested in the case we *know* the object is * reachable and we have already scanned it. */ if (((o = lookup_object(remote)) != NULL) && (o->flags & COMPLETE)) { continue; } remote_hex = sha1_to_hex(remote); if (!fetching) { struct strbuf c = STRBUF_INIT; if (multi_ack == 2) strbuf_addstr(&c, " multi_ack_detailed"); if (multi_ack == 1) strbuf_addstr(&c, " multi_ack"); if (no_done) strbuf_addstr(&c, " no-done"); if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k"); if (use_sideband == 1) strbuf_addstr(&c, " side-band"); if (args->use_thin_pack) strbuf_addstr(&c, " thin-pack"); if (args->no_progress) strbuf_addstr(&c, " no-progress"); if (args->include_tag) strbuf_addstr(&c, " include-tag"); if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta"); if (agent_supported) strbuf_addf(&c, " agent=%s", git_user_agent_sanitized()); packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf); strbuf_release(&c); } else packet_buf_write(&req_buf, "want %s\n", remote_hex); fetching++; } if (!fetching) { strbuf_release(&req_buf); packet_flush(fd[1]); return 1; } if (is_repository_shallow()) write_shallow_commits(&req_buf, 1, NULL); if (args->depth > 0) packet_buf_write(&req_buf, "deepen %d", args->depth); packet_buf_flush(&req_buf); state_len = req_buf.len; if (args->depth > 0) { char *line; const char *arg; unsigned char sha1[20]; send_request(args, fd[1], &req_buf); while ((line = packet_read_line(fd[0], NULL))) { if (skip_prefix(line, "shallow ", &arg)) { if (get_sha1_hex(arg, sha1)) die("invalid shallow line: %s", line); register_shallow(sha1); continue; } if (skip_prefix(line, "unshallow ", &arg)) { if (get_sha1_hex(arg, sha1)) die("invalid unshallow line: %s", line); if (!lookup_object(sha1)) die("object not found: %s", line); /* make sure that it is parsed as shallow */ if (!parse_object(sha1)) die("error in object: %s", line); if (unregister_shallow(sha1)) die("no shallow found: %s", line); continue; } die("expected shallow/unshallow, got %s", line); } } else if (!args->stateless_rpc) send_request(args, fd[1], &req_buf); if (!args->stateless_rpc) { /* If we aren't using the stateless-rpc interface * we don't need to retain the headers. */ strbuf_setlen(&req_buf, 0); state_len = 0; } flushes = 0; retval = -1; while ((sha1 = get_rev())) { packet_buf_write(&req_buf, "have %s\n", sha1_to_hex(sha1)); if (args->verbose) fprintf(stderr, "have %s\n", sha1_to_hex(sha1)); in_vain++; if (flush_at <= ++count) { int ack; packet_buf_flush(&req_buf); send_request(args, fd[1], &req_buf); strbuf_setlen(&req_buf, state_len); flushes++; flush_at = next_flush(args, count); /* * We keep one window "ahead" of the other side, and * will wait for an ACK only on the next one */ if (!args->stateless_rpc && count == INITIAL_FLUSH) continue; consume_shallow_list(args, fd[0]); do { ack = get_ack(fd[0], result_sha1); if (args->verbose && ack) fprintf(stderr, "got ack %d %s\n", ack, sha1_to_hex(result_sha1)); switch (ack) { case ACK: flushes = 0; multi_ack = 0; retval = 0; goto done; case ACK_common: case ACK_ready: case ACK_continue: { struct commit *commit = lookup_commit(result_sha1); if (!commit) die("invalid commit %s", sha1_to_hex(result_sha1)); if (args->stateless_rpc && ack == ACK_common && !(commit->object.flags & COMMON)) { /* We need to replay the have for this object * on the next RPC request so the peer knows * it is in common with us. */ const char *hex = sha1_to_hex(result_sha1); packet_buf_write(&req_buf, "have %s\n", hex); state_len = req_buf.len; } mark_common(commit, 0, 1); retval = 0; in_vain = 0; got_continue = 1; if (ack == ACK_ready) { clear_prio_queue(&rev_list); got_ready = 1; } break; } } } while (ack); flushes--; if (got_continue && MAX_IN_VAIN < in_vain) { if (args->verbose) fprintf(stderr, "giving up\n"); break; /* give up */ } } } done: if (!got_ready || !no_done) { packet_buf_write(&req_buf, "done\n"); send_request(args, fd[1], &req_buf); } if (args->verbose) fprintf(stderr, "done\n"); if (retval != 0) { multi_ack = 0; flushes++; } strbuf_release(&req_buf); if (!got_ready || !no_done) consume_shallow_list(args, fd[0]); while (flushes || multi_ack) { int ack = get_ack(fd[0], result_sha1); if (ack) { if (args->verbose) fprintf(stderr, "got ack (%d) %s\n", ack, sha1_to_hex(result_sha1)); if (ack == ACK) return 0; multi_ack = 1; continue; } flushes--; } /* it is no error to fetch into a completely empty repo */ return count ? retval : 0; }
static int find_common(int fd[2], unsigned char *result_sha1, struct ref *refs) { int fetching; int count = 0, flushes = 0, retval; const unsigned char *sha1; unsigned in_vain = 0; int got_continue = 0; if (marked) for_each_ref(clear_marks, NULL); marked = 1; for_each_ref(rev_list_insert_ref, NULL); fetching = 0; for ( ; refs ; refs = refs->next) { unsigned char *remote = refs->old_sha1; struct object *o; /* * If that object is complete (i.e. it is an ancestor of a * local ref), we tell them we have it but do not have to * tell them about its ancestors, which they already know * about. * * We use lookup_object here because we are only * interested in the case we *know* the object is * reachable and we have already scanned it. */ if (((o = lookup_object(remote)) != NULL) && (o->flags & COMPLETE)) { continue; } if (!fetching) packet_write(fd[1], "want %s%s%s%s%s%s%s%s\n", sha1_to_hex(remote), (multi_ack ? " multi_ack" : ""), (use_sideband == 2 ? " side-band-64k" : ""), (use_sideband == 1 ? " side-band" : ""), (args.use_thin_pack ? " thin-pack" : ""), (args.no_progress ? " no-progress" : ""), (args.include_tag ? " include-tag" : ""), " ofs-delta"); else packet_write(fd[1], "want %s\n", sha1_to_hex(remote)); fetching++; } if (is_repository_shallow()) write_shallow_commits(fd[1], 1); if (args.depth > 0) packet_write(fd[1], "deepen %d", args.depth); packet_flush(fd[1]); if (!fetching) return 1; if (args.depth > 0) { char line[1024]; unsigned char sha1[20]; while (packet_read_line(fd[0], line, sizeof(line))) { if (!prefixcmp(line, "shallow ")) { if (get_sha1_hex(line + 8, sha1)) die("invalid shallow line: %s", line); register_shallow(sha1); continue; } if (!prefixcmp(line, "unshallow ")) { if (get_sha1_hex(line + 10, sha1)) die("invalid unshallow line: %s", line); if (!lookup_object(sha1)) die("object not found: %s", line); /* make sure that it is parsed as shallow */ if (!parse_object(sha1)) die("error in object: %s", line); if (unregister_shallow(sha1)) die("no shallow found: %s", line); continue; } die("expected shallow/unshallow, got %s", line); } } flushes = 0; retval = -1; while ((sha1 = get_rev())) { packet_write(fd[1], "have %s\n", sha1_to_hex(sha1)); if (args.verbose) fprintf(stderr, "have %s\n", sha1_to_hex(sha1)); in_vain++; if (!(31 & ++count)) { int ack; packet_flush(fd[1]); flushes++; /* * We keep one window "ahead" of the other side, and * will wait for an ACK only on the next one */ if (count == 32) continue; do { ack = get_ack(fd[0], result_sha1); if (args.verbose && ack) fprintf(stderr, "got ack %d %s\n", ack, sha1_to_hex(result_sha1)); if (ack == 1) { flushes = 0; multi_ack = 0; retval = 0; goto done; } else if (ack == 2) { struct commit *commit = lookup_commit(result_sha1); mark_common(commit, 0, 1); retval = 0; in_vain = 0; got_continue = 1; } } while (ack); flushes--; if (got_continue && MAX_IN_VAIN < in_vain) { if (args.verbose) fprintf(stderr, "giving up\n"); break; /* give up */ } } } done: packet_write(fd[1], "done\n"); if (args.verbose) fprintf(stderr, "done\n"); if (retval != 0) { multi_ack = 0; flushes++; } while (flushes || multi_ack) { int ack = get_ack(fd[0], result_sha1); if (ack) { if (args.verbose) fprintf(stderr, "got ack (%d) %s\n", ack, sha1_to_hex(result_sha1)); if (ack == 1) return 0; multi_ack = 1; continue; } flushes--; } /* it is no error to fetch into a completely empty repo */ return count ? retval : 0; }