зеркало из https://github.com/microsoft/git.git
Merge branch 'jk/write-packed-refs-via-stdio'
Optimize the code path to write out the packed-refs file, which especially matters in a repository with a large number of refs. * jk/write-packed-refs-via-stdio: refs: write packed_refs file using stdio
This commit is contained in:
Коммит
69a5bbbbfa
2
cache.h
2
cache.h
|
@ -1430,6 +1430,8 @@ extern const char *git_mailmap_blob;
|
|||
|
||||
/* IO helper functions */
|
||||
extern void maybe_flush_or_die(FILE *, const char *);
|
||||
__attribute__((format (printf, 2, 3)))
|
||||
extern void fprintf_or_die(FILE *, const char *fmt, ...);
|
||||
extern int copy_fd(int ifd, int ofd);
|
||||
extern int copy_file(const char *dst, const char *src, int mode);
|
||||
extern int copy_file_with_time(const char *dst, const char *src, int mode);
|
||||
|
|
39
refs.c
39
refs.c
|
@ -2190,25 +2190,12 @@ struct ref_lock *lock_any_ref_for_update(const char *refname,
|
|||
* Write an entry to the packed-refs file for the specified refname.
|
||||
* If peeled is non-NULL, write it as the entry's peeled value.
|
||||
*/
|
||||
static void write_packed_entry(int fd, char *refname, unsigned char *sha1,
|
||||
static void write_packed_entry(FILE *fh, char *refname, unsigned char *sha1,
|
||||
unsigned char *peeled)
|
||||
{
|
||||
char line[PATH_MAX + 100];
|
||||
int len;
|
||||
|
||||
len = snprintf(line, sizeof(line), "%s %s\n",
|
||||
sha1_to_hex(sha1), refname);
|
||||
/* this should not happen but just being defensive */
|
||||
if (len > sizeof(line))
|
||||
die("too long a refname '%s'", refname);
|
||||
write_or_die(fd, line, len);
|
||||
|
||||
if (peeled) {
|
||||
if (snprintf(line, sizeof(line), "^%s\n",
|
||||
sha1_to_hex(peeled)) != PEELED_LINE_LENGTH)
|
||||
die("internal error");
|
||||
write_or_die(fd, line, PEELED_LINE_LENGTH);
|
||||
}
|
||||
fprintf_or_die(fh, "%s %s\n", sha1_to_hex(sha1), refname);
|
||||
if (peeled)
|
||||
fprintf_or_die(fh, "^%s\n", sha1_to_hex(peeled));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2216,13 +2203,12 @@ static void write_packed_entry(int fd, char *refname, unsigned char *sha1,
|
|||
*/
|
||||
static int write_packed_entry_fn(struct ref_entry *entry, void *cb_data)
|
||||
{
|
||||
int *fd = cb_data;
|
||||
enum peel_status peel_status = peel_entry(entry, 0);
|
||||
|
||||
if (peel_status != PEEL_PEELED && peel_status != PEEL_NON_TAG)
|
||||
error("internal error: %s is not a valid packed reference!",
|
||||
entry->name);
|
||||
write_packed_entry(*fd, entry->name, entry->u.value.sha1,
|
||||
write_packed_entry(cb_data, entry->name, entry->u.value.sha1,
|
||||
peel_status == PEEL_PEELED ?
|
||||
entry->u.value.peeled : NULL);
|
||||
return 0;
|
||||
|
@ -2258,15 +2244,22 @@ int commit_packed_refs(void)
|
|||
get_packed_ref_cache(&ref_cache);
|
||||
int error = 0;
|
||||
int save_errno = 0;
|
||||
FILE *out;
|
||||
|
||||
if (!packed_ref_cache->lock)
|
||||
die("internal error: packed-refs not locked");
|
||||
write_or_die(packed_ref_cache->lock->fd,
|
||||
PACKED_REFS_HEADER, strlen(PACKED_REFS_HEADER));
|
||||
|
||||
out = fdopen(packed_ref_cache->lock->fd, "w");
|
||||
if (!out)
|
||||
die_errno("unable to fdopen packed-refs descriptor");
|
||||
|
||||
fprintf_or_die(out, "%s", PACKED_REFS_HEADER);
|
||||
do_for_each_entry_in_dir(get_packed_ref_dir(packed_ref_cache),
|
||||
0, write_packed_entry_fn,
|
||||
&packed_ref_cache->lock->fd);
|
||||
0, write_packed_entry_fn, out);
|
||||
if (fclose(out))
|
||||
die_errno("write error");
|
||||
packed_ref_cache->lock->fd = -1;
|
||||
|
||||
if (commit_lock_file(packed_ref_cache->lock)) {
|
||||
save_errno = errno;
|
||||
error = -1;
|
||||
|
|
|
@ -49,6 +49,21 @@ void maybe_flush_or_die(FILE *f, const char *desc)
|
|||
}
|
||||
}
|
||||
|
||||
void fprintf_or_die(FILE *f, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = vfprintf(f, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (ret < 0) {
|
||||
check_pipe(errno);
|
||||
die_errno("write error");
|
||||
}
|
||||
}
|
||||
|
||||
void fsync_or_die(int fd, const char *msg)
|
||||
{
|
||||
if (fsync(fd) < 0) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче