<commit_before>#include "builtin.h"
#include "cache.h"
#include "object.h"
#include "commit.h"
#include "diff.h"
#include "revision.h"
#include "list-objects.h"
#include "run-command.h"

/*
 * Basic handler for bundle files to connect repositories via sneakernet.
 * Invocation must include action.
 * This function can create a bundle or provide information on an existing
 * bundle supporting git-fetch, git-pull, and git-ls-remote
 */

static const char *bundle_usage="git-bundle (create <bundle> <git-rev-list args> | verify <bundle> | list-heads <bundle> [refname]... | unbundle <bundle> [refname]... )";

static const char bundle_signature[] = "# v2 git bundle\n";

struct ref_list {
	unsigned int nr, alloc;
	struct ref_list_entry {
		unsigned char sha1[20];
		char *name;
	} *list;
};

static void add_to_ref_list(const unsigned char *sha1, const char *name,
		struct ref_list *list)
{
	if (list->nr + 1 >= list->alloc) {
		list->alloc = alloc_nr(list->nr + 1);
		list->list = xrealloc(list->list,
				list->alloc * sizeof(list->list[0]));
	}
	memcpy(list->list[list->nr].sha1, sha1, 20);
	list->list[list->nr].name = xstrdup(name);
	list->nr++;
}

struct bundle_header {
	struct ref_list prerequisites;
	struct ref_list references;
};

/* this function returns the length of the string */
static int read_string(int fd, char *buffer, int size)
{
	int i;
	for (i = 0; i < size - 1; i++) {
		ssize_t count = xread(fd, buffer + i, 1);
		if (count < 0)
			return error("Read error: %s", strerror(errno));
		if (count == 0) {
			i--;
			break;
		}
		if (buffer[i] == '\n')
			break;
	}
	buffer[i + 1] = '\0';
	return i + 1;
}

/* returns an fd */
static int read_header(const char *path, struct bundle_header *header) {
	char buffer[1024];
	int fd = open(path, O_RDONLY);

	if (fd < 0)
		return error("could not open '%s'", path);
	if (read_string(fd, buffer, sizeof(buffer)) < 0 ||
			strcmp(buffer, bundle_signature)) {
		close(fd);
		return error("'%s' does not look like a v2 bundle file", path);
	}
	while (read_string(fd, buffer, sizeof(buffer)) > 0
			&& buffer[0] != '\n') {
		int is_prereq = buffer[0] == '-';
		int offset = is_prereq ? 1 : 0;
		int len = strlen(buffer);
		unsigned char sha1[20];
		struct ref_list *list = is_prereq ? &header->prerequisites
			: &header->references;
		char delim;

		if (buffer[len - 1] == '\n')
			buffer[len - 1] = '\0';
		if (get_sha1_hex(buffer + offset, sha1)) {
			warning("unrecognized header: %s", buffer);
			continue;
		}
		delim = buffer[40 + offset];
		if (!isspace(delim) && (delim != '\0' || !is_prereq))
			die ("invalid header: %s", buffer);
		add_to_ref_list(sha1, isspace(delim) ?
				buffer + 41 + offset : "", list);
	}
	return fd;
}

static int list_refs(struct ref_list *r, int argc, const char **argv)
{
	int i;

	for (i = 0; i < r->nr; i++) {
		if (argc > 1) {
			int j;
			for (j = 1; j < argc; j++)
				if (!strcmp(r->list[i].name, argv[j]))
					break;<commit_msg>builtin-bundle - use buffered reads for bundle header<commit_after>#include "builtin.h"
#include "cache.h"
#include "object.h"
#include "commit.h"
#include "diff.h"
#include "revision.h"
#include "list-objects.h"
#include "run-command.h"

/*
 * Basic handler for bundle files to connect repositories via sneakernet.
 * Invocation must include action.
 * This function can create a bundle or provide information on an existing
 * bundle supporting git-fetch, git-pull, and git-ls-remote
 */

static const char *bundle_usage="git-bundle (create <bundle> <git-rev-list args> | verify <bundle> | list-heads <bundle> [refname]... | unbundle <bundle> [refname]... )";

static const char bundle_signature[] = "# v2 git bundle\n";

struct ref_list {
	unsigned int nr, alloc;
	struct ref_list_entry {
		unsigned char sha1[20];
		char *name;
	} *list;
};

static void add_to_ref_list(const unsigned char *sha1, const char *name,
		struct ref_list *list)
{
	if (list->nr + 1 >= list->alloc) {
		list->alloc = alloc_nr(list->nr + 1);
		list->list = xrealloc(list->list,
				list->alloc * sizeof(list->list[0]));
	}
	memcpy(list->list[list->nr].sha1, sha1, 20);
	list->list[list->nr].name = xstrdup(name);
	list->nr++;
}

struct bundle_header {
	struct ref_list prerequisites;
	struct ref_list references;
};

/* returns an fd */
static int read_header(const char *path, struct bundle_header *header) {
	char buffer[1024];
	int fd;
	long fpos;
	FILE *ffd = fopen(path, "rb");

	if (!ffd)
		return error("could not open '%s'", path);
	if (!fgets(buffer, sizeof(buffer), ffd) ||
			strcmp(buffer, bundle_signature)) {
		fclose(ffd);
		return error("'%s' does not look like a v2 bundle file", path);
	}
	while (fgets(buffer, sizeof(buffer), ffd)
			&& buffer[0] != '\n') {
		int is_prereq = buffer[0] == '-';
		int offset = is_prereq ? 1 : 0;
		int len = strlen(buffer);
		unsigned char sha1[20];
		struct ref_list *list = is_prereq ? &header->prerequisites
			: &header->references;
		char delim;

		if (buffer[len - 1] == '\n')
			buffer[len - 1] = '\0';
		if (get_sha1_hex(buffer + offset, sha1)) {
			warning("unrecognized header: %s", buffer);
			continue;
		}
		delim = buffer[40 + offset];
		if (!isspace(delim) && (delim != '\0' || !is_prereq))
			die ("invalid header: %s", buffer);
		add_to_ref_list(sha1, isspace(delim) ?
				buffer + 41 + offset : "", list);
	}
	fpos = ftell(ffd);
	fclose(ffd);
	fd = open(path, O_RDONLY);
	if (fd < 0)
		return error("could not open '%s'", path);
	lseek(fd, fpos, SEEK_SET);
	return fd;
}

static int list_refs(struct ref_list *r, int argc, const char **argv)
{
	int i;

	for (i = 0; i < r->nr; i++) {
		if (argc > 1) {
			int j;
			for (j = 1; j < argc; j++)
				if (!strcmp(r->list[i].name, argv[j]))
					break;
{'fraction_non_alphanumeric': 0.1688951442646024, 'fraction_numerical': 0.015482054890921885, 'mean_word_length': 3.7613065326633164, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2434661', 'n_tokens_mistral': 2278, 'n_tokens_neox': 2079, 'n_words': 610}