1 /* Copyright (c) 2006-2013 Jonas Fonseca <fonseca@diku.dk>
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.
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
{
28 char head_id
[SIZEOF_REV
];
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 string_ncopy(repo
.prefix
, name
, namelen
);
54 } else if (!strcmp(arg
, REPO_INFO_RESOLVED_HEAD
)) {
55 string_ncopy(state
->head_id
, name
, namelen
);
57 } else if (!strcmp(arg
, REPO_INFO_SYMBOLIC_HEAD
)) {
58 if (!prefixcmp(name
, "refs/heads/")) {
59 char *offset
= name
+ STRING_SIZE("refs/heads/");
61 string_ncopy(repo
.head
, offset
, strlen(offset
) + 1);
62 add_ref(state
->head_id
, name
, repo
.remote
, repo
.head
);
73 const char *rev_parse_argv
[] = {
74 "git", "rev-parse", REPO_INFO_GIT_DIR
, REPO_INFO_WORK_TREE
,
75 REPO_INFO_SHOW_CDUP
, REPO_INFO_SHOW_PREFIX
, \
76 REPO_INFO_RESOLVED_HEAD
, REPO_INFO_SYMBOLIC_HEAD
, "HEAD",
79 struct repo_info_state state
= { rev_parse_argv
+ 2 };
81 return io_run_load(rev_parse_argv
, "=", read_repo_info
, &state
);
84 struct repo_info repo
;
86 /* vim: set ts=8 sw=8 noexpandtab: */