summaryrefslogtreecommitdiff
path: root/builtin/pack-objects.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/pack-objects.c')
-rw-r--r--builtin/pack-objects.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 97802585ea..b0503b202a 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -16,22 +16,18 @@
#include "list-objects.h"
#include "progress.h"
#include "refs.h"
-
-#ifndef NO_PTHREADS
#include "thread-utils.h"
-#include <pthread.h>
-#endif
static const char pack_usage[] =
- "git pack-objects [{ -q | --progress | --all-progress }]\n"
+ "git pack-objects [ -q | --progress | --all-progress ]\n"
" [--all-progress-implied]\n"
- " [--max-pack-size=N] [--local] [--incremental]\n"
- " [--window=N] [--window-memory=N] [--depth=N]\n"
+ " [--max-pack-size=<n>] [--local] [--incremental]\n"
+ " [--window=<n>] [--window-memory=<n>] [--depth=<n>]\n"
" [--no-reuse-delta] [--no-reuse-object] [--delta-base-offset]\n"
- " [--threads=N] [--non-empty] [--revs [--unpacked | --all]*]\n"
+ " [--threads=<n>] [--non-empty] [--revs [--unpacked | --all]]\n"
" [--reflog] [--stdout | base-name] [--include-tag]\n"
- " [--keep-unreachable | --unpack-unreachable \n"
- " [<ref-list | <object-list]";
+ " [--keep-unreachable | --unpack-unreachable]\n"
+ " [< ref-list | < object-list]";
struct object_entry {
struct pack_idx_entry idx;
@@ -431,7 +427,7 @@ static int write_one(struct sha1file *f,
written_list[nr_written++] = &e->idx;
/* make sure off_t is sufficiently large not to wrap */
- if (*offset > *offset + size)
+ if (signed_add_overflows(*offset, size))
die("pack too large for current definition of off_t");
*offset += size;
return 1;
@@ -1298,9 +1294,23 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
read_lock();
src->data = read_sha1_file(src_entry->idx.sha1, &type, &sz);
read_unlock();
- if (!src->data)
+ if (!src->data) {
+ if (src_entry->preferred_base) {
+ static int warned = 0;
+ if (!warned++)
+ warning("object %s cannot be read",
+ sha1_to_hex(src_entry->idx.sha1));
+ /*
+ * Those objects are not included in the
+ * resulting pack. Be resilient and ignore
+ * them if they can't be read, in case the
+ * pack could be created nevertheless.
+ */
+ return 0;
+ }
die("object %s cannot be read",
sha1_to_hex(src_entry->idx.sha1));
+ }
if (sz != src_size)
die("object %s inconsistent object length (%lu vs %lu)",
sha1_to_hex(src_entry->idx.sha1), sz, src_size);
@@ -1522,6 +1532,15 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
#ifndef NO_PTHREADS
+static void try_to_free_from_threads(size_t size)
+{
+ read_lock();
+ release_pack_memory(size, -1);
+ read_unlock();
+}
+
+static try_to_free_t old_try_to_free_routine;
+
/*
* The main thread waits on the condition that (at least) one of the workers
* has stopped working (which is indicated in the .working member of
@@ -1552,14 +1571,16 @@ static pthread_cond_t progress_cond;
*/
static void init_threaded_search(void)
{
- pthread_mutex_init(&read_mutex, NULL);
+ init_recursive_mutex(&read_mutex);
pthread_mutex_init(&cache_mutex, NULL);
pthread_mutex_init(&progress_mutex, NULL);
pthread_cond_init(&progress_cond, NULL);
+ old_try_to_free_routine = set_try_to_free_routine(try_to_free_from_threads);
}
static void cleanup_threaded_search(void)
{
+ set_try_to_free_routine(old_try_to_free_routine);
pthread_cond_destroy(&progress_cond);
pthread_mutex_destroy(&read_mutex);
pthread_mutex_destroy(&cache_mutex);