add a force_object_loose() function
This is meant to force the creation of a loose object even if it already exists packed. Needed for the next commit. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nicolas Pitre committed
May 14, 2008 at 01:32 UTC
bbac73117ebed9f02ccae3df45f4baa0c793dab7
2 files changed
+48
-13
cache.h
+1
@@ -506,6 +506,7 @@ extern void * read_sha1_file(const unsigned char *sha1, enum object_type *type,
506
extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
507
extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
508
extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
509
+extern int force_object_loose(const unsigned char *sha1, time_t mtime);
510
511
extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);
512
sha1_file.c
+47
-13
@@ -2102,26 +2102,16 @@ int hash_sha1_file(const void *buf, unsigned long len, const char *type,
2102
return 0;
2103
}
2104
2105
-int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
2105
+static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
2106
+ void *buf, unsigned long len, time_t mtime)
2107
{
2107
- int size, ret;
2108
+ int fd, size, ret;
2109
unsigned char *compressed;
2110
z_stream stream;
2110
- unsigned char sha1[20];
2111
char *filename;
2112
static char tmpfile[PATH_MAX];
2113
- char hdr[32];
2114
- int fd, hdrlen;
2113
2116
- /* Normally if we have it in the pack then we do not bother writing
2117
- * it out into .git/objects/??/?{38} file.
2118
- */
2119
- write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
2114
filename = sha1_file_name(sha1);
2121
- if (returnsha1)
2122
- hashcpy(returnsha1, sha1);
2123
- if (has_sha1_file(sha1))
2124
- return 0;
2115
fd = open(filename, O_RDONLY);
2116
if (fd >= 0) {
2117
/*
@@ -2182,9 +2172,53 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha
2172
die("unable to write sha1 file");
2173
free(compressed);
2174
2175
+ if (mtime) {
2176
+ struct utimbuf utb;
2177
+ utb.actime = mtime;
2178
+ utb.modtime = mtime;
2179
+ if (utime(tmpfile, &utb) < 0)
2180
+ warning("failed utime() on %s: %s",
2181
+ tmpfile, strerror(errno));
2182
+ }
2183
+
2184
return move_temp_to_file(tmpfile, filename);
2185
}
2186
2187
+int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
2188
+{
2189
+ unsigned char sha1[20];
2190
+ char hdr[32];
2191
+ int hdrlen;
2192
+
2193
+ /* Normally if we have it in the pack then we do not bother writing
2194
+ * it out into .git/objects/??/?{38} file.
2195
+ */
2196
+ write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
2197
+ if (returnsha1)
2198
+ hashcpy(returnsha1, sha1);
2199
+ if (has_sha1_file(sha1))
2200
+ return 0;
2201
+ return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
2202
+}
2203
+
2204
+int force_object_loose(const unsigned char *sha1, time_t mtime)
2205
+{
2206
+ struct stat st;
2207
+ void *buf;
2208
+ unsigned long len;
2209
+ enum object_type type;
2210
+ char hdr[32];
2211
+ int hdrlen;
2212
+
2213
+ if (find_sha1_file(sha1, &st))
2214
+ return 0;
2215
+ buf = read_packed_sha1(sha1, &type, &len);
2216
+ if (!buf)
2217
+ return error("cannot read sha1_file for %s", sha1_to_hex(sha1));
2218
+ hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1;
2219
+ return write_loose_object(sha1, hdr, hdrlen, buf, len, mtime);
2220
+}
2221
+
2222
/*
2223
* We need to unpack and recompress the object for writing
2224
* it out to a different file.