2 * GIT - The information manager from hell
4 * Copyright (C) Linus Torvalds, 2005
8 static int check_valid_sha1(unsigned char *sha1
)
10 char *filename
= sha1_file_name(sha1
);
13 /* If we were anal, we'd check that the sha1 of the contents actually matches */
14 ret
= access(filename
, R_OK
);
20 static int prepend_integer(char *buffer
, unsigned val
, int i
)
24 buffer
[--i
] = '0' + (val
% 10);
30 #define ORIG_OFFSET (40) /* Enough space to add the header of "tree <size>\0" */
32 static int write_tree(struct cache_entry
**cachep
, int maxentries
, const char *base
, int baselen
, unsigned char *returnsha1
)
34 unsigned char subdir_sha1
[20];
35 unsigned long size
, offset
;
39 /* Guess at some random initial size */
41 buffer
= malloc(size
);
46 struct cache_entry
*ce
= cachep
[nr
];
47 const char *pathname
= ce
->name
, *filename
, *dirname
;
48 int pathlen
= ce_namelen(ce
), entrylen
;
52 /* Did we hit the end of the directory? Return how many we wrote */
53 if (baselen
>= pathlen
|| memcmp(base
, pathname
, baselen
))
57 mode
= ntohl(ce
->ce_mode
);
59 /* Do we have _further_ subdirectories? */
60 filename
= pathname
+ baselen
;
61 dirname
= strchr(filename
, '/');
65 subdir_written
= write_tree(cachep
+ nr
, maxentries
- nr
, pathname
, dirname
-pathname
+1, subdir_sha1
);
68 /* Now we need to write out the directory entry into this tree.. */
70 pathlen
= dirname
- pathname
;
72 /* ..but the directory entry doesn't count towards the total count */
77 if (check_valid_sha1(sha1
) < 0)
80 entrylen
= pathlen
- baselen
;
81 if (offset
+ entrylen
+ 100 > size
) {
82 size
= alloc_nr(offset
+ entrylen
+ 100);
83 buffer
= realloc(buffer
, size
);
85 offset
+= sprintf(buffer
+ offset
, "%o %.*s", mode
, entrylen
, filename
);
87 memcpy(buffer
+ offset
, sha1
, 20);
90 } while (nr
< maxentries
);
92 i
= prepend_integer(buffer
, offset
- ORIG_OFFSET
, ORIG_OFFSET
);
94 memcpy(buffer
+i
, "tree ", 5);
96 write_sha1_file(buffer
+ i
, offset
- i
, returnsha1
);
101 int main(int argc
, char **argv
)
104 int entries
= read_cache();
105 unsigned char sha1
[20];
108 die("write-tree: no cache contents to write");
110 /* Verify that the tree is merged */
112 for (i
= 0; i
< entries
; i
++) {
113 struct cache_entry
*ce
= active_cache
[i
];
114 if (ntohs(ce
->ce_flags
) & ~CE_NAMEMASK
) {
115 if (++unmerged
> 10) {
116 fprintf(stderr
, "...\n");
119 fprintf(stderr
, "%s: unmerged (%s)\n", ce
->name
, sha1_to_hex(ce
->sha1
));
123 die("write-tree: not able to write tree");
125 /* Ok, write it out */
126 if (write_tree(active_cache
, entries
, "", 0, sha1
) != entries
)
127 die("write-tree: internal error");
128 printf("%s\n", sha1_to_hex(sha1
));