pack-objects: use of version 3 delta is now optional.

This introduces a new configuration item, pack.deltaversion, to
control whether pack-objects is allowed to use version 3 delta.
By default, we keep generating version 2 delta (and version 2
packfile format) to be compatible with git earlier than v1.2.0.

This configuration affects the command in the following ways:

 - the resulting packfile will have the specified version;

 - when generating delta, larger copies are allowed only when
   deltaversion is 3;

 - the logic to reuse delta from existing packs refuses to reuse
   delta from packs that uses delta version 3 when the
   configuration is set to 2.

Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Junio C Hamano
2006-10-15 00:34:47 -07:00
parent 29f049a0c2
commit 394737eb42
6 changed files with 33 additions and 6 deletions

View File

@@ -456,7 +456,7 @@ static void write_pack_file(void)
fprintf(stderr, "Writing %d objects.\n", nr_result);
hdr.hdr_signature = htonl(PACK_SIGNATURE);
hdr.hdr_version = htonl(PACK_VERSION);
hdr.hdr_version = htonl(delta_version);
hdr.hdr_entries = htonl(nr_result);
sha1write(f, &hdr, sizeof(hdr));
offset = sizeof(hdr);
@@ -914,12 +914,15 @@ static void check_object(struct object_entry *entry)
/* Check if it is delta, and the base is also an object
* we are going to pack. If so we will reuse the existing
* delta.
*
* Also make sure that we do not reuse delta from an existing
* pack that uses higher delta version than allowed.
*/
if (!no_reuse_delta &&
entry->in_pack_type == OBJ_DELTA &&
(base_entry = locate_object_entry(base)) &&
(!base_entry->preferred_base)) {
(!base_entry->preferred_base) &&
entry->in_pack->pack_version <= delta_version) {
/* Depth value does not matter - find_deltas()
* will never consider reused delta as the
* base object to deltify other objects
@@ -1101,6 +1104,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
* on an earlier try, but only when reusing delta data.
*/
if (!no_reuse_delta && trg_entry->in_pack &&
trg_entry->in_pack->pack_version <= delta_version &&
trg_entry->in_pack == src_entry->in_pack)
return 0;
@@ -1326,10 +1330,15 @@ static void setup_progress_signal(void)
static int git_pack_config(const char *k, const char *v)
{
if(!strcmp(k, "pack.window")) {
if (!strcmp(k, "pack.window")) {
window = git_config_int(k, v);
return 0;
}
if (!strcmp(k, "pack.deltaversion")) {
delta_version = git_config_int(k, v);
if (!pack_version_ok(htonl(delta_version)))
die("value %s for '%s' not allowed", v, k);
}
return git_default_config(k, v);
}

View File

@@ -337,6 +337,7 @@ extern struct packed_git {
unsigned int pack_last_used;
unsigned int pack_use_cnt;
int pack_local;
int pack_version;
unsigned char sha1[20];
/* something like ".git/objects/pack/xxxxx.pack" */
char pack_name[FLEX_ARRAY]; /* more */

View File

@@ -1,6 +1,8 @@
#ifndef DELTA_H
#define DELTA_H
extern int delta_version;
/* opaque object for delta index */
struct delta_index;

View File

@@ -253,10 +253,13 @@ create_delta(const struct delta_index *index,
int inscnt;
const unsigned char *ref_data, *ref_top, *data, *top;
unsigned char *out;
unsigned int ref_size_limit;
if (!trg_buf || !trg_size)
return NULL;
ref_size_limit = (delta_version > 2) ? 0xffffff : 0x10000;
outpos = 0;
outsize = 8192;
if (max_size && outsize >= max_size)
@@ -308,8 +311,8 @@ create_delta(const struct delta_index *index,
continue;
if (ref_size > top - src)
ref_size = top - src;
if (ref_size > 0x10000)
ref_size = 0x10000;
if (ref_size > ref_size_limit)
ref_size = ref_size_limit;
if (ref_size <= msize)
break;
while (ref_size-- && *src++ == *ref)
@@ -318,6 +321,8 @@ create_delta(const struct delta_index *index,
/* this is our best match so far */
msize = ref - entry->ptr;
moff = entry->ptr - ref_data;
if (delta_version > 2 && msize >= 0x10000)
break; /* this is good enough */
}
}
@@ -381,6 +386,12 @@ create_delta(const struct delta_index *index,
if (msize & 0xff) { out[outpos++] = msize; i |= 0x10; }
msize >>= 8;
if (msize & 0xff) { out[outpos++] = msize; i |= 0x20; }
if (delta_version > 2) {
msize >>= 8;
if (msize & 0xff) {
out[outpos++] = msize; i |= 0x40;
}
}
*op = i;
}

View File

@@ -8,6 +8,7 @@
* are.
*/
#include "cache.h"
#include "pack.h"
char git_default_email[MAX_GITNAME];
char git_default_name[MAX_GITNAME];
@@ -25,6 +26,8 @@ const char *apply_default_whitespace;
int zlib_compression_level = Z_DEFAULT_COMPRESSION;
int pager_in_use;
int pager_use_color = 1;
/* by default we allow 2 but up to PACK_VERSION is allowed */
int delta_version = 2;
static const char *git_dir;
static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file;

View File

@@ -527,6 +527,7 @@ int use_packed_git(struct packed_git *p)
p->pack_size - 20)) {
die("packfile %s does not match index.", p->pack_name);
}
p->pack_version = ntohl(hdr->hdr_version);
}
p->pack_last_used = pack_used_ctr++;
p->pack_use_cnt++;