Correct packfile edge output in fast-import.
authorShawn O. Pearce <spearce@spearce.org>
Wed, 17 Jan 2007 07:42:43 +0000 (02:42 -0500)
committerShawn O. Pearce <spearce@spearce.org>
Wed, 17 Jan 2007 07:42:43 +0000 (02:42 -0500)
Branches are only contained by a packfile if the branch actually
had its most recent commit in that packfile.  So new branches are
set to MAX_PACK_ID to ensure they don't cause their commit to list
as part of the first packfile when it closes out if the commit was
actually in existance before fast-import started.

Also corrected the type of last_commit to be umaxint_t to prevent
overflow and wraparound on very large imports.  Though that is
highly unlikely to occur as we're talking 4 billion commits, which
no real project has right now.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
fast-import.c

index 84f855fb8e9e13a3d585ee830dfd6b3056fc6473..a3073c5f0334baaec59c5c4a6650bbdb4e3de1fb 100644 (file)
@@ -111,12 +111,15 @@ Format of STDIN stream:
 #include "strbuf.h"
 #include "quote.h"
 
+#define PACK_ID_BITS 16
+#define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
+
 struct object_entry
 {
        struct object_entry *next;
        unsigned long offset;
        unsigned type : TYPE_BITS;
-       unsigned pack_id : 16;
+       unsigned pack_id : PACK_ID_BITS;
        unsigned char sha1[20];
 };
 
@@ -193,7 +196,7 @@ struct branch
        struct branch *active_next_branch;
        const char *name;
        struct tree_entry branch_tree;
-       unsigned long last_commit;
+       uintmax_t last_commit;
        unsigned int pack_id;
        unsigned char sha1[20];
 };
@@ -494,6 +497,7 @@ static struct branch* new_branch(const char *name)
        b->table_next_branch = branch_table[hc];
        b->branch_tree.versions[0].mode = S_IFDIR;
        b->branch_tree.versions[1].mode = S_IFDIR;
+       b->pack_id = MAX_PACK_ID;
        branch_table[hc] = b;
        branch_count++;
        return b;
@@ -1696,11 +1700,11 @@ static void cmd_new_commit(void)
        free(committer);
        free(msg);
 
-       store_object(OBJ_COMMIT,
+       if (!store_object(OBJ_COMMIT,
                new_data.buffer, sp - (char*)new_data.buffer,
-               NULL, b->sha1, next_mark);
+               NULL, b->sha1, next_mark))
+               b->pack_id = pack_id;
        b->last_commit = object_count_by_type[OBJ_COMMIT];
-       b->pack_id = pack_id;
 
        if (branch_log) {
                int need_dq = quote_c_style(b->name, NULL, NULL, 0);
@@ -1807,9 +1811,12 @@ static void cmd_new_tag(void)
        free(tagger);
        free(msg);
 
-       store_object(OBJ_TAG, new_data.buffer, sp - (char*)new_data.buffer,
-               NULL, t->sha1, 0);
-       t->pack_id = pack_id;
+       if (store_object(OBJ_TAG, new_data.buffer,
+               sp - (char*)new_data.buffer,
+               NULL, t->sha1, 0))
+               t->pack_id = MAX_PACK_ID;
+       else
+               t->pack_id = pack_id;
 
        if (branch_log) {
                int need_dq = quote_c_style(t->name, NULL, NULL, 0);