]> git.proxmox.com Git - libgit2.git/blob - examples/lg2.c
New upstream version 1.1.0+dfsg.1
[libgit2.git] / examples / lg2.c
1 #include "common.h"
2
3 /* This part is not strictly libgit2-dependent, but you can use this
4 * as a starting point for a git-like tool */
5
6 typedef int (*git_command_fn)(git_repository *, int , char **);
7
8 struct {
9 char *name;
10 git_command_fn fn;
11 char requires_repo;
12 } commands[] = {
13 { "add", lg2_add, 1 },
14 { "blame", lg2_blame, 1 },
15 { "cat-file", lg2_cat_file, 1 },
16 { "checkout", lg2_checkout, 1 },
17 { "clone", lg2_clone, 0 },
18 { "commit", lg2_commit, 1 },
19 { "config", lg2_config, 1 },
20 { "describe", lg2_describe, 1 },
21 { "diff", lg2_diff, 1 },
22 { "fetch", lg2_fetch, 1 },
23 { "for-each-ref", lg2_for_each_ref, 1 },
24 { "general", lg2_general, 0 },
25 { "index-pack", lg2_index_pack, 1 },
26 { "init", lg2_init, 0 },
27 { "log", lg2_log, 1 },
28 { "ls-files", lg2_ls_files, 1 },
29 { "ls-remote", lg2_ls_remote, 1 },
30 { "merge", lg2_merge, 1 },
31 { "push", lg2_push, 1 },
32 { "remote", lg2_remote, 1 },
33 { "rev-list", lg2_rev_list, 1 },
34 { "rev-parse", lg2_rev_parse, 1 },
35 { "show-index", lg2_show_index, 0 },
36 { "stash", lg2_stash, 1 },
37 { "status", lg2_status, 1 },
38 { "tag", lg2_tag, 1 },
39 };
40
41 static int run_command(git_command_fn fn, git_repository *repo, struct args_info args)
42 {
43 int error;
44
45 /* Run the command. If something goes wrong, print the error message to stderr */
46 error = fn(repo, args.argc - args.pos, &args.argv[args.pos]);
47 if (error < 0) {
48 if (git_error_last() == NULL)
49 fprintf(stderr, "Error without message");
50 else
51 fprintf(stderr, "Bad news:\n %s\n", git_error_last()->message);
52 }
53
54 return !!error;
55 }
56
57 static int usage(const char *prog)
58 {
59 size_t i;
60
61 fprintf(stderr, "usage: %s <cmd>...\n\nAvailable commands:\n\n", prog);
62 for (i = 0; i < ARRAY_SIZE(commands); i++)
63 fprintf(stderr, "\t%s\n", commands[i].name);
64
65 exit(EXIT_FAILURE);
66 }
67
68 int main(int argc, char **argv)
69 {
70 struct args_info args = ARGS_INFO_INIT;
71 git_repository *repo = NULL;
72 const char *git_dir = NULL;
73 int return_code = 1;
74 size_t i;
75
76 if (argc < 2)
77 usage(argv[0]);
78
79 git_libgit2_init();
80
81 for (args.pos = 1; args.pos < args.argc; ++args.pos) {
82 char *a = args.argv[args.pos];
83
84 if (a[0] != '-') {
85 /* non-arg */
86 break;
87 } else if (optional_str_arg(&git_dir, &args, "--git-dir", ".git")) {
88 continue;
89 } else if (match_arg_separator(&args)) {
90 break;
91 }
92 }
93
94 if (args.pos == args.argc)
95 usage(argv[0]);
96
97 if (!git_dir)
98 git_dir = ".";
99
100 for (i = 0; i < ARRAY_SIZE(commands); ++i) {
101 if (strcmp(args.argv[args.pos], commands[i].name))
102 continue;
103
104 /*
105 * Before running the actual command, create an instance
106 * of the local repository and pass it to the function.
107 * */
108 if (commands[i].requires_repo) {
109 check_lg2(git_repository_open_ext(&repo, git_dir, 0, NULL),
110 "Unable to open repository '%s'", git_dir);
111 }
112
113 return_code = run_command(commands[i].fn, repo, args);
114 goto shutdown;
115 }
116
117 fprintf(stderr, "Command not found: %s\n", argv[1]);
118
119 shutdown:
120 git_repository_free(repo);
121 git_libgit2_shutdown();
122
123 return return_code;
124 }