static result_t* cvs_get_info(vccontext_t* context) { result_t* result = init_result(context->options); char buf[1024]; if (!read_first_line("CVS/Tag", buf, 1024)) { debug("unable to read CVS/Tag: assuming trunk"); result_set_branch(result, "trunk"); } else { debug("read first line of CVS/Tag: '%s'", buf); if (buf[0] == 'T') { /* there is a sticky tag and it's a branch tag */ result_set_branch(result, buf + 1); } else { /* non-branch sticky tag or sticky date */ } } return result; }
static result_t* hg_get_info(vccontext_t* context) { result_t* result = init_result(context->options); char buf[1024]; // prefers bookmark because it tends to be more informative if (read_first_line(".hg/bookmarks.current", buf, 1024) && buf[0]) { debug("read first line from .hg/bookmarks.current: '%s'", buf); result_set_branch(result, buf); } else if (read_first_line(".hg/branch", buf, 1024)) { debug("read first line from .hg/branch: '%s'", buf); result_set_branch(result, buf); } else { debug("failed to read from .hg/branch: assuming default branch"); result_set_branch(result, "default"); } update_nodeid(context, result); return result; }
static result_t* fossil_get_info(vccontext_t *context) { result_t *result = init_result(); char *t; int tab_len = 14; char buf2[81]; // Since fossil stores info in SQLite databases, we're going to read // the output of 'fossil status' command and analyze it. We need // enough to cover all the usual fields (note that 'comment:' can be // several lines long) plus eventual output indicating changes in // the repo. char *argv[] = {"fossil", "status", NULL}; capture_t *capture = capture_child("fossil", argv); if (capture == NULL) { debug("unable to execute 'fossil status'"); return NULL; } char *cstdout = capture->childout.buf; if (context->options->show_branch) { if ((t = strstr(cstdout, "\ntags:"))) { // This in fact shows also other tags than just the // propagating ones (=branches). So either we show all // of them (as now), or we can show only the first one // (which should be the branch name); or we use one more // child process to read the output of 'fossil branch'. get_till_eol(buf2, t + tab_len + 1, 80); debug("found tag line: '%s'", buf2); result_set_branch(result, buf2); } else { debug("tag line not found in fossil output; unknown branch"); result_set_branch(result, "(unknown)"); } } if (context->options->show_revision) { if ((t = strstr(cstdout, "\ncheckout:"))) { get_till_eol(buf2, t + tab_len + 1, 80); debug("found revision line: '%s'", buf2); result_set_revision(result, buf2, 12); } else { debug("revision line not found in fossil output; unknown revision"); result_set_revision(result, "unknown", 7); } } if (context->options->show_modified) { // This can be also done by checking if 'fossil changes' // prints anything, but we save a child process this way. result->modified = (strstr(cstdout, "\nEDITED") || strstr(cstdout, "\nADDED") || strstr(cstdout, "\nDELETED") || strstr(cstdout, "\nMISSING") || strstr(cstdout, "\nRENAMED") || strstr(cstdout, "\nNOT_A_FILE") || strstr(cstdout, "\nUPDATED") || strstr(cstdout, "\nMERGED")); } cstdout = NULL; free_capture(capture); if (context->options->show_unknown) { // This can't be read from 'fossil status' output char *argv[] = {"fossil", "extra", NULL}; capture = capture_child("fossil", argv); if (capture == NULL) { debug("unable to execute 'fossil extra'"); return NULL; } result->unknown = (capture->childout.len > 0); free_capture(capture); } return result; }
static result_t* git_get_info(vccontext_t *context) { result_t *result = init_result(); char buf[1024]; if (!read_first_line(".git/HEAD", buf, 1024)) { debug("unable to read .git/HEAD: assuming not a git repo"); goto err; } char *prefix = "ref: refs/heads/"; int prefixlen = strlen(prefix); if (context->options->show_branch || context->options->show_revision) { int found_branch = 0; if (strncmp(prefix, buf, prefixlen) == 0) { /* yep, we're on a known branch */ debug("read a head ref from .git/HEAD: '%s'", buf); if (result_set_branch(result, buf + prefixlen)) found_branch = 1; } else { /* if it's not a branch name, assume it is a commit ID */ debug(".git/HEAD doesn't look like a head ref: unknown branch"); result_set_branch(result, "(unknown)"); result_set_revision(result, buf, 12); } if (context->options->show_revision && found_branch) { char buf[1024]; char filename[1024] = ".git/refs/heads/"; int nchars = sizeof(filename) - strlen(filename) - 1; strncat(filename, result->branch, nchars); if (read_first_line(filename, buf, 1024)) { result_set_revision(result, buf, 12); } } } if (context->options->show_modified) { char *argv[] = { "git", "diff", "--no-ext-diff", "--quiet", "--exit-code", NULL}; capture_t *capture = capture_child("git", argv); result->modified = (capture->status == 1); /* any other outcome (including failure to fork/exec, failure to run git, or diff error): assume no modifications */ free_capture(capture); } if (context->options->show_staged) { //git diff --name-only --cached int status = system("git diff --cached --no-ext-diff --quiet --exit-code"); if (WEXITSTATUS(status) == 1) /* files modified */ result->staged = 1; /* any other outcome (including failure to fork/exec, failure to run git, or diff error): assume no modifications */ } if (context->options->show_unknown) { char *argv[] = { "git", "ls-files", "--others", "--exclude-standard", NULL}; capture_t *capture = capture_child("git", argv); result->unknown = (capture != NULL && capture->childout.len > 0); /* again, ignore other errors and assume no unknown files */ free_capture(capture); } return result; err: free_result(result); return NULL; }