static int cmd_log_walk(struct rev_info *rev) { struct commit *commit; if (rev->early_output) setup_early_output(rev); if (prepare_revision_walk(rev)) die("revision walk setup failed"); if (rev->early_output) finish_early_output(rev); /* * For --check and --exit-code, the exit code is based on CHECK_FAILED * and HAS_CHANGES being accumulated in rev->diffopt, so be careful to * retain that state information if replacing rev->diffopt in this loop */ while ((commit = get_revision(rev)) != NULL) { log_tree_commit(rev, commit); if (!rev->reflog_info) { /* we allow cycles in reflog ancestry */ free(commit->buffer); commit->buffer = NULL; } free_commit_list(commit->parents); commit->parents = NULL; } if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF && DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) { return 02; } return diff_result_code(&rev->diffopt, 0); }
int find_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name, struct string_list *needs_pushing) { struct rev_info rev; struct commit *commit; const char *argv[] = {NULL, NULL, "--not", "NULL", NULL}; int argc = ARRAY_SIZE(argv) - 1; char *sha1_copy; struct strbuf remotes_arg = STRBUF_INIT; strbuf_addf(&remotes_arg, "--remotes=%s", remotes_name); init_revisions(&rev, NULL); sha1_copy = xstrdup(sha1_to_hex(new_sha1)); argv[1] = sha1_copy; argv[3] = remotes_arg.buf; setup_revisions(argc, argv, &rev, NULL); if (prepare_revision_walk(&rev)) die("revision walk setup failed"); while ((commit = get_revision(&rev)) != NULL) find_unpushed_submodule_commits(commit, needs_pushing); reset_revision_walk(); free(sha1_copy); strbuf_release(&remotes_arg); return needs_pushing->nr; }
static void do_traverse(struct rev_info *revs, show_commit_fn show_commit, show_object_fn show_object, void *show_data, filter_object_fn filter_fn, void *filter_data) { struct commit *commit; struct strbuf csp; /* callee's scratch pad */ strbuf_init(&csp, PATH_MAX); while ((commit = get_revision(revs)) != NULL) { /* * an uninteresting boundary commit may not have its tree * parsed yet, but we are not going to show them anyway */ if (commit->tree) add_pending_tree(revs, commit->tree); show_commit(commit, show_data); if (revs->tree_blobs_in_commit_order) /* * NEEDSWORK: Adding the tree and then flushing it here * needs a reallocation for each commit. Can we pass the * tree directory without allocation churn? */ traverse_trees_and_blobs(revs, &csp, show_object, show_data, filter_fn, filter_data); } traverse_trees_and_blobs(revs, &csp, show_object, show_data, filter_fn, filter_data); strbuf_release(&csp); }
static const char *find_author_by_nickname(const char *name) { struct rev_info revs; struct commit *commit; struct strbuf buf = STRBUF_INIT; struct string_list mailmap = STRING_LIST_INIT_NODUP; const char *av[20]; int ac = 0; init_revisions(&revs, NULL); strbuf_addf(&buf, "--author=%s", name); av[++ac] = "--all"; av[++ac] = "-i"; av[++ac] = buf.buf; av[++ac] = NULL; setup_revisions(ac, av, &revs, NULL); revs.mailmap = &mailmap; read_mailmap(revs.mailmap, NULL); prepare_revision_walk(&revs); commit = get_revision(&revs); if (commit) { struct pretty_print_context ctx = {0}; ctx.date_mode = DATE_NORMAL; strbuf_release(&buf); format_commit_message(commit, "%aN <%aE>", &buf, &ctx); clear_mailmap(&mailmap); return strbuf_detach(&buf, NULL); } die(_("No existing author found with '%s'"), name); }
int git_get_log_nextcommit(GIT_LOG handle, GIT_COMMIT *commit, int follow) { int ret =0; if(commit == NULL) return -1; memset(commit, 0, sizeof(GIT_COMMIT)); commit->m_pGitCommit = get_revision(handle); if( commit->m_pGitCommit == NULL) return -2; if (follow && !log_tree_commit(handle, commit->m_pGitCommit)) { commit->m_ignore = 1; return 0; } commit->m_ignore = 0; ret=git_parse_commit(commit); if(ret) return ret; return 0; }
static int revert_or_cherry_pick(int argc, const char **argv) { struct rev_info revs; git_config(git_default_config, NULL); me = action == REVERT ? "revert" : "cherry-pick"; setenv(GIT_REFLOG_ACTION, me, 0); parse_args(argc, argv); if (allow_ff) { if (signoff) die("cherry-pick --ff cannot be used with --signoff"); if (no_commit) die("cherry-pick --ff cannot be used with --no-commit"); if (no_replay) die("cherry-pick --ff cannot be used with -x"); if (edit) die("cherry-pick --ff cannot be used with --edit"); } if (read_cache() < 0) die("git %s: failed to read the index", me); prepare_revs(&revs); while ((commit = get_revision(&revs))) { int res = do_pick_commit(); if (res) return res; } return 0; }
static int cmd_log_walk(struct rev_info *rev) { struct commit *commit; if (rev->early_output) setup_early_output(rev); if (prepare_revision_walk(rev)) die("revision walk setup failed"); if (rev->early_output) finish_early_output(rev); while ((commit = get_revision(rev)) != NULL) { log_tree_commit(rev, commit); if (!rev->reflog_info) { /* we allow cycles in reflog ancestry */ free(commit->buffer); commit->buffer = NULL; } free_commit_list(commit->parents); commit->parents = NULL; } return 0; }
static void print_submodule_summary(struct rev_info *rev, FILE *f, const char *del, const char *add, const char *reset) { static const char format[] = " %m %s"; struct strbuf sb = STRBUF_INIT; struct commit *commit; while ((commit = get_revision(rev))) { struct pretty_print_context ctx = {0}; ctx.date_mode = rev->date_mode; strbuf_setlen(&sb, 0); if (commit->object.flags & SYMMETRIC_LEFT) { if (del) strbuf_addstr(&sb, del); } else if (add) strbuf_addstr(&sb, add); format_commit_message(commit, format, &sb, &ctx); if (reset) strbuf_addstr(&sb, reset); strbuf_addch(&sb, '\n'); fprintf(f, "%s", sb.buf); } strbuf_release(&sb); }
int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name) { struct rev_info rev; struct commit *commit; const char *argv[] = {NULL, NULL, "--not", "NULL", NULL}; int argc = ARRAY_SIZE(argv) - 1; char *sha1_copy; int needs_pushing = 0; struct strbuf remotes_arg = STRBUF_INIT; strbuf_addf(&remotes_arg, "--remotes=%s", remotes_name); init_revisions(&rev, NULL); sha1_copy = xstrdup(sha1_to_hex(new_sha1)); argv[1] = sha1_copy; argv[3] = remotes_arg.buf; setup_revisions(argc, argv, &rev, NULL); if (prepare_revision_walk(&rev)) die("revision walk setup failed"); while ((commit = get_revision(&rev)) && !needs_pushing) commit_need_pushing(commit, commit->parents, &needs_pushing); free(sha1_copy); strbuf_release(&remotes_arg); return needs_pushing; }
static int walk_revs_populate_todo(struct todo_list *todo_list, struct replay_opts *opts) { enum todo_command command = opts->action == REPLAY_PICK ? TODO_PICK : TODO_REVERT; const char *command_string = todo_command_strings[command]; struct commit *commit; if (prepare_revs(opts)) return -1; while ((commit = get_revision(opts->revs))) { struct todo_item *item = append_new_todo(todo_list); const char *commit_buffer = get_commit_buffer(commit, NULL); const char *subject; int subject_len; item->command = command; item->commit = commit; item->arg = NULL; item->arg_len = 0; item->offset_in_buf = todo_list->buf.len; subject_len = find_commit_subject(commit_buffer, &subject); strbuf_addf(&todo_list->buf, "%s %s %.*s\n", command_string, short_commit_name(commit), subject_len, subject); unuse_commit_buffer(commit, commit_buffer); } return 0; }
void check_for_new_submodule_commits(unsigned char new_sha1[20]) { struct rev_info rev; struct commit *commit; const char *argv[] = {NULL, NULL, "--not", "--all", NULL}; int argc = ARRAY_SIZE(argv) - 1; init_revisions(&rev, NULL); argv[1] = xstrdup(sha1_to_hex(new_sha1)); setup_revisions(argc, argv, &rev, NULL); if (prepare_revision_walk(&rev)) die("revision walk setup failed"); /* * Collect all submodules (whether checked out or not) for which new * commits have been recorded upstream in "changed_submodule_paths". */ while ((commit = get_revision(&rev))) { struct commit_list *parent = commit->parents; while (parent) { struct diff_options diff_opts; diff_setup(&diff_opts); diff_opts.output_format |= DIFF_FORMAT_CALLBACK; diff_opts.format_callback = submodule_collect_changed_cb; if (diff_setup_done(&diff_opts) < 0) die("diff_setup_done failed"); diff_tree_sha1(parent->item->object.sha1, commit->object.sha1, "", &diff_opts); diffcore_std(&diff_opts); diff_flush(&diff_opts); parent = parent->next; } } free((char *)argv[1]); }
static int find_first_merges(struct object_array *result, const char *path, struct commit *a, struct commit *b) { int i, j; struct object_array merges; struct commit *commit; int contains_another; char merged_revision[42]; const char *rev_args[] = { "rev-list", "--merges", "--ancestry-path", "--all", merged_revision, NULL }; struct rev_info revs; struct setup_revision_opt rev_opts; memset(&merges, 0, sizeof(merges)); memset(result, 0, sizeof(struct object_array)); memset(&rev_opts, 0, sizeof(rev_opts)); /* get all revisions that merge commit a */ snprintf(merged_revision, sizeof(merged_revision), "^%s", sha1_to_hex(a->object.sha1)); init_revisions(&revs, NULL); rev_opts.submodule = path; setup_revisions(sizeof(rev_args)/sizeof(char *)-1, rev_args, &revs, &rev_opts); /* save all revisions from the above list that contain b */ if (prepare_revision_walk(&revs)) die("revision walk setup failed"); while ((commit = get_revision(&revs)) != NULL) { struct object *o = &(commit->object); if (in_merge_bases(b, commit)) add_object_array(o, NULL, &merges); } reset_revision_walk(); /* Now we've got all merges that contain a and b. Prune all * merges that contain another found merge and save them in * result. */ for (i = 0; i < merges.nr; i++) { struct commit *m1 = (struct commit *) merges.objects[i].item; contains_another = 0; for (j = 0; j < merges.nr; j++) { struct commit *m2 = (struct commit *) merges.objects[j].item; if (i != j && in_merge_bases(m2, m1)) { contains_another = 1; break; } } if (!contains_another) add_object_array(merges.objects[i].item, merges.objects[i].name, result); } free(merges.objects); return result->nr; }
static void get_from_rev(struct rev_info *rev, struct shortlog *log) { struct commit *commit; if (prepare_revision_walk(rev)) die(_("revision walk setup failed")); while ((commit = get_revision(rev)) != NULL) shortlog_add_commit(log, commit); }
static void walk_revs_populate_todo(struct commit_list **todo_list, struct replay_opts *opts) { struct commit *commit; struct commit_list **next; prepare_revs(opts); next = todo_list; while ((commit = get_revision(opts->revs))) next = commit_list_append(commit, next); }
static void suggest_reattach(struct commit *commit, struct rev_info *revs) { struct commit *c, *last = NULL; struct strbuf sb = STRBUF_INIT; int lost = 0; while ((c = get_revision(revs)) != NULL) { if (lost < ORPHAN_CUTOFF) describe_one_orphan(&sb, c); last = c; lost++; } if (ORPHAN_CUTOFF < lost) { int more = lost - ORPHAN_CUTOFF; if (more == 1) describe_one_orphan(&sb, last); else strbuf_addf(&sb, _(" ... and %d more.\n"), more); } fprintf(stderr, Q_( /* The singular version */ "Warning: you are leaving %d commit behind, " "not connected to\n" "any of your branches:\n\n" "%s\n", /* The plural version */ "Warning: you are leaving %d commits behind, " "not connected to\n" "any of your branches:\n\n" "%s\n", /* Give ngettext() the count */ lost), lost, sb.buf); strbuf_release(&sb); if (advice_detached_head) fprintf(stderr, Q_( /* The singular version */ "If you want to keep it by creating a new branch, " "this may be a good time\nto do so with:\n\n" " git branch <new-branch-name> %s\n\n", /* The plural version */ "If you want to keep them by creating a new branch, " "this may be a good time\nto do so with:\n\n" " git branch <new-branch-name> %s\n\n", /* Give ngettext() the count */ lost), find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV)); }
void traverse_commit_list(struct rev_info *revs, show_commit_fn show_commit, show_object_fn show_object, void *data) { int i; struct commit *commit; struct strbuf base; strbuf_init(&base, PATH_MAX); while ((commit = get_revision(revs)) != NULL) { /* * an uninteresting boundary commit may not have its tree * parsed yet, but we are not going to show them anyway */ if (commit->tree) add_pending_tree(revs, commit->tree); show_commit(commit, data); } for (i = 0; i < revs->pending.nr; i++) { struct object_array_entry *pending = revs->pending.objects + i; struct object *obj = pending->item; const char *name = pending->name; if (obj->flags & (UNINTERESTING | SEEN)) continue; if (obj->type == OBJ_TAG) { obj->flags |= SEEN; show_object(obj, NULL, name); continue; } if (obj->type == OBJ_TREE) { process_tree(revs, (struct tree *)obj, show_object, NULL, &base, name); continue; } if (obj->type == OBJ_BLOB) { process_blob(revs, (struct blob *)obj, show_object, NULL, name); continue; } die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name); } if (revs->pending.nr) { free(revs->pending.objects); revs->pending.nr = 0; revs->pending.alloc = 0; revs->pending.objects = NULL; } strbuf_release(&base); }
void cgit_print_atom(char *tip, char *path, int max_count) { char *host; const char *argv[] = {NULL, tip, NULL, NULL, NULL}; struct commit *commit; struct rev_info rev; int argc = 2; if (!tip) argv[1] = ctx.qry.head; if (path) { argv[argc++] = "--"; argv[argc++] = path; } init_revisions(&rev, NULL); rev.abbrev = DEFAULT_ABBREV; rev.commit_format = CMIT_FMT_DEFAULT; rev.verbose_header = 1; rev.show_root_diff = 0; rev.max_count = max_count; setup_revisions(argc, argv, &rev, NULL); prepare_revision_walk(&rev); host = cgit_hosturl(); ctx.page.mimetype = "text/xml"; ctx.page.charset = "utf-8"; cgit_print_http_headers(&ctx); html("<feed xmlns='http://www.w3.org/2005/Atom'>\n"); html("<title>"); html_txt(ctx.repo->name); html("</title>\n"); html("<subtitle>"); html_txt(ctx.repo->desc); html("</subtitle>\n"); if (host) { html("<link rel='alternate' type='text/html' href='http://"); html_attr(host); html_attr(cgit_repourl(ctx.repo->url)); html("'/>\n"); } while ((commit = get_revision(&rev)) != NULL) { add_entry(commit, host); free(commit->buffer); commit->buffer = NULL; free_commit_list(commit->parents); commit->parents = NULL; } html("</feed>\n"); }
static void prepare_bases(struct base_tree_info *bases, struct commit *base, struct commit **list, int total) { struct commit *commit; struct rev_info revs; struct diff_options diffopt; int i; if (!base) return; diff_setup(&diffopt); DIFF_OPT_SET(&diffopt, RECURSIVE); diff_setup_done(&diffopt); oidcpy(&bases->base_commit, &base->object.oid); init_revisions(&revs, NULL); revs.max_parents = 1; revs.topo_order = 1; for (i = 0; i < total; i++) { list[i]->object.flags &= ~UNINTERESTING; add_pending_object(&revs, &list[i]->object, "rev_list"); list[i]->util = (void *)1; } base->object.flags |= UNINTERESTING; add_pending_object(&revs, &base->object, "base"); if (prepare_revision_walk(&revs)) die(_("revision walk setup failed")); /* * Traverse the commits list, get prerequisite patch ids * and stuff them in bases structure. */ while ((commit = get_revision(&revs)) != NULL) { unsigned char sha1[20]; struct object_id *patch_id; if (commit->util) continue; if (commit_patch_id(commit, &diffopt, sha1)) die(_("cannot get patch id")); ALLOC_GROW(bases->patch_id, bases->nr_patch_id + 1, bases->alloc_patch_id); patch_id = bases->patch_id + bases->nr_patch_id; hashcpy(patch_id->hash, sha1); bases->nr_patch_id++; } }
static int cmd_log_walk(struct rev_info *rev) { struct commit *commit; int saved_nrl = 0; int saved_dcctc = 0; if (rev->early_output) setup_early_output(rev); if (prepare_revision_walk(rev)) die(_("revision walk setup failed")); if (rev->early_output) finish_early_output(rev); /* * For --check and --exit-code, the exit code is based on CHECK_FAILED * and HAS_CHANGES being accumulated in rev->diffopt, so be careful to * retain that state information if replacing rev->diffopt in this loop */ while ((commit = get_revision(rev)) != NULL) { if (!log_tree_commit(rev, commit) && rev->max_count >= 0) /* * We decremented max_count in get_revision, * but we didn't actually show the commit. */ rev->max_count++; if (!rev->reflog_info) { /* we allow cycles in reflog ancestry */ free(commit->buffer); commit->buffer = NULL; } free_commit_list(commit->parents); commit->parents = NULL; if (saved_nrl < rev->diffopt.needed_rename_limit) saved_nrl = rev->diffopt.needed_rename_limit; if (rev->diffopt.degraded_cc_to_c) saved_dcctc = 1; } rev->diffopt.degraded_cc_to_c = saved_dcctc; rev->diffopt.needed_rename_limit = saved_nrl; if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF && DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) { return 02; } return diff_result_code(&rev->diffopt, 0); }
static void calculate_changed_submodule_paths(void) { struct rev_info rev; struct commit *commit; struct argv_array argv = ARGV_ARRAY_INIT; /* No need to check if there are no submodules configured */ if (!config_name_for_path.nr) return; init_revisions(&rev, NULL); argv_array_push(&argv, "--"); /* argv[0] program name */ sha1_array_for_each_unique(&ref_tips_after_fetch, add_sha1_to_argv, &argv); argv_array_push(&argv, "--not"); sha1_array_for_each_unique(&ref_tips_before_fetch, add_sha1_to_argv, &argv); setup_revisions(argv.argc, argv.argv, &rev, NULL); if (prepare_revision_walk(&rev)) die("revision walk setup failed"); /* * Collect all submodules (whether checked out or not) for which new * commits have been recorded upstream in "changed_submodule_paths". */ while ((commit = get_revision(&rev))) { struct commit_list *parent = commit->parents; while (parent) { struct diff_options diff_opts; diff_setup(&diff_opts); DIFF_OPT_SET(&diff_opts, RECURSIVE); diff_opts.output_format |= DIFF_FORMAT_CALLBACK; diff_opts.format_callback = submodule_collect_changed_cb; if (diff_setup_done(&diff_opts) < 0) die("diff_setup_done failed"); diff_tree_sha1(parent->item->object.sha1, commit->object.sha1, "", &diff_opts); diffcore_std(&diff_opts); diff_flush(&diff_opts); parent = parent->next; } } argv_array_clear(&argv); sha1_array_clear(&ref_tips_before_fetch); sha1_array_clear(&ref_tips_after_fetch); initialized_fetch_ref_tips = 0; }
static void squash_message(struct commit *commit, struct commit_list *remoteheads) { struct rev_info rev; struct strbuf out = STRBUF_INIT; struct commit_list *j; const char *filename; int fd; struct pretty_print_context ctx = {0}; printf(_("Squash commit -- not updating HEAD\n")); filename = git_path("SQUASH_MSG"); fd = open(filename, O_WRONLY | O_CREAT, 0666); if (fd < 0) die_errno(_("Could not write to '%s'"), filename); init_revisions(&rev, NULL); rev.ignore_merges = 1; rev.commit_format = CMIT_FMT_MEDIUM; commit->object.flags |= UNINTERESTING; add_pending_object(&rev, &commit->object, NULL); for (j = remoteheads; j; j = j->next) add_pending_object(&rev, &j->item->object, NULL); setup_revisions(0, NULL, &rev, NULL); if (prepare_revision_walk(&rev)) die(_("revision walk setup failed")); ctx.abbrev = rev.abbrev; ctx.date_mode = rev.date_mode; ctx.fmt = rev.commit_format; strbuf_addstr(&out, "Squashed commit of the following:\n"); while ((commit = get_revision(&rev)) != NULL) { strbuf_addch(&out, '\n'); strbuf_addf(&out, "commit %s\n", sha1_to_hex(commit->object.sha1)); pretty_print_commit(&ctx, commit, &out); } if (write(fd, out.buf, out.len) < 0) die_errno(_("Writing SQUASH_MSG")); if (close(fd)) die_errno(_("Finishing SQUASH_MSG")); strbuf_release(&out); }
void traverse_commit_list(struct rev_info *revs, void (*show_commit)(struct commit *), void (*show_object)(struct object_array_entry *)) { int i; struct commit *commit; struct object_array objects = { 0, 0, NULL }; while ((commit = get_revision(revs)) != NULL) { process_tree(revs, commit->tree, &objects, NULL, ""); show_commit(commit); } for (i = 0; i < revs->pending.nr; i++) { struct object_array_entry *pending = revs->pending.objects + i; struct object *obj = pending->item; const char *name = pending->name; if (obj->flags & (UNINTERESTING | SEEN)) continue; if (obj->type == OBJ_TAG) { obj->flags |= SEEN; add_object_array(obj, name, &objects); continue; } if (obj->type == OBJ_TREE) { process_tree(revs, (struct tree *)obj, &objects, NULL, name); continue; } if (obj->type == OBJ_BLOB) { process_blob(revs, (struct blob *)obj, &objects, NULL, name); continue; } die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name); } for (i = 0; i < objects.nr; i++) show_object(&objects.objects[i]); free(objects.objects); if (revs->pending.nr) { free(revs->pending.objects); revs->pending.nr = 0; revs->pending.alloc = 0; revs->pending.objects = NULL; } }
static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const char *prefix) { struct rev_info check_rev; struct commit *commit; struct object *o1, *o2; unsigned flags1, flags2; if (rev->pending.nr != 2) die("Need exactly one range."); o1 = rev->pending.objects[0].item; flags1 = o1->flags; o2 = rev->pending.objects[1].item; flags2 = o2->flags; if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING)) die("Not a range."); init_patch_ids(ids); /* given a range a..b get all patch ids for b..a */ init_revisions(&check_rev, prefix); o1->flags ^= UNINTERESTING; o2->flags ^= UNINTERESTING; add_pending_object(&check_rev, o1, "o1"); add_pending_object(&check_rev, o2, "o2"); if (prepare_revision_walk(&check_rev)) die("revision walk setup failed"); while ((commit = get_revision(&check_rev)) != NULL) { /* ignore merges */ if (commit->parents && commit->parents->next) continue; add_commit_patch_id(commit, ids); } /* reset for next revision walk */ clear_commit_marks((struct commit *)o1, SEEN | UNINTERESTING | SHOWN | ADDED); clear_commit_marks((struct commit *)o2, SEEN | UNINTERESTING | SHOWN | ADDED); o1->flags = flags1; o2->flags = flags2; }
static int get_delta(struct rev_info *revs, struct remote_lock *lock) { int i; struct commit *commit; struct object_list **p = &objects; int count = 0; while ((commit = get_revision(revs)) != NULL) { p = process_tree(commit->tree, p); commit->object.flags |= LOCAL; if (!(commit->object.flags & UNINTERESTING)) count += add_send_request(&commit->object, lock); } for (i = 0; i < revs->pending.nr; i++) { struct object_array_entry *entry = revs->pending.objects + i; struct object *obj = entry->item; const char *name = entry->name; if (obj->flags & (UNINTERESTING | SEEN)) continue; if (obj->type == OBJ_TAG) { obj->flags |= SEEN; p = add_one_object(obj, p); continue; } if (obj->type == OBJ_TREE) { p = process_tree((struct tree *)obj, p); continue; } if (obj->type == OBJ_BLOB) { p = process_blob((struct blob *)obj, p); continue; } die("unknown pending object %s (%s)", oid_to_hex(&obj->oid), name); } while (objects) { if (!(objects->item->flags & UNINTERESTING)) count += add_send_request(objects->item, lock); objects = objects->next; } return count; }
int git_get_log_nextcommit(GIT_LOG handle, GIT_COMMIT *commit) { int ret =0; if(commit == NULL) return -1; memset(commit, 0, sizeof(GIT_COMMIT)); commit->m_pGitCommit = get_revision(handle); if( commit->m_pGitCommit == NULL) return -2; ret=git_parse_commit(commit); if(ret) return ret; return 0; }
static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids) { struct rev_info check_rev; struct commit *commit, *c1, *c2; struct object *o1, *o2; unsigned flags1, flags2; if (rev->pending.nr != 2) die(_("Need exactly one range.")); o1 = rev->pending.objects[0].item; o2 = rev->pending.objects[1].item; flags1 = o1->flags; flags2 = o2->flags; c1 = lookup_commit_reference(o1->oid.hash); c2 = lookup_commit_reference(o2->oid.hash); if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING)) die(_("Not a range.")); init_patch_ids(ids); /* given a range a..b get all patch ids for b..a */ init_revisions(&check_rev, rev->prefix); check_rev.max_parents = 1; o1->flags ^= UNINTERESTING; o2->flags ^= UNINTERESTING; add_pending_object(&check_rev, o1, "o1"); add_pending_object(&check_rev, o2, "o2"); if (prepare_revision_walk(&check_rev)) die(_("revision walk setup failed")); while ((commit = get_revision(&check_rev)) != NULL) { add_commit_patch_id(commit, ids); } /* reset for next revision walk */ clear_commit_marks(c1, SEEN | UNINTERESTING | SHOWN | ADDED); clear_commit_marks(c2, SEEN | UNINTERESTING | SHOWN | ADDED); o1->flags = flags1; o2->flags = flags2; }
/* Walk the commit DAG and collect number of commits per author per * timeperiod into a nested string_list collection. */ static struct string_list collect_stats(const struct cgit_period *period) { struct string_list authors; struct rev_info rev; struct commit *commit; const char *argv[] = {NULL, ctx.qry.head, NULL, NULL, NULL, NULL}; int argc = 3; time_t now; long i; struct tm *tm; char tmp[11]; time(&now); tm = gmtime(&now); period->trunc(tm); for (i = 1; i < period->count; i++) period->dec(tm); strftime(tmp, sizeof(tmp), "%Y-%m-%d", tm); argv[2] = xstrdup(fmt("--since=%s", tmp)); if (ctx.qry.path) { argv[3] = "--"; argv[4] = ctx.qry.path; argc += 2; } init_revisions(&rev, NULL); rev.abbrev = DEFAULT_ABBREV; rev.commit_format = CMIT_FMT_DEFAULT; rev.max_parents = 1; rev.verbose_header = 1; rev.show_root_diff = 0; setup_revisions(argc, argv, &rev, NULL); prepare_revision_walk(&rev); memset(&authors, 0, sizeof(authors)); while ((commit = get_revision(&rev)) != NULL) { add_commit(&authors, commit, period); free_commit_buffer(commit); free_commit_list(commit->parents); commit->parents = NULL; } return authors; }
static void squash_message(void) { struct rev_info rev; struct commit *commit; struct strbuf out; struct commit_list *j; int fd; printf("Squash commit -- not updating HEAD\n"); fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666); if (fd < 0) die("Could not write to %s", git_path("SQUASH_MSG")); init_revisions(&rev, NULL); rev.ignore_merges = 1; rev.commit_format = CMIT_FMT_MEDIUM; commit = lookup_commit(head); commit->object.flags |= UNINTERESTING; add_pending_object(&rev, &commit->object, NULL); for (j = remoteheads; j; j = j->next) add_pending_object(&rev, &j->item->object, NULL); setup_revisions(0, NULL, &rev, NULL); if (prepare_revision_walk(&rev)) die("revision walk setup failed"); strbuf_init(&out, 0); strbuf_addstr(&out, "Squashed commit of the following:\n"); while ((commit = get_revision(&rev)) != NULL) { strbuf_addch(&out, '\n'); strbuf_addf(&out, "commit %s\n", sha1_to_hex(commit->object.sha1)); pretty_print_commit(rev.commit_format, commit, &out, rev.abbrev, NULL, NULL, rev.date_mode, 0); } write(fd, out.buf, out.len); close(fd); strbuf_release(&out); }
static void squash_message(struct commit *commit, struct commit_list *remoteheads) { struct rev_info rev; struct strbuf out = STRBUF_INIT; struct commit_list *j; struct pretty_print_context ctx = {0}; printf(_("Squash commit -- not updating HEAD\n")); init_revisions(&rev, NULL); rev.ignore_merges = 1; rev.commit_format = CMIT_FMT_MEDIUM; commit->object.flags |= UNINTERESTING; add_pending_object(&rev, &commit->object, NULL); for (j = remoteheads; j; j = j->next) add_pending_object(&rev, &j->item->object, NULL); setup_revisions(0, NULL, &rev, NULL); if (prepare_revision_walk(&rev)) die(_("revision walk setup failed")); ctx.abbrev = rev.abbrev; ctx.date_mode = rev.date_mode; ctx.fmt = rev.commit_format; strbuf_addstr(&out, "Squashed commit of the following:\n"); while ((commit = get_revision(&rev)) != NULL) { strbuf_addch(&out, '\n'); strbuf_addf(&out, "commit %s\n", oid_to_hex(&commit->object.oid)); pretty_print_commit(&ctx, commit, &out); } write_file_buf(git_path_squash_msg(), out.buf, out.len); strbuf_release(&out); }
static const char *find_author_by_nickname(const char *name) { struct rev_info revs; struct commit *commit; struct strbuf buf = STRBUF_INIT; const char *av[20]; int ac = 0; init_revisions(&revs, NULL); strbuf_addf(&buf, "--author=%s", name); av[++ac] = "--all"; av[++ac] = "-i"; av[++ac] = buf.buf; av[++ac] = NULL; setup_revisions(ac, av, &revs, NULL); prepare_revision_walk(&revs); commit = get_revision(&revs); if (commit) { strbuf_release(&buf); format_commit_message(commit, "%an <%ae>", &buf, DATE_NORMAL); return strbuf_detach(&buf, NULL); } die("No existing author found with '%s'", name); }