Read git diff.context option
[tig.git] / src / repo.c
blobeb8c06c87cd67faafd083ae90198531e94e6cd34
1 /* Copyright (c) 2006-2014 Jonas Fonseca <jonas.fonseca@gmail.com>
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License as
5 * published by the Free Software Foundation; either version 2 of
6 * the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include "tig/tig.h"
15 #include "tig/repo.h"
16 #include "tig/io.h"
17 #include "tig/refdb.h"
19 #define REPO_INFO_GIT_DIR "--git-dir"
20 #define REPO_INFO_WORK_TREE "--is-inside-work-tree"
21 #define REPO_INFO_SHOW_CDUP "--show-cdup"
22 #define REPO_INFO_SHOW_PREFIX "--show-prefix"
23 #define REPO_INFO_SYMBOLIC_HEAD "--symbolic-full-name"
24 #define REPO_INFO_RESOLVED_HEAD "HEAD"
26 struct repo_info_state {
27 const char **argv;
28 char head_id[SIZEOF_REV];
31 static int
32 read_repo_info(char *name, size_t namelen, char *value, size_t valuelen, void *data)
34 struct repo_info_state *state = data;
35 const char *arg = *state->argv ? *state->argv++ : "";
37 if (!strcmp(arg, REPO_INFO_GIT_DIR)) {
38 string_ncopy(repo.git_dir, name, namelen);
40 } else if (!strcmp(arg, REPO_INFO_WORK_TREE)) {
41 /* This can be 3 different values depending on the
42 * version of git being used. If git-rev-parse does not
43 * understand --is-inside-work-tree it will simply echo
44 * the option else either "true" or "false" is printed.
45 * Default to true for the unknown case. */
46 repo.is_inside_work_tree = strcmp(name, "false") ? TRUE : FALSE;
48 } else if (!strcmp(arg, REPO_INFO_SHOW_CDUP)) {
49 string_ncopy(repo.cdup, name, namelen);
51 } else if (!strcmp(arg, REPO_INFO_SHOW_PREFIX)) {
52 /* Some versions of Git does not emit anything for --show-prefix
53 * when the user is in the repository root directory. Try to detect
54 * this special case by looking at the emitted value. If it looks
55 * like a commit ID and there's no cdup path assume that no value
56 * was emitted. */
57 if (!*repo.cdup && namelen == 40 && iscommit(name))
58 return read_repo_info(name, namelen, value, valuelen, data);
60 string_ncopy(repo.prefix, name, namelen);
62 } else if (!strcmp(arg, REPO_INFO_RESOLVED_HEAD)) {
63 string_ncopy(state->head_id, name, namelen);
65 } else if (!strcmp(arg, REPO_INFO_SYMBOLIC_HEAD)) {
66 if (!prefixcmp(name, "refs/heads/")) {
67 char *offset = name + STRING_SIZE("refs/heads/");
69 string_ncopy(repo.head, offset, strlen(offset) + 1);
70 add_ref(state->head_id, name, repo.remote, repo.head);
72 state->argv++;
75 return OK;
78 int
79 load_repo_info(void)
81 const char *rev_parse_argv[] = {
82 "git", "rev-parse", REPO_INFO_GIT_DIR, REPO_INFO_WORK_TREE,
83 REPO_INFO_SHOW_CDUP, REPO_INFO_SHOW_PREFIX, \
84 REPO_INFO_RESOLVED_HEAD, REPO_INFO_SYMBOLIC_HEAD, "HEAD",
85 NULL
87 struct repo_info_state state = { rev_parse_argv + 2 };
89 return io_run_load(rev_parse_argv, "=", read_repo_info, &state);
92 struct repo_info repo;
94 /* vim: set ts=8 sw=8 noexpandtab: */