]> git.proxmox.com Git - libgit2.git/blame - examples/rev-list.c
Library transition to 1.0.0
[libgit2.git] / examples / rev-list.c
CommitLineData
784b3abb 1/*
6cb831bd
BS
2 * libgit2 "rev-list" example - shows how to transform a rev-spec into a list
3 * of commit ids
784b3abb 4 *
6cb831bd
BS
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/>.
784b3abb 14 */
8f7f5e55 15
784b3abb 16#include "common.h"
8f7f5e55 17
0c9c969a 18#include <assert.h>
784b3abb 19
0c9c969a
UG
20static int revwalk_parse_options(git_sort_t *sort, struct args_info *args);
21static int revwalk_parse_revs(git_repository *repo, git_revwalk *walk, struct args_info *args);
22
23int lg2_rev_list(git_repository *repo, int argc, char **argv)
8f7f5e55 24{
0c9c969a 25 struct args_info args = ARGS_INFO_INIT;
784b3abb
BS
26 git_revwalk *walk;
27 git_oid oid;
0c9c969a 28 git_sort_t sort;
3b2cb2c9 29 char buf[GIT_OID_HEXSZ+1];
784b3abb 30
0c9c969a 31 check_lg2(revwalk_parse_options(&sort, &args), "parsing options", NULL);
8f7f5e55 32
784b3abb 33 check_lg2(git_revwalk_new(&walk, repo), "allocating revwalk", NULL);
0c9c969a
UG
34 git_revwalk_sorting(walk, sort);
35 check_lg2(revwalk_parse_revs(repo, walk, &args), "parsing revs", NULL);
784b3abb
BS
36
37 while (!git_revwalk_next(&oid, walk)) {
38 git_oid_fmt(buf, &oid);
3b2cb2c9 39 buf[GIT_OID_HEXSZ] = '\0';
784b3abb
BS
40 printf("%s\n", buf);
41 }
42
0c9c969a 43 git_revwalk_free(walk);
784b3abb 44 return 0;
8f7f5e55
GP
45}
46
5961d5ea 47static int push_commit(git_revwalk *walk, const git_oid *oid, int hide)
8f7f5e55
GP
48{
49 if (hide)
1aa21fe3 50 return git_revwalk_hide(walk, oid);
8f7f5e55 51 else
1aa21fe3 52 return git_revwalk_push(walk, oid);
8f7f5e55
GP
53}
54
55static int push_spec(git_repository *repo, git_revwalk *walk, const char *spec, int hide)
56{
57 int error;
299a224b 58 git_object *obj;
8f7f5e55 59
5961d5ea 60 if ((error = git_revparse_single(&obj, repo, spec)) < 0)
8f7f5e55 61 return error;
32ef1d1c 62
299a224b
BS
63 error = push_commit(walk, git_object_id(obj), hide);
64 git_object_free(obj);
65 return error;
8f7f5e55
GP
66}
67
68static int push_range(git_repository *repo, git_revwalk *walk, const char *range, int hide)
69{
32ef1d1c 70 git_revspec revspec;
8f7f5e55
GP
71 int error = 0;
72
32ef1d1c 73 if ((error = git_revparse(&revspec, repo, range)))
8f7f5e55 74 return error;
32ef1d1c
VM
75
76 if (revspec.flags & GIT_REVPARSE_MERGE_BASE) {
8f7f5e55
GP
77 /* TODO: support "<commit>...<commit>" */
78 return GIT_EINVALIDSPEC;
79 }
80
32ef1d1c 81 if ((error = push_commit(walk, git_object_id(revspec.from), !hide)))
8f7f5e55 82 goto out;
8f7f5e55 83
32ef1d1c
VM
84 error = push_commit(walk, git_object_id(revspec.to), hide);
85
86out:
87 git_object_free(revspec.from);
88 git_object_free(revspec.to);
8f7f5e55
GP
89 return error;
90}
91
0c9c969a
UG
92static 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
98static 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
122static int revwalk_parse_revs(git_repository *repo, git_revwalk *walk, struct args_info *args)
8f7f5e55 123{
0c9c969a
UG
124 int hide, error;
125 git_oid oid;
8f7f5e55
GP
126
127 hide = 0;
0c9c969a
UG
128 for (; args->pos < args->argc; ++args->pos) {
129 const char *curr = args->argv[args->pos];
130
131 if (!strcmp(curr, "--not")) {
8f7f5e55 132 hide = !hide;
0c9c969a
UG
133 } else if (curr[0] == '^') {
134 if ((error = push_spec(repo, walk, curr + 1, !hide)))
8f7f5e55 135 return error;
0c9c969a
UG
136 } else if (strstr(curr, "..")) {
137 if ((error = push_range(repo, walk, curr, hide)))
8f7f5e55
GP
138 return error;
139 } else {
0c9c969a
UG
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)))
8f7f5e55
GP
146 return error;
147 }
148 }
149
150 return 0;
151}
152