File Coverage

deps/libgit2/src/branch.c
Criterion Covered Total %
statement 136 351 38.7
branch 47 210 22.3
condition n/a
subroutine n/a
pod n/a
total 183 561 32.6


line stmt bran cond sub pod time code
1             /*
2             * Copyright (C) the libgit2 contributors. All rights reserved.
3             *
4             * This file is part of libgit2, distributed under the GNU GPL v2 with
5             * a Linking Exception. For full terms see the included COPYING file.
6             */
7              
8             #include "branch.h"
9              
10             #include "commit.h"
11             #include "tag.h"
12             #include "config.h"
13             #include "refspec.h"
14             #include "refs.h"
15             #include "remote.h"
16             #include "annotated_commit.h"
17             #include "worktree.h"
18              
19             #include "git2/branch.h"
20              
21 15           static int retrieve_branch_reference(
22             git_reference **branch_reference_out,
23             git_repository *repo,
24             const char *branch_name,
25             bool is_remote)
26             {
27 15           git_reference *branch = NULL;
28 15           int error = 0;
29             char *prefix;
30 15           git_buf ref_name = GIT_BUF_INIT;
31              
32 15 100         prefix = is_remote ? GIT_REFS_REMOTES_DIR : GIT_REFS_HEADS_DIR;
33              
34 15 50         if ((error = git_buf_joinpath(&ref_name, prefix, branch_name)) < 0)
35             /* OOM */;
36 15 100         else if ((error = git_reference_lookup(&branch, repo, ref_name.ptr)) < 0)
37 2 100         git_error_set(
38             GIT_ERROR_REFERENCE, "cannot locate %s branch '%s'",
39             is_remote ? "remote-tracking" : "local", branch_name);
40              
41 15           *branch_reference_out = branch; /* will be NULL on error */
42              
43 15           git_buf_dispose(&ref_name);
44 15           return error;
45             }
46              
47 0           static int not_a_local_branch(const char *reference_name)
48             {
49 0           git_error_set(
50             GIT_ERROR_INVALID,
51             "reference '%s' is not a local branch.", reference_name);
52 0           return -1;
53             }
54              
55 16           static int create_branch(
56             git_reference **ref_out,
57             git_repository *repository,
58             const char *branch_name,
59             const git_commit *commit,
60             const char *from,
61             int force)
62             {
63 16           int is_unmovable_head = 0;
64 16           git_reference *branch = NULL;
65 16           git_buf canonical_branch_name = GIT_BUF_INIT,
66 16           log_message = GIT_BUF_INIT;
67 16           int error = -1;
68 16           int bare = git_repository_is_bare(repository);
69              
70 16 50         assert(branch_name && commit && ref_out);
    50          
    50          
71 16 50         assert(git_object_owner((const git_object *)commit) == repository);
72              
73 16 50         if (!git__strcmp(branch_name, "HEAD")) {
74 0           git_error_set(GIT_ERROR_REFERENCE, "'HEAD' is not a valid branch name");
75 0           error = -1;
76 0           goto cleanup;
77             }
78              
79 16 50         if (force && !bare && git_branch_lookup(&branch, repository, branch_name, GIT_BRANCH_LOCAL) == 0) {
    0          
    0          
80 0           error = git_branch_is_head(branch);
81 0           git_reference_free(branch);
82 0           branch = NULL;
83              
84 0 0         if (error < 0)
85 0           goto cleanup;
86              
87 0           is_unmovable_head = error;
88             }
89              
90 16 50         if (is_unmovable_head && force) {
    0          
91 0           git_error_set(GIT_ERROR_REFERENCE, "cannot force update branch '%s' as it is "
92             "the current HEAD of the repository.", branch_name);
93 0           error = -1;
94 0           goto cleanup;
95             }
96              
97 16 50         if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0)
98 0           goto cleanup;
99              
100 16 50         if (git_buf_printf(&log_message, "branch: Created from %s", from) < 0)
101 0           goto cleanup;
102              
103 16           error = git_reference_create(&branch, repository,
104             git_buf_cstr(&canonical_branch_name), git_commit_id(commit), force,
105             git_buf_cstr(&log_message));
106              
107 16 50         if (!error)
108 16           *ref_out = branch;
109              
110             cleanup:
111 16           git_buf_dispose(&canonical_branch_name);
112 16           git_buf_dispose(&log_message);
113 16           return error;
114             }
115              
116 16           int git_branch_create(
117             git_reference **ref_out,
118             git_repository *repository,
119             const char *branch_name,
120             const git_commit *commit,
121             int force)
122             {
123 16           return create_branch(ref_out, repository, branch_name, commit, git_oid_tostr_s(git_commit_id(commit)), force);
124             }
125              
126 0           int git_branch_create_from_annotated(
127             git_reference **ref_out,
128             git_repository *repository,
129             const char *branch_name,
130             const git_annotated_commit *commit,
131             int force)
132             {
133 0           return create_branch(ref_out,
134 0           repository, branch_name, commit->commit, commit->description, force);
135             }
136              
137 17           static int branch_is_checked_out(git_repository *worktree, void *payload)
138             {
139 17           git_reference *branch = (git_reference *) payload;
140 17           git_reference *head = NULL;
141             int error;
142              
143 17 50         if (git_repository_is_bare(worktree))
144 0           return 0;
145              
146 17 50         if ((error = git_reference_lookup(&head, worktree, GIT_HEAD_FILE)) < 0) {
147 0 0         if (error == GIT_ENOTFOUND)
148 0           error = 0;
149 0           goto out;
150             }
151              
152 17 50         if (git_reference_type(head) != GIT_REFERENCE_SYMBOLIC)
153 0           goto out;
154              
155 17           error = !git__strcmp(head->target.symbolic, branch->name);
156              
157             out:
158 17           git_reference_free(head);
159 17           return error;
160             }
161              
162 17           int git_branch_is_checked_out(const git_reference *branch)
163             {
164 17 50         if (!git_reference_is_branch(branch))
165 0           return 0;
166 17           return git_repository_foreach_worktree(git_reference_owner(branch),
167 17           branch_is_checked_out, (void *)branch) == 1;
168             }
169              
170 0           int git_branch_delete(git_reference *branch)
171             {
172             int is_head;
173 0           git_buf config_section = GIT_BUF_INIT;
174 0           int error = -1;
175              
176 0 0         assert(branch);
177              
178 0 0         if (!git_reference_is_branch(branch) && !git_reference_is_remote(branch)) {
    0          
179 0           git_error_set(GIT_ERROR_INVALID, "reference '%s' is not a valid branch.",
180             git_reference_name(branch));
181 0           return GIT_ENOTFOUND;
182             }
183              
184 0 0         if ((is_head = git_branch_is_head(branch)) < 0)
185 0           return is_head;
186              
187 0 0         if (is_head) {
188 0           git_error_set(GIT_ERROR_REFERENCE, "cannot delete branch '%s' as it is "
189             "the current HEAD of the repository.", git_reference_name(branch));
190 0           return -1;
191             }
192              
193 0 0         if (git_reference_is_branch(branch) && git_branch_is_checked_out(branch)) {
    0          
194 0           git_error_set(GIT_ERROR_REFERENCE, "Cannot delete branch '%s' as it is "
195             "the current HEAD of a linked repository.", git_reference_name(branch));
196 0           return -1;
197             }
198              
199 0 0         if (git_buf_join(&config_section, '.', "branch",
200 0           git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0)
201 0           goto on_error;
202              
203 0 0         if (git_config_rename_section(
204             git_reference_owner(branch), git_buf_cstr(&config_section), NULL) < 0)
205 0           goto on_error;
206              
207 0           error = git_reference_delete(branch);
208              
209             on_error:
210 0           git_buf_dispose(&config_section);
211 0           return error;
212             }
213              
214             typedef struct {
215             git_reference_iterator *iter;
216             unsigned int flags;
217             } branch_iter;
218              
219 6           int git_branch_next(git_reference **out, git_branch_t *out_type, git_branch_iterator *_iter)
220             {
221 6           branch_iter *iter = (branch_iter *) _iter;
222             git_reference *ref;
223             int error;
224              
225 8 100         while ((error = git_reference_next(&ref, iter->iter)) == 0) {
226 12           if ((iter->flags & GIT_BRANCH_LOCAL) &&
227 6           !git__prefixcmp(ref->name, GIT_REFS_HEADS_DIR)) {
228 4           *out = ref;
229 4           *out_type = GIT_BRANCH_LOCAL;
230              
231 4           return 0;
232 3           } else if ((iter->flags & GIT_BRANCH_REMOTE) &&
233 1           !git__prefixcmp(ref->name, GIT_REFS_REMOTES_DIR)) {
234 0           *out = ref;
235 0           *out_type = GIT_BRANCH_REMOTE;
236              
237 0           return 0;
238             } else {
239 2           git_reference_free(ref);
240             }
241             }
242              
243 6           return error;
244             }
245              
246 2           int git_branch_iterator_new(
247             git_branch_iterator **out,
248             git_repository *repo,
249             git_branch_t list_flags)
250             {
251             branch_iter *iter;
252              
253 2           iter = git__calloc(1, sizeof(branch_iter));
254 2 50         GIT_ERROR_CHECK_ALLOC(iter);
255              
256 2           iter->flags = list_flags;
257              
258 2 50         if (git_reference_iterator_new(&iter->iter, repo) < 0) {
259 0           git__free(iter);
260 0           return -1;
261             }
262              
263 2           *out = (git_branch_iterator *) iter;
264              
265 2           return 0;
266             }
267              
268 2           void git_branch_iterator_free(git_branch_iterator *_iter)
269             {
270 2           branch_iter *iter = (branch_iter *) _iter;
271              
272 2 50         if (iter == NULL)
273 0           return;
274              
275 2           git_reference_iterator_free(iter->iter);
276 2           git__free(iter);
277             }
278              
279 1           int git_branch_move(
280             git_reference **out,
281             git_reference *branch,
282             const char *new_branch_name,
283             int force)
284             {
285 1           git_buf new_reference_name = GIT_BUF_INIT,
286 1           old_config_section = GIT_BUF_INIT,
287 1           new_config_section = GIT_BUF_INIT,
288 1           log_message = GIT_BUF_INIT;
289             int error;
290              
291 1 50         assert(branch && new_branch_name);
    50          
292              
293 1 50         if (!git_reference_is_branch(branch))
294 0           return not_a_local_branch(git_reference_name(branch));
295              
296 1 50         if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0)
297 0           goto done;
298              
299 1 50         if ((error = git_buf_printf(&log_message, "branch: renamed %s to %s",
300             git_reference_name(branch), git_buf_cstr(&new_reference_name))) < 0)
301 0           goto done;
302              
303             /* first update ref then config so failure won't trash config */
304              
305 1           error = git_reference_rename(
306             out, branch, git_buf_cstr(&new_reference_name), force,
307             git_buf_cstr(&log_message));
308 1 50         if (error < 0)
309 0           goto done;
310              
311 1           git_buf_join(&old_config_section, '.', "branch",
312 1           git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR));
313 1           git_buf_join(&new_config_section, '.', "branch", new_branch_name);
314              
315 1           error = git_config_rename_section(
316             git_reference_owner(branch),
317             git_buf_cstr(&old_config_section),
318             git_buf_cstr(&new_config_section));
319              
320             done:
321 1           git_buf_dispose(&new_reference_name);
322 1           git_buf_dispose(&old_config_section);
323 1           git_buf_dispose(&new_config_section);
324 1           git_buf_dispose(&log_message);
325              
326 1           return error;
327             }
328              
329 15           int git_branch_lookup(
330             git_reference **ref_out,
331             git_repository *repo,
332             const char *branch_name,
333             git_branch_t branch_type)
334             {
335 15           int error = -1;
336 15 50         assert(ref_out && repo && branch_name);
    50          
    50          
337              
338 15           switch (branch_type) {
339             case GIT_BRANCH_LOCAL:
340             case GIT_BRANCH_REMOTE:
341 15           error = retrieve_branch_reference(ref_out, repo, branch_name, branch_type == GIT_BRANCH_REMOTE);
342 15           break;
343             case GIT_BRANCH_ALL:
344 0           error = retrieve_branch_reference(ref_out, repo, branch_name, false);
345 0 0         if (error == GIT_ENOTFOUND)
346 0           error = retrieve_branch_reference(ref_out, repo, branch_name, true);
347 0           break;
348             default:
349 0           assert(false);
350             }
351 15           return error;
352             }
353              
354 0           int git_branch_name(
355             const char **out,
356             const git_reference *ref)
357             {
358             const char *branch_name;
359              
360 0 0         assert(out && ref);
    0          
361              
362 0           branch_name = ref->name;
363              
364 0 0         if (git_reference_is_branch(ref)) {
365 0           branch_name += strlen(GIT_REFS_HEADS_DIR);
366 0 0         } else if (git_reference_is_remote(ref)) {
367 0           branch_name += strlen(GIT_REFS_REMOTES_DIR);
368             } else {
369 0           git_error_set(GIT_ERROR_INVALID,
370 0           "reference '%s' is neither a local nor a remote branch.", ref->name);
371 0           return -1;
372             }
373 0           *out = branch_name;
374 0           return 0;
375             }
376              
377 4           static int retrieve_upstream_configuration(
378             git_buf *out,
379             const git_config *config,
380             const char *canonical_branch_name,
381             const char *format)
382             {
383 4           git_buf buf = GIT_BUF_INIT;
384             int error;
385              
386 4 50         if (git_buf_printf(&buf, format,
387             canonical_branch_name + strlen(GIT_REFS_HEADS_DIR)) < 0)
388 0           return -1;
389              
390 4           error = git_config_get_string_buf(out, config, git_buf_cstr(&buf));
391 4           git_buf_dispose(&buf);
392 4           return error;
393             }
394              
395 4           int git_branch_upstream_name(
396             git_buf *out,
397             git_repository *repo,
398             const char *refname)
399             {
400 4           git_buf remote_name = GIT_BUF_INIT;
401 4           git_buf merge_name = GIT_BUF_INIT;
402 4           git_buf buf = GIT_BUF_INIT;
403 4           int error = -1;
404 4           git_remote *remote = NULL;
405             const git_refspec *refspec;
406             git_config *config;
407              
408 4 50         assert(out && refname);
    50          
409              
410 4           git_buf_sanitize(out);
411              
412 4 50         if (!git_reference__is_branch(refname))
413 0           return not_a_local_branch(refname);
414              
415 4 50         if ((error = git_repository_config_snapshot(&config, repo)) < 0)
416 0           return error;
417              
418 4 50         if ((error = retrieve_upstream_configuration(
419             &remote_name, config, refname, "branch.%s.remote")) < 0)
420 4           goto cleanup;
421              
422 0 0         if ((error = retrieve_upstream_configuration(
423             &merge_name, config, refname, "branch.%s.merge")) < 0)
424 0           goto cleanup;
425              
426 0 0         if (git_buf_len(&remote_name) == 0 || git_buf_len(&merge_name) == 0) {
    0          
427 0           git_error_set(GIT_ERROR_REFERENCE,
428             "branch '%s' does not have an upstream", refname);
429 0           error = GIT_ENOTFOUND;
430 0           goto cleanup;
431             }
432              
433 0 0         if (strcmp(".", git_buf_cstr(&remote_name)) != 0) {
434 0 0         if ((error = git_remote_lookup(&remote, repo, git_buf_cstr(&remote_name))) < 0)
435 0           goto cleanup;
436              
437 0           refspec = git_remote__matching_refspec(remote, git_buf_cstr(&merge_name));
438 0 0         if (!refspec) {
439 0           error = GIT_ENOTFOUND;
440 0           goto cleanup;
441             }
442              
443 0 0         if (git_refspec_transform(&buf, refspec, git_buf_cstr(&merge_name)) < 0)
444 0           goto cleanup;
445             } else
446 0 0         if (git_buf_set(&buf, git_buf_cstr(&merge_name), git_buf_len(&merge_name)) < 0)
447 0           goto cleanup;
448              
449 0           error = git_buf_set(out, git_buf_cstr(&buf), git_buf_len(&buf));
450              
451             cleanup:
452 4           git_config_free(config);
453 4           git_remote_free(remote);
454 4           git_buf_dispose(&remote_name);
455 4           git_buf_dispose(&merge_name);
456 4           git_buf_dispose(&buf);
457 4           return error;
458             }
459              
460 0           int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *refname)
461             {
462             int error;
463             git_config *cfg;
464              
465 0 0         if (!git_reference__is_branch(refname))
466 0           return not_a_local_branch(refname);
467              
468 0 0         if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
469 0           return error;
470              
471 0           git_buf_sanitize(buf);
472              
473 0 0         if ((error = retrieve_upstream_configuration(buf, cfg, refname, "branch.%s.remote")) < 0)
474 0           return error;
475              
476 0 0         if (git_buf_len(buf) == 0) {
477 0           git_error_set(GIT_ERROR_REFERENCE, "branch '%s' does not have an upstream remote", refname);
478 0           error = GIT_ENOTFOUND;
479 0           git_buf_clear(buf);
480             }
481              
482 0           return error;
483             }
484              
485 0           int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refname)
486             {
487 0           git_strarray remote_list = {0};
488             size_t i;
489             git_remote *remote;
490             const git_refspec *fetchspec;
491 0           int error = 0;
492 0           char *remote_name = NULL;
493              
494 0 0         assert(buf && repo && refname);
    0          
    0          
495              
496 0           git_buf_sanitize(buf);
497              
498             /* Verify that this is a remote branch */
499 0 0         if (!git_reference__is_remote(refname)) {
500 0           git_error_set(GIT_ERROR_INVALID, "reference '%s' is not a remote branch.",
501             refname);
502 0           error = GIT_ERROR;
503 0           goto cleanup;
504             }
505              
506             /* Get the remotes */
507 0 0         if ((error = git_remote_list(&remote_list, repo)) < 0)
508 0           goto cleanup;
509              
510             /* Find matching remotes */
511 0 0         for (i = 0; i < remote_list.count; i++) {
512 0 0         if ((error = git_remote_lookup(&remote, repo, remote_list.strings[i])) < 0)
513 0           continue;
514              
515 0           fetchspec = git_remote__matching_dst_refspec(remote, refname);
516 0 0         if (fetchspec) {
517             /* If we have not already set out yet, then set
518             * it to the matching remote name. Otherwise
519             * multiple remotes match this reference, and it
520             * is ambiguous. */
521 0 0         if (!remote_name) {
522 0           remote_name = remote_list.strings[i];
523             } else {
524 0           git_remote_free(remote);
525              
526 0           git_error_set(GIT_ERROR_REFERENCE,
527             "reference '%s' is ambiguous", refname);
528 0           error = GIT_EAMBIGUOUS;
529 0           goto cleanup;
530             }
531             }
532              
533 0           git_remote_free(remote);
534             }
535              
536 0 0         if (remote_name) {
537 0           git_buf_clear(buf);
538 0           error = git_buf_puts(buf, remote_name);
539             } else {
540 0           git_error_set(GIT_ERROR_REFERENCE,
541             "could not determine remote for '%s'", refname);
542 0           error = GIT_ENOTFOUND;
543             }
544              
545             cleanup:
546 0 0         if (error < 0)
547 0           git_buf_dispose(buf);
548              
549 0           git_strarray_dispose(&remote_list);
550 0           return error;
551             }
552              
553 2           int git_branch_upstream(
554             git_reference **tracking_out,
555             const git_reference *branch)
556             {
557             int error;
558 2           git_buf tracking_name = GIT_BUF_INIT;
559              
560 2 50         if ((error = git_branch_upstream_name(&tracking_name,
561             git_reference_owner(branch), git_reference_name(branch))) < 0)
562 2           return error;
563              
564 0           error = git_reference_lookup(
565             tracking_out,
566             git_reference_owner(branch),
567             git_buf_cstr(&tracking_name));
568              
569 0           git_buf_dispose(&tracking_name);
570 2           return error;
571             }
572              
573 0           static int unset_upstream(git_config *config, const char *shortname)
574             {
575 0           git_buf buf = GIT_BUF_INIT;
576              
577 0 0         if (git_buf_printf(&buf, "branch.%s.remote", shortname) < 0)
578 0           return -1;
579              
580 0 0         if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0)
581 0           goto on_error;
582              
583 0           git_buf_clear(&buf);
584 0 0         if (git_buf_printf(&buf, "branch.%s.merge", shortname) < 0)
585 0           goto on_error;
586              
587 0 0         if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0)
588 0           goto on_error;
589              
590 0           git_buf_dispose(&buf);
591 0           return 0;
592              
593             on_error:
594 0           git_buf_dispose(&buf);
595 0           return -1;
596             }
597              
598 0           int git_branch_set_upstream(git_reference *branch, const char *branch_name)
599             {
600 0           git_buf key = GIT_BUF_INIT, remote_name = GIT_BUF_INIT, merge_refspec = GIT_BUF_INIT;
601             git_reference *upstream;
602             git_repository *repo;
603 0           git_remote *remote = NULL;
604             git_config *config;
605             const char *refname, *shortname;
606             int local, error;
607             const git_refspec *fetchspec;
608              
609 0           refname = git_reference_name(branch);
610 0 0         if (!git_reference__is_branch(refname))
611 0           return not_a_local_branch(refname);
612              
613 0 0         if (git_repository_config__weakptr(&config, git_reference_owner(branch)) < 0)
614 0           return -1;
615              
616 0           shortname = refname + strlen(GIT_REFS_HEADS_DIR);
617              
618             /* We're unsetting, delegate and bail-out */
619 0 0         if (branch_name == NULL)
620 0           return unset_upstream(config, shortname);
621              
622 0           repo = git_reference_owner(branch);
623              
624             /* First we need to resolve name to a branch */
625 0 0         if (git_branch_lookup(&upstream, repo, branch_name, GIT_BRANCH_LOCAL) == 0)
626 0           local = 1;
627 0 0         else if (git_branch_lookup(&upstream, repo, branch_name, GIT_BRANCH_REMOTE) == 0)
628 0           local = 0;
629             else {
630 0           git_error_set(GIT_ERROR_REFERENCE,
631             "cannot set upstream for branch '%s'", shortname);
632 0           return GIT_ENOTFOUND;
633             }
634              
635             /*
636             * If it's a local-tracking branch, its remote is "." (as "the local
637             * repository"), and the branch name is simply the refname.
638             * Otherwise we need to figure out what the remote-tracking branch's
639             * name on the remote is and use that.
640             */
641 0 0         if (local)
642 0           error = git_buf_puts(&remote_name, ".");
643             else
644 0           error = git_branch_remote_name(&remote_name, repo, git_reference_name(upstream));
645              
646 0 0         if (error < 0)
647 0           goto on_error;
648              
649             /* Update the upsteam branch config with the new name */
650 0 0         if (git_buf_printf(&key, "branch.%s.remote", shortname) < 0)
651 0           goto on_error;
652              
653 0 0         if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&remote_name)) < 0)
654 0           goto on_error;
655              
656 0 0         if (local) {
657             /* A local branch uses the upstream refname directly */
658 0 0         if (git_buf_puts(&merge_refspec, git_reference_name(upstream)) < 0)
659 0           goto on_error;
660             } else {
661             /* We transform the upstream branch name according to the remote's refspecs */
662 0 0         if (git_remote_lookup(&remote, repo, git_buf_cstr(&remote_name)) < 0)
663 0           goto on_error;
664              
665 0           fetchspec = git_remote__matching_dst_refspec(remote, git_reference_name(upstream));
666 0 0         if (!fetchspec || git_refspec_rtransform(&merge_refspec, fetchspec, git_reference_name(upstream)) < 0)
    0          
667             goto on_error;
668              
669 0           git_remote_free(remote);
670 0           remote = NULL;
671             }
672              
673             /* Update the merge branch config with the refspec */
674 0           git_buf_clear(&key);
675 0 0         if (git_buf_printf(&key, "branch.%s.merge", shortname) < 0)
676 0           goto on_error;
677              
678 0 0         if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&merge_refspec)) < 0)
679 0           goto on_error;
680              
681 0           git_reference_free(upstream);
682 0           git_buf_dispose(&key);
683 0           git_buf_dispose(&remote_name);
684 0           git_buf_dispose(&merge_refspec);
685              
686 0           return 0;
687              
688             on_error:
689 0           git_reference_free(upstream);
690 0           git_buf_dispose(&key);
691 0           git_buf_dispose(&remote_name);
692 0           git_buf_dispose(&merge_refspec);
693 0           git_remote_free(remote);
694              
695 0           return -1;
696             }
697              
698 1           int git_branch_is_head(
699             const git_reference *branch)
700             {
701             git_reference *head;
702 1           bool is_same = false;
703             int error;
704              
705 1 50         assert(branch);
706              
707 1 50         if (!git_reference_is_branch(branch))
708 0           return false;
709              
710 1           error = git_repository_head(&head, git_reference_owner(branch));
711              
712 1 50         if (error == GIT_EUNBORNBRANCH || error == GIT_ENOTFOUND)
    50          
713 0           return false;
714              
715 1 50         if (error < 0)
716 0           return -1;
717              
718 1           is_same = strcmp(
719             git_reference_name(branch),
720             git_reference_name(head)) == 0;
721              
722 1           git_reference_free(head);
723              
724 1           return is_same;
725             }