static void update_nodeid(vccontext_t* context, result_t* result) { char buf[NODEID_LEN * 2]; size_t readsize; if (!context->options->show_revision) return; readsize = read_file(".hg/dirstate", buf, NODEID_LEN * 2); if (readsize == NODEID_LEN * 2) { char destbuf[1024] = {'\0'}; char* p = destbuf; debug("read nodeids from .hg/dirstate"); // first parent if (sum_bytes((unsigned char *) buf, NODEID_LEN)) { p += put_nodeid(p, buf); } // second parent if (sum_bytes((unsigned char *) buf + NODEID_LEN, NODEID_LEN)) { *p = ','; ++p; p += put_nodeid(p, buf + NODEID_LEN); } result_set_revision(result, destbuf, -1); } else { debug("failed to read from .hg/dirstate"); } }
static int svn_read_xml(FILE *fp, char line[], int size, int line_num, result_t *result) { char rev[100]; char *marker = "revision="; char *p = NULL; while (fgets(line, size, fp)) { if ((p = strstr(line, marker)) != NULL) { break; } } if (p == NULL) { debug("no 'revision=' line found in .svn/entries"); return 0; } if (sscanf(p, " %*[^\"]\"%[0-9]\"", rev) == 1) { result_set_revision(result, rev, -1); debug("read svn revision from .svn/entries: '%s'", rev); } return 1; }
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; }