|
| 1 | +/* |
| 2 | + * libgit2 "reset" example - Reset current HEAD to the specified state |
| 3 | + * |
| 4 | + * Written by the libgit2 contributors |
| 5 | + * |
| 6 | + * To the extent possible under law, the author(s) have dedicated all copyright |
| 7 | + * and related and neighboring rights to this software to the public domain |
| 8 | + * worldwide. This software is distributed without any warranty. |
| 9 | + * |
| 10 | + * You should have received a copy of the CC0 Public Domain Dedication along |
| 11 | + * with this software. If not, see |
| 12 | + * <http://creativecommons.org/publicdomain/zero/1.0/>. |
| 13 | + */ |
| 14 | + |
| 15 | +#include "common.h" |
| 16 | + |
| 17 | +/** |
| 18 | + * The following example demonstrates how to list and delete branches with libgit2. |
| 19 | + * |
| 20 | + * It will use the repository in the current working directory and list local branches by default, but also allows deleting local branches and list remote branches with options. |
| 21 | + * |
| 22 | + * Recognized options are: |
| 23 | + * -r: list remote branches. |
| 24 | + * -d <branch_name>: delete local branch. |
| 25 | + */ |
| 26 | + |
| 27 | +typedef struct { |
| 28 | + int list : 1; |
| 29 | + int remote : 1; |
| 30 | + int delete : 1; |
| 31 | + char* branch_name; |
| 32 | +} branch_options; |
| 33 | + |
| 34 | +static void print_usage(void) |
| 35 | +{ |
| 36 | + fprintf(stderr, "usage: branch [options]\n" |
| 37 | + "Options are :\n" |
| 38 | + " : list local branches." |
| 39 | + " -r: list remote branches.\n" |
| 40 | + " -d <branch_name>: delete local branch.\n"); |
| 41 | + exit(1); |
| 42 | +} |
| 43 | + |
| 44 | +static void parse_options(const char **repo_path, branch_options *opts, struct args_info *args) |
| 45 | +{ |
| 46 | + memset(opts, 0, sizeof(*opts)); |
| 47 | + |
| 48 | + /* Default values */ |
| 49 | + opts->list = 1; |
| 50 | + opts->remote = 0; |
| 51 | + opts->delete = 0; |
| 52 | + opts->branch_name = NULL; |
| 53 | + |
| 54 | + for (args->pos = 1; args->pos < args->argc; ++args->pos) { |
| 55 | + const char *curr = args->argv[args->pos]; |
| 56 | + |
| 57 | + if (match_arg_separator(args)) { |
| 58 | + break; |
| 59 | + } else if (!strcmp(curr, "-r")) { |
| 60 | + opts->remote = 1; |
| 61 | + if (args->pos != args->argc -1) { |
| 62 | + print_usage(); |
| 63 | + } |
| 64 | + } else if (!strcmp(curr, "-d")) { |
| 65 | + opts->list = 0; |
| 66 | + opts->delete = 1; |
| 67 | + |
| 68 | + if (args->pos == args->argc -1) { |
| 69 | + print_usage(); |
| 70 | + } else { |
| 71 | + opts->branch_name = strdup(args->argv[args->pos + 1]); |
| 72 | + } |
| 73 | + } |
| 74 | + } |
| 75 | +} |
| 76 | + |
| 77 | +int lg2_branch(git_repository *repo, int argc, char **argv) |
| 78 | +{ |
| 79 | + struct args_info args = ARGS_INFO_INIT; |
| 80 | + branch_options opts; |
| 81 | + const char *path = "."; |
| 82 | + |
| 83 | + git_branch_iterator *iter = NULL; |
| 84 | + git_branch_t git_branch_type = GIT_BRANCH_LOCAL; |
| 85 | + git_reference *ref = NULL; |
| 86 | + git_reference *upstream_ref = NULL; |
| 87 | + |
| 88 | + /** Parse our command line options */ |
| 89 | + parse_options(&path, &opts, &args); |
| 90 | + |
| 91 | + if (opts.list) { |
| 92 | + if (opts.remote) { |
| 93 | + git_branch_type = GIT_BRANCH_REMOTE; |
| 94 | + } |
| 95 | + |
| 96 | + // Create the branch iterator for branches |
| 97 | + if (git_branch_iterator_new(&iter, repo, git_branch_type) != 0) { |
| 98 | + fprintf(stderr, "Could not create branch iterator\n"); |
| 99 | + goto cleanup; |
| 100 | + } |
| 101 | + |
| 102 | + // Iterate through the branches |
| 103 | + while (git_branch_next(&ref, &git_branch_type, iter) != GIT_ITEROVER) { |
| 104 | + const char *branch_name; |
| 105 | + if (git_branch_name(&branch_name, ref) == 0) { |
| 106 | + if (!opts.remote) { |
| 107 | + if (git_branch_upstream(&upstream_ref, ref) == 0) { |
| 108 | + printf("%s:%s\n", branch_name, branch_name); |
| 109 | + } else { |
| 110 | + printf("%s\n", branch_name); |
| 111 | + } |
| 112 | + } else { |
| 113 | + printf("%s\n", branch_name); |
| 114 | + } |
| 115 | + |
| 116 | + } |
| 117 | + git_reference_free(ref); |
| 118 | + } |
| 119 | + } else if (opts.delete) { |
| 120 | + // Lookup the reference for the branch |
| 121 | + if (git_branch_lookup(&ref, repo, opts.branch_name, GIT_BRANCH_LOCAL) != 0) { |
| 122 | + fprintf(stderr, "Error looking up branch: %s\n", opts.branch_name); |
| 123 | + goto cleanup; |
| 124 | + } |
| 125 | + |
| 126 | + // Delete the reference |
| 127 | + if (git_branch_delete(ref) != 0) { |
| 128 | + fprintf(stderr, "Error deleting branch: %s\n", opts.branch_name); |
| 129 | + goto cleanup; |
| 130 | + } |
| 131 | + } |
| 132 | + |
| 133 | +cleanup: |
| 134 | + if (iter) git_branch_iterator_free(iter); |
| 135 | + |
| 136 | + return 0; |
| 137 | +} |
0 commit comments