]> git.proxmox.com Git - libgit2.git/blob - examples/rev-list.c
Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, Repository-Browse.
[libgit2.git] / examples / rev-list.c
1 /*
2 * libgit2 "rev-list" example - shows how to transform a rev-spec into a list
3 * of commit ids
4 *
5 * Written by the libgit2 contributors
6 *
7 * To the extent possible under law, the author(s) have dedicated all copyright
8 * and related and neighboring rights to this software to the public domain
9 * worldwide. This software is distributed without any warranty.
10 *
11 * You should have received a copy of the CC0 Public Domain Dedication along
12 * with this software. If not, see
13 * <http://creativecommons.org/publicdomain/zero/1.0/>.
14 */
15
16 #include "common.h"
17
18 #include <assert.h>
19
20 static int revwalk_parse_options(git_sort_t *sort, struct args_info *args);
21 static int revwalk_parse_revs(git_repository *repo, git_revwalk *walk, struct args_info *args);
22
23 int lg2_rev_list(git_repository *repo, int argc, char **argv)
24 {
25 struct args_info args = ARGS_INFO_INIT;
26 git_revwalk *walk;
27 git_oid oid;
28 git_sort_t sort;
29 char buf[GIT_OID_HEXSZ+1];
30
31 check_lg2(revwalk_parse_options(&sort, &args), "parsing options", NULL);
32
33 check_lg2(git_revwalk_new(&walk, repo), "allocating revwalk", NULL);
34 git_revwalk_sorting(walk, sort);
35 check_lg2(revwalk_parse_revs(repo, walk, &args), "parsing revs", NULL);
36
37 while (!git_revwalk_next(&oid, walk)) {
38 git_oid_fmt(buf, &oid);
39 buf[GIT_OID_HEXSZ] = '\0';
40 printf("%s\n", buf);
41 }
42
43 git_revwalk_free(walk);
44 return 0;
45 }
46
47 static int push_commit(git_revwalk *walk, const git_oid *oid, int hide)
48 {
49 if (hide)
50 return git_revwalk_hide(walk, oid);
51 else
52 return git_revwalk_push(walk, oid);
53 }
54
55 static int push_spec(git_repository *repo, git_revwalk *walk, const char *spec, int hide)
56 {
57 int error;
58 git_object *obj;
59
60 if ((error = git_revparse_single(&obj, repo, spec)) < 0)
61 return error;
62
63 error = push_commit(walk, git_object_id(obj), hide);
64 git_object_free(obj);
65 return error;
66 }
67
68 static int push_range(git_repository *repo, git_revwalk *walk, const char *range, int hide)
69 {
70 git_revspec revspec;
71 int error = 0;
72
73 if ((error = git_revparse(&revspec, repo, range)))
74 return error;
75
76 if (revspec.flags & GIT_REVPARSE_MERGE_BASE) {
77 /* TODO: support "<commit>...<commit>" */
78 return GIT_EINVALIDSPEC;
79 }
80
81 if ((error = push_commit(walk, git_object_id(revspec.from), !hide)))
82 goto out;
83
84 error = push_commit(walk, git_object_id(revspec.to), hide);
85
86 out:
87 git_object_free(revspec.from);
88 git_object_free(revspec.to);
89 return error;
90 }
91
92 static void print_usage(void)
93 {
94 fprintf(stderr, "rev-list [--git-dir=dir] [--topo-order|--date-order] [--reverse] <revspec>\n");
95 exit(-1);
96 }
97
98 static int revwalk_parse_options(git_sort_t *sort, struct args_info *args)
99 {
100 assert(sort && args);
101 *sort = GIT_SORT_NONE;
102
103 if (args->argc < 1)
104 print_usage();
105
106 for (args->pos = 1; args->pos < args->argc; ++args->pos) {
107 const char *curr = args->argv[args->pos];
108
109 if (!strcmp(curr, "--topo-order")) {
110 *sort |= GIT_SORT_TOPOLOGICAL;
111 } else if (!strcmp(curr, "--date-order")) {
112 *sort |= GIT_SORT_TIME;
113 } else if (!strcmp(curr, "--reverse")) {
114 *sort |= (*sort & ~GIT_SORT_REVERSE) ^ GIT_SORT_REVERSE;
115 } else {
116 break;
117 }
118 }
119 return 0;
120 }
121
122 static int revwalk_parse_revs(git_repository *repo, git_revwalk *walk, struct args_info *args)
123 {
124 int hide, error;
125 git_oid oid;
126
127 hide = 0;
128 for (; args->pos < args->argc; ++args->pos) {
129 const char *curr = args->argv[args->pos];
130
131 if (!strcmp(curr, "--not")) {
132 hide = !hide;
133 } else if (curr[0] == '^') {
134 if ((error = push_spec(repo, walk, curr + 1, !hide)))
135 return error;
136 } else if (strstr(curr, "..")) {
137 if ((error = push_range(repo, walk, curr, hide)))
138 return error;
139 } else {
140 if (push_spec(repo, walk, curr, hide) == 0)
141 continue;
142
143 if ((error = git_oid_fromstr(&oid, curr)))
144 return error;
145 if ((error = push_commit(walk, &oid, hide)))
146 return error;
147 }
148 }
149
150 return 0;
151 }
152