8
#include "ll-merge.h"
9
#include "attr.h"
10
#include "pathspec.h"
11
+#include "sha1-lookup.h"
12
13
#define RESOLVED 0
14
#define PUNTED 1
23
24
static char *merge_rr_path;
25
26
+static int rerere_dir_nr;
27
+static int rerere_dir_alloc;
28
+
29
+static struct rerere_dir {
30
+ unsigned char sha1[20];
31
+} **rerere_dir;
32
+
33
+static void free_rerere_dirs(void)
34
+{
35
+ int i;
36
+ for (i = 0; i < rerere_dir_nr; i++)
37
+ free(rerere_dir[i]);
38
+ free(rerere_dir);
39
+ rerere_dir_nr = rerere_dir_alloc = 0;
40
+ rerere_dir = NULL;
41
+}
42
+
43
static void free_rerere_id(struct string_list_item *item)
44
{
45
free(item->util);
47
48
static const char *rerere_id_hex(const struct rerere_id *id)
49
{
32
- return id->hex;
50
+ return sha1_to_hex(id->collection->sha1);
51
}
52
53
const char *rerere_path(const struct rerere_id *id, const char *file)
58
return git_path("rr-cache/%s/%s", rerere_id_hex(id), file);
59
}
60
61
+static const unsigned char *rerere_dir_sha1(size_t i, void *table)
62
+{
63
+ struct rerere_dir **rr_dir = table;
64
+ return rr_dir[i]->sha1;
65
+}
66
+
67
+static struct rerere_dir *find_rerere_dir(const char *hex)
68
+{
69
+ unsigned char sha1[20];
70
+ struct rerere_dir *rr_dir;
71
+ int pos;
72
+
73
+ if (get_sha1_hex(hex, sha1))
74
+ return NULL; /* BUG */
75
+ pos = sha1_pos(sha1, rerere_dir, rerere_dir_nr, rerere_dir_sha1);
76
+ if (pos < 0) {
77
+ rr_dir = xmalloc(sizeof(*rr_dir));
78
+ hashcpy(rr_dir->sha1, sha1);
79
+ pos = -1 - pos;
80
+
81
+ /* Make sure the array is big enough ... */
82
+ ALLOC_GROW(rerere_dir, rerere_dir_nr + 1, rerere_dir_alloc);
83
+ /* ... and add it in. */
84
+ rerere_dir_nr++;
85
+ memmove(rerere_dir + pos + 1, rerere_dir + pos,
86
+ (rerere_dir_nr - pos - 1) * sizeof(*rerere_dir));
87
+ rerere_dir[pos] = rr_dir;
88
+ }
89
+ return rerere_dir[pos];
90
+}
91
+
92
static int has_rerere_resolution(const struct rerere_id *id)
93
{
94
struct stat st;
99
static struct rerere_id *new_rerere_id_hex(char *hex)
100
{
101
struct rerere_id *id = xmalloc(sizeof(*id));
53
- xsnprintf(id->hex, sizeof(id->hex), "%s", hex);
102
+ id->collection = find_rerere_dir(hex);
103
return id;
104
}
105
859
int rerere(int flags)
860
{
861
struct string_list merge_rr = STRING_LIST_INIT_DUP;
813
- int fd;
862
+ int fd, status;
863
864
fd = setup_rerere(&merge_rr, flags);
865
if (fd < 0)
866
return 0;
818
- return do_plain_rerere(&merge_rr, fd);
867
+ status = do_plain_rerere(&merge_rr, fd);
868
+ free_rerere_dirs();
869
+ return status;
870
}
871
872
static int rerere_forget_one_path(const char *path, struct string_list *rr)
951
static struct rerere_id *dirname_to_id(const char *name)
952
{
953
static struct rerere_id id;
903
- xsnprintf(id.hex, sizeof(id.hex), "%s", name);
954
+ id.collection = find_rerere_dir(name);
955
return &id;
956
}
957