Merge branch 'master' into js/merge-base
This is to pull in the object-hash clean-up from the master branch.
This commit is contained in:
@ -15,9 +15,9 @@ SYNOPSIS
|
|||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
Updates the index file for given paths, or all modified files if
|
Updates the index file for given paths, or all modified files if
|
||||||
'-a' is specified, and makes a commit object. The command
|
'-a' is specified, and makes a commit object. The command specified
|
||||||
VISUAL and EDITOR environment variables to edit the commit log
|
by either the VISUAL or EDITOR environment variables are used to edit
|
||||||
message.
|
the commit log message.
|
||||||
|
|
||||||
Several environment variable are used during commits. They are
|
Several environment variable are used during commits. They are
|
||||||
documented in gitlink:git-commit-tree[1].
|
documented in gitlink:git-commit-tree[1].
|
||||||
|
4
Makefile
4
Makefile
@ -587,11 +587,11 @@ git-ssh-push$X: rsh.o
|
|||||||
git-imap-send$X: imap-send.o $(LIB_FILE)
|
git-imap-send$X: imap-send.o $(LIB_FILE)
|
||||||
|
|
||||||
http.o http-fetch.o http-push.o: http.h
|
http.o http-fetch.o http-push.o: http.h
|
||||||
git-http-fetch$X: fetch.o http.o http-fetch.o $(LIB_FILE)
|
git-http-fetch$X: fetch.o http.o http-fetch.o $(GITLIBS)
|
||||||
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
|
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
|
||||||
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
|
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
|
||||||
|
|
||||||
git-http-push$X: revision.o http.o http-push.o $(LIB_FILE)
|
git-http-push$X: revision.o http.o http-push.o $(GITLIBS)
|
||||||
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
|
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
|
||||||
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
|
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
|
||||||
|
|
||||||
|
18
connect.c
18
connect.c
@ -328,7 +328,7 @@ static enum protocol get_protocol(const char *name)
|
|||||||
*/
|
*/
|
||||||
static int git_tcp_connect_sock(char *host)
|
static int git_tcp_connect_sock(char *host)
|
||||||
{
|
{
|
||||||
int sockfd = -1;
|
int sockfd = -1, saved_errno = 0;
|
||||||
char *colon, *end;
|
char *colon, *end;
|
||||||
const char *port = STR(DEFAULT_GIT_PORT);
|
const char *port = STR(DEFAULT_GIT_PORT);
|
||||||
struct addrinfo hints, *ai0, *ai;
|
struct addrinfo hints, *ai0, *ai;
|
||||||
@ -362,9 +362,12 @@ static int git_tcp_connect_sock(char *host)
|
|||||||
for (ai0 = ai; ai; ai = ai->ai_next) {
|
for (ai0 = ai; ai; ai = ai->ai_next) {
|
||||||
sockfd = socket(ai->ai_family,
|
sockfd = socket(ai->ai_family,
|
||||||
ai->ai_socktype, ai->ai_protocol);
|
ai->ai_socktype, ai->ai_protocol);
|
||||||
if (sockfd < 0)
|
if (sockfd < 0) {
|
||||||
|
saved_errno = errno;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
|
if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||||
|
saved_errno = errno;
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
sockfd = -1;
|
sockfd = -1;
|
||||||
continue;
|
continue;
|
||||||
@ -375,7 +378,7 @@ static int git_tcp_connect_sock(char *host)
|
|||||||
freeaddrinfo(ai0);
|
freeaddrinfo(ai0);
|
||||||
|
|
||||||
if (sockfd < 0)
|
if (sockfd < 0)
|
||||||
die("unable to connect a socket (%s)", strerror(errno));
|
die("unable to connect a socket (%s)", strerror(saved_errno));
|
||||||
|
|
||||||
return sockfd;
|
return sockfd;
|
||||||
}
|
}
|
||||||
@ -387,7 +390,7 @@ static int git_tcp_connect_sock(char *host)
|
|||||||
*/
|
*/
|
||||||
static int git_tcp_connect_sock(char *host)
|
static int git_tcp_connect_sock(char *host)
|
||||||
{
|
{
|
||||||
int sockfd = -1;
|
int sockfd = -1, saved_errno = 0;
|
||||||
char *colon, *end;
|
char *colon, *end;
|
||||||
char *port = STR(DEFAULT_GIT_PORT), *ep;
|
char *port = STR(DEFAULT_GIT_PORT), *ep;
|
||||||
struct hostent *he;
|
struct hostent *he;
|
||||||
@ -426,8 +429,10 @@ static int git_tcp_connect_sock(char *host)
|
|||||||
|
|
||||||
for (ap = he->h_addr_list; *ap; ap++) {
|
for (ap = he->h_addr_list; *ap; ap++) {
|
||||||
sockfd = socket(he->h_addrtype, SOCK_STREAM, 0);
|
sockfd = socket(he->h_addrtype, SOCK_STREAM, 0);
|
||||||
if (sockfd < 0)
|
if (sockfd < 0) {
|
||||||
|
saved_errno = errno;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&sa, 0, sizeof sa);
|
memset(&sa, 0, sizeof sa);
|
||||||
sa.sin_family = he->h_addrtype;
|
sa.sin_family = he->h_addrtype;
|
||||||
@ -435,6 +440,7 @@ static int git_tcp_connect_sock(char *host)
|
|||||||
memcpy(&sa.sin_addr, *ap, he->h_length);
|
memcpy(&sa.sin_addr, *ap, he->h_length);
|
||||||
|
|
||||||
if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
|
if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
|
||||||
|
saved_errno = errno;
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
sockfd = -1;
|
sockfd = -1;
|
||||||
continue;
|
continue;
|
||||||
@ -443,7 +449,7 @@ static int git_tcp_connect_sock(char *host)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sockfd < 0)
|
if (sockfd < 0)
|
||||||
die("unable to connect a socket (%s)", strerror(errno));
|
die("unable to connect a socket (%s)", strerror(saved_errno));
|
||||||
|
|
||||||
return sockfd;
|
return sockfd;
|
||||||
}
|
}
|
||||||
|
@ -264,9 +264,19 @@ when you have upgraded your tools and habits to use refs/remotes/$GIT_SVN
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub init {
|
sub init {
|
||||||
$SVN_URL = shift or die "SVN repository location required " .
|
my $url = shift or die "SVN repository location required " .
|
||||||
"as a command-line argument\n";
|
"as a command-line argument\n";
|
||||||
$SVN_URL =~ s!/+$!!; # strip trailing slash
|
$url =~ s!/+$!!; # strip trailing slash
|
||||||
|
|
||||||
|
if (my $repo_path = shift) {
|
||||||
|
unless (-d $repo_path) {
|
||||||
|
mkpath([$repo_path]);
|
||||||
|
}
|
||||||
|
$GIT_DIR = $ENV{GIT_DIR} = $repo_path . "/.git";
|
||||||
|
init_vars();
|
||||||
|
}
|
||||||
|
|
||||||
|
$SVN_URL = $url;
|
||||||
unless (-d $GIT_DIR) {
|
unless (-d $GIT_DIR) {
|
||||||
my @init_db = ('git-init-db');
|
my @init_db = ('git-init-db');
|
||||||
push @init_db, "--template=$_template" if defined $_template;
|
push @init_db, "--template=$_template" if defined $_template;
|
||||||
|
@ -60,12 +60,13 @@ static int objwarning(struct object *obj, const char *err, ...)
|
|||||||
|
|
||||||
static void check_connectivity(void)
|
static void check_connectivity(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i, max;
|
||||||
|
|
||||||
/* Look up all the requirements, warn about missing objects.. */
|
/* Look up all the requirements, warn about missing objects.. */
|
||||||
for (i = 0; i < obj_allocs; i++) {
|
max = get_max_object_index();
|
||||||
|
for (i = 0; i < max; i++) {
|
||||||
const struct object_refs *refs;
|
const struct object_refs *refs;
|
||||||
struct object *obj = objs[i];
|
struct object *obj = get_indexed_object(i);
|
||||||
|
|
||||||
if (!obj)
|
if (!obj)
|
||||||
continue;
|
continue;
|
||||||
|
@ -29,7 +29,7 @@ THIS_INDEX="$GIT_DIR/index"
|
|||||||
NEXT_INDEX="$GIT_DIR/next-index$$"
|
NEXT_INDEX="$GIT_DIR/next-index$$"
|
||||||
rm -f "$NEXT_INDEX"
|
rm -f "$NEXT_INDEX"
|
||||||
save_index () {
|
save_index () {
|
||||||
cp "$THIS_INDEX" "$NEXT_INDEX"
|
cp -p "$THIS_INDEX" "$NEXT_INDEX"
|
||||||
}
|
}
|
||||||
|
|
||||||
report () {
|
report () {
|
||||||
|
@ -534,7 +534,7 @@ sub commit {
|
|||||||
my($author_name,$author_email,$dest);
|
my($author_name,$author_email,$dest);
|
||||||
my(@old,@new,@parents);
|
my(@old,@new,@parents);
|
||||||
|
|
||||||
if (not defined $author) {
|
if (not defined $author or $author eq "") {
|
||||||
$author_name = $author_email = "unknown";
|
$author_name = $author_email = "unknown";
|
||||||
} elsif (defined $users_file) {
|
} elsif (defined $users_file) {
|
||||||
die "User $author is not listed in $users_file\n"
|
die "User $author is not listed in $users_file\n"
|
||||||
|
13
name-rev.c
13
name-rev.c
@ -234,12 +234,15 @@ int main(int argc, char **argv)
|
|||||||
fwrite(p_start, p - p_start, 1, stdout);
|
fwrite(p_start, p - p_start, 1, stdout);
|
||||||
}
|
}
|
||||||
} else if (all) {
|
} else if (all) {
|
||||||
int i;
|
int i, max;
|
||||||
|
|
||||||
for (i = 0; i < obj_allocs; i++)
|
max = get_max_object_index();
|
||||||
if (objs[i])
|
for (i = 0; i < max; i++) {
|
||||||
printf("%s %s\n", sha1_to_hex(objs[i]->sha1),
|
struct object * obj = get_indexed_object(i);
|
||||||
get_rev_name(objs[i]));
|
if (!obj)
|
||||||
|
continue;
|
||||||
|
printf("%s %s\n", sha1_to_hex(obj->sha1), get_rev_name(obj));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < revs.nr; i++)
|
for (i = 0; i < revs.nr; i++)
|
||||||
|
126
object.c
126
object.c
@ -5,79 +5,97 @@
|
|||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
|
|
||||||
struct object **objs;
|
static struct object **obj_hash;
|
||||||
static int nr_objs;
|
static int nr_objs, obj_hash_size;
|
||||||
int obj_allocs;
|
|
||||||
|
unsigned int get_max_object_index(void)
|
||||||
|
{
|
||||||
|
return obj_hash_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct object *get_indexed_object(unsigned int idx)
|
||||||
|
{
|
||||||
|
return obj_hash[idx];
|
||||||
|
}
|
||||||
|
|
||||||
const char *type_names[] = {
|
const char *type_names[] = {
|
||||||
"none", "blob", "tree", "commit", "bad"
|
"none", "blob", "tree", "commit", "bad"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static unsigned int hash_obj(struct object *obj, unsigned int n)
|
||||||
|
{
|
||||||
|
unsigned int hash = *(unsigned int *)obj->sha1;
|
||||||
|
return hash % n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size)
|
||||||
|
{
|
||||||
|
int j = hash_obj(obj, size);
|
||||||
|
|
||||||
|
while (hash[j]) {
|
||||||
|
j++;
|
||||||
|
if (j >= size)
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
hash[j] = obj;
|
||||||
|
}
|
||||||
|
|
||||||
static int hashtable_index(const unsigned char *sha1)
|
static int hashtable_index(const unsigned char *sha1)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
memcpy(&i, sha1, sizeof(unsigned int));
|
memcpy(&i, sha1, sizeof(unsigned int));
|
||||||
return (int)(i % obj_allocs);
|
return (int)(i % obj_hash_size);
|
||||||
}
|
|
||||||
|
|
||||||
static int find_object(const unsigned char *sha1)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!objs)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
i = hashtable_index(sha1);
|
|
||||||
while (objs[i]) {
|
|
||||||
if (memcmp(sha1, objs[i]->sha1, 20) == 0)
|
|
||||||
return i;
|
|
||||||
i++;
|
|
||||||
if (i == obj_allocs)
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
return -1 - i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct object *lookup_object(const unsigned char *sha1)
|
struct object *lookup_object(const unsigned char *sha1)
|
||||||
{
|
{
|
||||||
int pos = find_object(sha1);
|
int i;
|
||||||
if (pos >= 0)
|
struct object *obj;
|
||||||
return objs[pos];
|
|
||||||
|
if (!obj_hash)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
i = hashtable_index(sha1);
|
||||||
|
while ((obj = obj_hash[i]) != NULL) {
|
||||||
|
if (!memcmp(sha1, obj->sha1, 20))
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
if (i == obj_hash_size)
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void grow_object_hash(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int new_hash_size = obj_hash_size < 32 ? 32 : 2 * obj_hash_size;
|
||||||
|
struct object **new_hash;
|
||||||
|
|
||||||
|
new_hash = calloc(new_hash_size, sizeof(struct object *));
|
||||||
|
for (i = 0; i < obj_hash_size; i++) {
|
||||||
|
struct object *obj = obj_hash[i];
|
||||||
|
if (!obj)
|
||||||
|
continue;
|
||||||
|
insert_obj_hash(obj, new_hash, new_hash_size);
|
||||||
|
}
|
||||||
|
free(obj_hash);
|
||||||
|
obj_hash = new_hash;
|
||||||
|
obj_hash_size = new_hash_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void created_object(const unsigned char *sha1, struct object *obj)
|
void created_object(const unsigned char *sha1, struct object *obj)
|
||||||
{
|
{
|
||||||
int pos;
|
|
||||||
|
|
||||||
obj->parsed = 0;
|
obj->parsed = 0;
|
||||||
memcpy(obj->sha1, sha1, 20);
|
|
||||||
obj->type = TYPE_NONE;
|
|
||||||
obj->used = 0;
|
obj->used = 0;
|
||||||
|
obj->type = TYPE_NONE;
|
||||||
|
obj->flags = 0;
|
||||||
|
memcpy(obj->sha1, sha1, 20);
|
||||||
|
|
||||||
if (obj_allocs - 1 <= nr_objs * 2) {
|
if (obj_hash_size - 1 <= nr_objs * 2)
|
||||||
int i, count = obj_allocs;
|
grow_object_hash();
|
||||||
obj_allocs = (obj_allocs < 32 ? 32 : 2 * obj_allocs);
|
|
||||||
objs = xrealloc(objs, obj_allocs * sizeof(struct object *));
|
|
||||||
memset(objs + count, 0, (obj_allocs - count)
|
|
||||||
* sizeof(struct object *));
|
|
||||||
for (i = 0; i < obj_allocs; i++)
|
|
||||||
if (objs[i]) {
|
|
||||||
int j = find_object(objs[i]->sha1);
|
|
||||||
if (j != i) {
|
|
||||||
j = -1 - j;
|
|
||||||
objs[j] = objs[i];
|
|
||||||
objs[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = find_object(sha1);
|
insert_obj_hash(obj, obj_hash, obj_hash_size);
|
||||||
if (pos >= 0)
|
|
||||||
die("Inserting %s twice\n", sha1_to_hex(sha1));
|
|
||||||
pos = -pos-1;
|
|
||||||
|
|
||||||
objs[pos] = obj;
|
|
||||||
nr_objs++;
|
nr_objs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +240,7 @@ void clear_object_marks(unsigned mark)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < obj_allocs; i++)
|
for (i = 0; i < obj_hash_size; i++)
|
||||||
if (objs[i])
|
if (obj_hash[i])
|
||||||
objs[i]->flags &= ~mark;
|
obj_hash[i]->flags &= ~mark;
|
||||||
}
|
}
|
||||||
|
5
object.h
5
object.h
@ -40,10 +40,11 @@ struct object {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern int track_object_refs;
|
extern int track_object_refs;
|
||||||
extern int obj_allocs;
|
|
||||||
extern struct object **objs;
|
|
||||||
extern const char *type_names[];
|
extern const char *type_names[];
|
||||||
|
|
||||||
|
extern unsigned int get_max_object_index(void);
|
||||||
|
extern struct object *get_indexed_object(unsigned int);
|
||||||
|
|
||||||
static inline const char *typename(unsigned int type)
|
static inline const char *typename(unsigned int type)
|
||||||
{
|
{
|
||||||
return type_names[type > TYPE_TAG ? TYPE_BAD : type];
|
return type_names[type > TYPE_TAG ? TYPE_BAD : type];
|
||||||
|
@ -970,11 +970,12 @@ struct unpacked {
|
|||||||
* one.
|
* one.
|
||||||
*/
|
*/
|
||||||
static int try_delta(struct unpacked *trg, struct unpacked *src,
|
static int try_delta(struct unpacked *trg, struct unpacked *src,
|
||||||
struct delta_index *src_index, unsigned max_depth)
|
unsigned max_depth)
|
||||||
{
|
{
|
||||||
struct object_entry *trg_entry = trg->entry;
|
struct object_entry *trg_entry = trg->entry;
|
||||||
struct object_entry *src_entry = src->entry;
|
struct object_entry *src_entry = src->entry;
|
||||||
unsigned long size, src_size, delta_size, sizediff, max_size;
|
unsigned long trg_size, src_size, delta_size, sizediff, max_size, sz;
|
||||||
|
char type[10];
|
||||||
void *delta_buf;
|
void *delta_buf;
|
||||||
|
|
||||||
/* Don't bother doing diffs between different types */
|
/* Don't bother doing diffs between different types */
|
||||||
@ -987,6 +988,14 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
|
|||||||
if (trg_entry->preferred_base)
|
if (trg_entry->preferred_base)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We do not bother to try a delta that we discarded
|
||||||
|
* on an earlier try, but only when reusing delta data.
|
||||||
|
*/
|
||||||
|
if (!no_reuse_delta && trg_entry->in_pack &&
|
||||||
|
trg_entry->in_pack == src_entry->in_pack)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the current object is at pack edge, take the depth the
|
* If the current object is at pack edge, take the depth the
|
||||||
* objects that depend on the current object into account --
|
* objects that depend on the current object into account --
|
||||||
@ -1001,19 +1010,38 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Now some size filtering heuristics. */
|
/* Now some size filtering heuristics. */
|
||||||
size = trg_entry->size;
|
trg_size = trg_entry->size;
|
||||||
max_size = size/2 - 20;
|
max_size = trg_size/2 - 20;
|
||||||
max_size = max_size * (max_depth - src_entry->depth) / max_depth;
|
max_size = max_size * (max_depth - src_entry->depth) / max_depth;
|
||||||
if (max_size == 0)
|
if (max_size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (trg_entry->delta && trg_entry->delta_size <= max_size)
|
if (trg_entry->delta && trg_entry->delta_size <= max_size)
|
||||||
max_size = trg_entry->delta_size-1;
|
max_size = trg_entry->delta_size-1;
|
||||||
src_size = src_entry->size;
|
src_size = src_entry->size;
|
||||||
sizediff = src_size < size ? size - src_size : 0;
|
sizediff = src_size < trg_size ? trg_size - src_size : 0;
|
||||||
if (sizediff >= max_size)
|
if (sizediff >= max_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
delta_buf = create_delta(src_index, trg->data, size, &delta_size, max_size);
|
/* Load data if not already done */
|
||||||
|
if (!trg->data) {
|
||||||
|
trg->data = read_sha1_file(trg_entry->sha1, type, &sz);
|
||||||
|
if (sz != trg_size)
|
||||||
|
die("object %s inconsistent object length (%lu vs %lu)",
|
||||||
|
sha1_to_hex(trg_entry->sha1), sz, trg_size);
|
||||||
|
}
|
||||||
|
if (!src->data) {
|
||||||
|
src->data = read_sha1_file(src_entry->sha1, type, &sz);
|
||||||
|
if (sz != src_size)
|
||||||
|
die("object %s inconsistent object length (%lu vs %lu)",
|
||||||
|
sha1_to_hex(src_entry->sha1), sz, src_size);
|
||||||
|
}
|
||||||
|
if (!src->index) {
|
||||||
|
src->index = create_delta_index(src->data, src_size);
|
||||||
|
if (!src->index)
|
||||||
|
die("out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
delta_buf = create_delta(src->index, trg->data, trg_size, &delta_size, max_size);
|
||||||
if (!delta_buf)
|
if (!delta_buf)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1046,8 +1074,6 @@ static void find_deltas(struct object_entry **list, int window, int depth)
|
|||||||
while (--i >= 0) {
|
while (--i >= 0) {
|
||||||
struct object_entry *entry = list[i];
|
struct object_entry *entry = list[i];
|
||||||
struct unpacked *n = array + idx;
|
struct unpacked *n = array + idx;
|
||||||
unsigned long size;
|
|
||||||
char type[10];
|
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
if (!entry->preferred_base)
|
if (!entry->preferred_base)
|
||||||
@ -1074,11 +1100,8 @@ static void find_deltas(struct object_entry **list, int window, int depth)
|
|||||||
free_delta_index(n->index);
|
free_delta_index(n->index);
|
||||||
n->index = NULL;
|
n->index = NULL;
|
||||||
free(n->data);
|
free(n->data);
|
||||||
|
n->data = NULL;
|
||||||
n->entry = entry;
|
n->entry = entry;
|
||||||
n->data = read_sha1_file(entry->sha1, type, &size);
|
|
||||||
if (size != entry->size)
|
|
||||||
die("object %s inconsistent object length (%lu vs %lu)",
|
|
||||||
sha1_to_hex(entry->sha1), size, entry->size);
|
|
||||||
|
|
||||||
j = window;
|
j = window;
|
||||||
while (--j > 0) {
|
while (--j > 0) {
|
||||||
@ -1089,7 +1112,7 @@ static void find_deltas(struct object_entry **list, int window, int depth)
|
|||||||
m = array + other_idx;
|
m = array + other_idx;
|
||||||
if (!m->entry)
|
if (!m->entry)
|
||||||
break;
|
break;
|
||||||
if (try_delta(n, m, m->index, depth) < 0)
|
if (try_delta(n, m, depth) < 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* if we made n a delta, and if n is already at max
|
/* if we made n a delta, and if n is already at max
|
||||||
@ -1099,10 +1122,6 @@ static void find_deltas(struct object_entry **list, int window, int depth)
|
|||||||
if (entry->delta && depth <= entry->depth)
|
if (entry->delta && depth <= entry->depth)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
n->index = create_delta_index(n->data, size);
|
|
||||||
if (!n->index)
|
|
||||||
die("out of memory");
|
|
||||||
|
|
||||||
idx++;
|
idx++;
|
||||||
if (idx >= window)
|
if (idx >= window)
|
||||||
idx = 0;
|
idx = 0;
|
||||||
|
16
revision.c
16
revision.c
@ -280,7 +280,7 @@ int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1)
|
|||||||
static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
|
static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
|
||||||
{
|
{
|
||||||
struct commit_list **pp, *parent;
|
struct commit_list **pp, *parent;
|
||||||
int tree_changed = 0;
|
int tree_changed = 0, tree_same = 0;
|
||||||
|
|
||||||
if (!commit->tree)
|
if (!commit->tree)
|
||||||
return;
|
return;
|
||||||
@ -298,6 +298,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
|
|||||||
parse_commit(p);
|
parse_commit(p);
|
||||||
switch (rev_compare_tree(revs, p->tree, commit->tree)) {
|
switch (rev_compare_tree(revs, p->tree, commit->tree)) {
|
||||||
case REV_TREE_SAME:
|
case REV_TREE_SAME:
|
||||||
|
tree_same = 1;
|
||||||
if (!revs->simplify_history || (p->object.flags & UNINTERESTING)) {
|
if (!revs->simplify_history || (p->object.flags & UNINTERESTING)) {
|
||||||
/* Even if a merge with an uninteresting
|
/* Even if a merge with an uninteresting
|
||||||
* side branch brought the entire change
|
* side branch brought the entire change
|
||||||
@ -334,7 +335,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
|
|||||||
}
|
}
|
||||||
die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1));
|
die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1));
|
||||||
}
|
}
|
||||||
if (tree_changed)
|
if (tree_changed && !tree_same)
|
||||||
commit->object.flags |= TREECHANGE;
|
commit->object.flags |= TREECHANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -926,6 +927,8 @@ static int rewrite_one(struct rev_info *revs, struct commit **pp)
|
|||||||
struct commit *p = *pp;
|
struct commit *p = *pp;
|
||||||
if (!revs->limited)
|
if (!revs->limited)
|
||||||
add_parents_to_list(revs, p, &revs->commits);
|
add_parents_to_list(revs, p, &revs->commits);
|
||||||
|
if (p->parents && p->parents->next)
|
||||||
|
return 0;
|
||||||
if (p->object.flags & (TREECHANGE | UNINTERESTING))
|
if (p->object.flags & (TREECHANGE | UNINTERESTING))
|
||||||
return 0;
|
return 0;
|
||||||
if (!p->parents)
|
if (!p->parents)
|
||||||
@ -1018,8 +1021,15 @@ struct commit *get_revision(struct rev_info *revs)
|
|||||||
commit->parents && commit->parents->next)
|
commit->parents && commit->parents->next)
|
||||||
continue;
|
continue;
|
||||||
if (revs->prune_fn && revs->dense) {
|
if (revs->prune_fn && revs->dense) {
|
||||||
if (!(commit->object.flags & TREECHANGE))
|
/* Commit without changes? */
|
||||||
|
if (!(commit->object.flags & TREECHANGE)) {
|
||||||
|
/* drop merges unless we want parenthood */
|
||||||
|
if (!revs->parents)
|
||||||
continue;
|
continue;
|
||||||
|
/* non-merge - always ignore it */
|
||||||
|
if (!commit->parents || !commit->parents->next)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (revs->parents)
|
if (revs->parents)
|
||||||
rewrite_parents(revs, commit);
|
rewrite_parents(revs, commit);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
#include <signal.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
#include "pkt-line.h"
|
#include "pkt-line.h"
|
||||||
@ -5,9 +8,6 @@
|
|||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "exec_cmd.h"
|
#include "exec_cmd.h"
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/poll.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
|
|
||||||
static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] <dir>";
|
static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] <dir>";
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user