Make "update-cache" a bit friendlier to use (and harder to mis-use).
[git.git] / update-cache.c
1 /*
2  * GIT - The information manager from hell
3  *
4  * Copyright (C) Linus Torvalds, 2005
5  */
6 #include "cache.h"
7
8 /*
9  * Default to not allowing changes to the list of files. The
10  * tool doesn't actually care, but this makes it harder to add
11  * files to the revision control by mistake by doing something
12  * like "update-cache *" and suddenly having all the object
13  * files be revision controlled.
14  */
15 static int allow_add = 0, allow_remove = 0;
16
17 static int index_fd(const char *path, int namelen, struct cache_entry *ce, int fd, struct stat *st)
18 {
19         z_stream stream;
20         int max_out_bytes = namelen + st->st_size + 200;
21         void *out = malloc(max_out_bytes);
22         void *metadata = malloc(namelen + 200);
23         void *in = mmap(NULL, st->st_size, PROT_READ, MAP_PRIVATE, fd, 0);
24         SHA_CTX c;
25
26         close(fd);
27         if (!out || (int)(long)in == -1)
28                 return -1;
29
30         memset(&stream, 0, sizeof(stream));
31         deflateInit(&stream, Z_BEST_COMPRESSION);
32
33         /*
34          * ASCII size + nul byte
35          */     
36         stream.next_in = metadata;
37         stream.avail_in = 1+sprintf(metadata, "blob %lu", (unsigned long) st->st_size);
38         stream.next_out = out;
39         stream.avail_out = max_out_bytes;
40         while (deflate(&stream, 0) == Z_OK)
41                 /* nothing */;
42
43         /*
44          * File content
45          */
46         stream.next_in = in;
47         stream.avail_in = st->st_size;
48         while (deflate(&stream, Z_FINISH) == Z_OK)
49                 /*nothing */;
50
51         deflateEnd(&stream);
52         
53         SHA1_Init(&c);
54         SHA1_Update(&c, out, stream.total_out);
55         SHA1_Final(ce->sha1, &c);
56
57         return write_sha1_buffer(ce->sha1, out, stream.total_out);
58 }
59
60 static int add_file_to_cache(char *path)
61 {
62         int size, namelen;
63         struct cache_entry *ce;
64         struct stat st;
65         int fd;
66
67         fd = open(path, O_RDONLY);
68         if (fd < 0) {
69                 if (errno == ENOENT) {
70                         if (allow_remove)
71                                 return remove_file_from_cache(path);
72                 }
73                 return -1;
74         }
75         if (fstat(fd, &st) < 0) {
76                 close(fd);
77                 return -1;
78         }
79         namelen = strlen(path);
80         size = cache_entry_size(namelen);
81         ce = malloc(size);
82         memset(ce, 0, size);
83         memcpy(ce->name, path, namelen);
84         ce->ctime.sec = st.st_ctime;
85         ce->ctime.nsec = st.st_ctim.tv_nsec;
86         ce->mtime.sec = st.st_mtime;
87         ce->mtime.nsec = st.st_mtim.tv_nsec;
88         ce->st_dev = st.st_dev;
89         ce->st_ino = st.st_ino;
90         ce->st_mode = st.st_mode;
91         ce->st_uid = st.st_uid;
92         ce->st_gid = st.st_gid;
93         ce->st_size = st.st_size;
94         ce->namelen = namelen;
95
96         if (index_fd(path, namelen, ce, fd, &st) < 0)
97                 return -1;
98
99         return add_cache_entry(ce, allow_add);
100 }
101
102 static void refresh_entry(struct cache_entry *ce)
103 {
104         /*
105          * This is really not the right way to do it, but
106          * add_file_to_cache() does do the right thing.
107          *
108          * We should really just update the cache
109          * entry in-place, I think. With this approach we
110          * end up allocating a new one, searching for where
111          * to insert it etc etc crud.
112          */
113         add_file_to_cache(ce->name);
114 }
115
116 static void refresh_cache(void)
117 {
118         int i;
119
120         for (i = 0; i < active_nr; i++)
121                 refresh_entry(active_cache[i]);
122 }
123
124 /*
125  * We fundamentally don't like some paths: we don't want
126  * dot or dot-dot anywhere, and in fact, we don't even want
127  * any other dot-files (.dircache or anything else). They
128  * are hidden, for chist sake.
129  *
130  * Also, we don't want double slashes or slashes at the
131  * end that can make pathnames ambiguous. 
132  */
133 static int verify_path(char *path)
134 {
135         char c;
136
137         goto inside;
138         for (;;) {
139                 if (!c)
140                         return 1;
141                 if (c == '/') {
142 inside:
143                         c = *path++;
144                         if (c != '/' && c != '.' && c != '\0')
145                                 continue;
146                         return 0;
147                 }
148                 c = *path++;
149         }
150 }
151
152 int main(int argc, char **argv)
153 {
154         int i, newfd, entries;
155         int allow_options = 1;
156
157         entries = read_cache();
158         if (entries < 0) {
159                 perror("cache corrupted");
160                 return -1;
161         }
162
163         newfd = open(".dircache/index.lock", O_RDWR | O_CREAT | O_EXCL, 0600);
164         if (newfd < 0) {
165                 perror("unable to create new cachefile");
166                 return -1;
167         }
168         for (i = 1 ; i < argc; i++) {
169                 char *path = argv[i];
170
171                 if (allow_options && *path == '-') {
172                         if (!strcmp(path, "--")) {
173                                 allow_options = 0;
174                                 continue;
175                         }
176                         if (!strcmp(path, "--add")) {
177                                 allow_add = 1;
178                                 continue;
179                         }
180                         if (!strcmp(path, "--remove")) {
181                                 allow_remove = 1;
182                                 continue;
183                         }
184                         if (!strcmp(path, "--refresh")) {
185                                 refresh_cache();
186                                 continue;
187                         }
188                         usage("unknown option %s", path);
189                 }
190                 if (!verify_path(path)) {
191                         fprintf(stderr, "Ignoring path %s\n", argv[i]);
192                         continue;
193                 }
194                 if (add_file_to_cache(path)) {
195                         fprintf(stderr, "Unable to add %s to database\n", path);
196                         goto out;
197                 }
198         }
199         if (!write_cache(newfd, active_cache, active_nr) && !rename(".dircache/index.lock", ".dircache/index"))
200                 return 0;
201 out:
202         unlink(".dircache/index.lock");
203         return 0;
204 }