Root/
| 1 | /* |
| 2 | * file/git-util.c - Git utility functions |
| 3 | * |
| 4 | * Written 2016 by Werner Almesberger |
| 5 | * Copyright 2016 by Werner Almesberger |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | */ |
| 12 | |
| 13 | #include <stdbool.h> |
| 14 | #include <assert.h> |
| 15 | |
| 16 | #include <git2.h> |
| 17 | |
| 18 | #include "file/git-util.h" |
| 19 | |
| 20 | |
| 21 | /* |
| 22 | * This seems to be an efficient way for finding out if a repo is dirty. |
| 23 | * |
| 24 | * http://ben.straub.cc/2013/04/02/libgit2-checkout/ |
| 25 | * |
| 26 | * References: |
| 27 | * https://libgit2.github.com/libgit2/#HEAD/group/checkout/git_checkout_index |
| 28 | * https://libgit2.github.com/libgit2/#HEAD/type/git_checkout_options |
| 29 | * https://github.com/libgit2/libgit2/blob/HEAD/include/git2/checkout.h#L251-295 |
| 30 | */ |
| 31 | |
| 32 | |
| 33 | static int checkout_notify_cb(git_checkout_notify_t why, |
| 34 | const char *path, const git_diff_file *baseline, |
| 35 | const git_diff_file *target, const git_diff_file *workdir, |
| 36 | void *payload) |
| 37 | { |
| 38 | bool *res = payload; |
| 39 | |
| 40 | assert(why == GIT_CHECKOUT_NOTIFY_DIRTY); |
| 41 | |
| 42 | *res = 1; |
| 43 | return 0; |
| 44 | } |
| 45 | |
| 46 | |
| 47 | bool git_repo_is_dirty(git_repository *repo) |
| 48 | { |
| 49 | git_checkout_options opts; |
| 50 | bool res = 0; |
| 51 | |
| 52 | /* |
| 53 | * Initialization with GIT_CHECKOUT_OPTIONS_INIT complains about not |
| 54 | * setting checkout_strategy. git_checkout_init_options is fine. |
| 55 | */ |
| 56 | git_checkout_init_options(&opts, GIT_CHECKOUT_OPTIONS_VERSION); |
| 57 | opts.checkout_strategy = GIT_CHECKOUT_NONE; |
| 58 | /* let's be explicit about this */ |
| 59 | opts.notify_flags = GIT_CHECKOUT_NOTIFY_DIRTY; |
| 60 | opts.notify_cb = checkout_notify_cb; |
| 61 | opts.notify_payload = &res; |
| 62 | git_checkout_index(repo, NULL, &opts); |
| 63 | |
| 64 | return res; |
| 65 | } |
| 66 | |
| 67 | |
| 68 | /* |
| 69 | * Git documentation says that git_libgit2_init can be called more then once |
| 70 | * but doesn't quite what happens then, e.g., whether references obtained |
| 71 | * before an init (except for the first, of course) can still be used after |
| 72 | * it. So we play it safe and initialize only once. |
| 73 | */ |
| 74 | |
| 75 | void git_init_once(void) |
| 76 | { |
| 77 | static bool initialized = 0; |
| 78 | |
| 79 | if (!initialized) { |
| 80 | #if LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR < 22 |
| 81 | git_threads_init(); |
| 82 | #else |
| 83 | git_libgit2_init(); |
| 84 | #endif |
| 85 | initialized = 1; |
| 86 | } |
| 87 | } |
| 88 |
Branches:
master
