diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c
index e9d16e631585c3795ee628ec33997548a01a01b4..12adb3833cd60771f8e63b2ebaecff3769fa74e2 100644 (file)
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
#include "refs.h"
#include "commit.h"
-#define CHUNK_SIZE (1048576)
+#define CHUNK_SIZE 1024
static char *get_stdin(void)
{
+ size_t offset = 0;
char *data = xmalloc(CHUNK_SIZE);
- int offset = 0, read = 0;
- read = xread(0, data, CHUNK_SIZE);
- while (read == CHUNK_SIZE) {
- offset += CHUNK_SIZE;
+
+ while (1) {
+ ssize_t cnt = xread(0, data + offset, CHUNK_SIZE);
+ if (cnt < 0)
+ die("error reading standard input: %s",
+ strerror(errno));
+ if (cnt == 0) {
+ data[offset] = 0;
+ break;
+ }
+ offset += cnt;
data = xrealloc(data, offset + CHUNK_SIZE);
- read = xread(0, data + offset, CHUNK_SIZE);
}
return data;
}
unsigned char *sha1,
unsigned char *oldval)
{
- int len;
char msg[1024];
char *rla = getenv("GIT_REFLOG_ACTION");
static struct ref_lock *lock;
if (!rla)
rla = "(reflog update)";
- len = snprintf(msg, sizeof(msg), "%s: %s", rla, action);
- if (sizeof(msg) <= len)
- die("insanely long action");
+ snprintf(msg, sizeof(msg), "%s: %s", rla, action);
lock = lock_any_ref_for_update(refname, oldval);
if (!lock)
return 1;
remote_len = i + 1;
if (4 < i && !strncmp(".git", remote + i - 3, 4))
remote_len = i - 3;
- note_len = sprintf(note, "%s\t%s\t",
- sha1_to_hex(commit ? commit->object.sha1 : sha1),
- not_for_merge ? "not-for-merge" : "");
+
+ note_len = 0;
if (*what) {
if (*kind)
note_len += sprintf(note + note_len, "%s ", kind);
note_len += sprintf(note + note_len, "'%s' of ", what);
}
note_len += sprintf(note + note_len, "%.*s", remote_len, remote);
- fprintf(fp, "%s\n", note);
+ fprintf(fp, "%s\t%s\t%s\n",
+ sha1_to_hex(commit ? commit->object.sha1 : sha1),
+ not_for_merge ? "not-for-merge" : "",
+ note);
return update_local_ref(local_name, head, note, verbose, force);
}
eol = !next ? (ls + strlen(ls)) : next;
if (!memcmp("^{}", eol-3, 3))
continue;
+ if (eol - ls < 40)
+ continue;
if (get_sha1_hex(ls, sha1))
continue;
ls += 40;
return 0;
}
+static int pick_rref(int sha1_only, const char *rref, const char *ls_remote_result)
+{
+ int err = 0;
+ int lrr_count = lrr_count, i, pass;
+ const char *cp;
+ struct lrr {
+ const char *line;
+ const char *name;
+ int namelen;
+ int shown;
+ } *lrr_list = lrr_list;
+
+ for (pass = 0; pass < 2; pass++) {
+ /* pass 0 counts and allocates, pass 1 fills... */
+ cp = ls_remote_result;
+ i = 0;
+ while (1) {
+ const char *np;
+ while (*cp && isspace(*cp))
+ cp++;
+ if (!*cp)
+ break;
+ np = strchr(cp, '\n');
+ if (!np)
+ np = cp + strlen(cp);
+ if (pass) {
+ lrr_list[i].line = cp;
+ lrr_list[i].name = cp + 41;
+ lrr_list[i].namelen = np - (cp + 41);
+ }
+ i++;
+ cp = np;
+ }
+ if (!pass) {
+ lrr_count = i;
+ lrr_list = xcalloc(lrr_count, sizeof(*lrr_list));
+ }
+ }
+
+ while (1) {
+ const char *next;
+ int rreflen;
+ int i;
+
+ while (*rref && isspace(*rref))
+ rref++;
+ if (!*rref)
+ break;
+ next = strchr(rref, '\n');
+ if (!next)
+ next = rref + strlen(rref);
+ rreflen = next - rref;
+
+ for (i = 0; i < lrr_count; i++) {
+ struct lrr *lrr = &(lrr_list[i]);
+
+ if (rreflen == lrr->namelen &&
+ !memcmp(lrr->name, rref, rreflen)) {
+ if (!lrr->shown)
+ printf("%.*s\n",
+ sha1_only ? 40 : lrr->namelen + 41,
+ lrr->line);
+ lrr->shown = 1;
+ break;
+ }
+ }
+ if (lrr_count <= i) {
+ error("pick-rref: %.*s not found", rreflen, rref);
+ err = 1;
+ }
+ rref = next;
+ }
+ free(lrr_list);
+ return err;
+}
+
int cmd_fetch__tool(int argc, const char **argv, const char *prefix)
{
int verbose = 0;
int force = 0;
+ int sopt = 0;
while (1 < argc) {
const char *arg = argv[1];
verbose = 1;
else if (!strcmp("-f", arg))
force = 1;
+ else if (!strcmp("-s", arg))
+ sopt = 1;
else
break;
argc--;
fclose(fp);
return result;
}
- if (!strcmp("update-local-ref", argv[1])) {
- if (argc != 5)
- return error("update-local-ref takes 3 args");
- return update_local_ref(argv[2], argv[3], argv[4],
- verbose, force);
- }
if (!strcmp("native-store", argv[1])) {
int result;
FILE *fp;
reflist = get_stdin();
return parse_reflist(reflist);
}
+ if (!strcmp("pick-rref", argv[1])) {
+ const char *ls_remote_result;
+ if (argc != 4)
+ return error("pick-rref takes 2 args");
+ ls_remote_result = argv[3];
+ if (!strcmp(ls_remote_result, "-"))
+ ls_remote_result = get_stdin();
+ return pick_rref(sopt, argv[2], ls_remote_result);
+ }
if (!strcmp("expand-refs-wildcard", argv[1])) {
const char *reflist;
if (argc < 4)