|
|
|
@ -4,7 +4,7 @@
@@ -4,7 +4,7 @@
|
|
|
|
|
#include "cache.h" |
|
|
|
|
#include "diff.h" |
|
|
|
|
#include "diffcore.h" |
|
|
|
|
#include "hash.h" |
|
|
|
|
#include "hashmap.h" |
|
|
|
|
#include "progress.h" |
|
|
|
|
|
|
|
|
|
/* Table of rename/copy destinations */ |
|
|
|
@ -243,9 +243,9 @@ static int score_compare(const void *a_, const void *b_)
@@ -243,9 +243,9 @@ static int score_compare(const void *a_, const void *b_)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct file_similarity { |
|
|
|
|
struct hashmap_entry entry; |
|
|
|
|
int index; |
|
|
|
|
struct diff_filespec *filespec; |
|
|
|
|
struct file_similarity *next; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static unsigned int hash_filespec(struct diff_filespec *filespec) |
|
|
|
@ -260,21 +260,22 @@ static unsigned int hash_filespec(struct diff_filespec *filespec)
@@ -260,21 +260,22 @@ static unsigned int hash_filespec(struct diff_filespec *filespec)
|
|
|
|
|
return hash; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int find_identical_files(struct hash_table *srcs, |
|
|
|
|
static int find_identical_files(struct hashmap *srcs, |
|
|
|
|
int dst_index, |
|
|
|
|
struct diff_options *options) |
|
|
|
|
{ |
|
|
|
|
int renames = 0; |
|
|
|
|
|
|
|
|
|
struct diff_filespec *target = rename_dst[dst_index].two; |
|
|
|
|
struct file_similarity *p, *best; |
|
|
|
|
struct file_similarity *p, *best, dst; |
|
|
|
|
int i = 100, best_score = -1; |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
* Find the best source match for specified destination. |
|
|
|
|
*/ |
|
|
|
|
best = NULL; |
|
|
|
|
for (p = lookup_hash(hash_filespec(target), srcs); p; p = p->next) { |
|
|
|
|
hashmap_entry_init(&dst, hash_filespec(target)); |
|
|
|
|
for (p = hashmap_get(srcs, &dst, NULL); p; p = hashmap_get_next(srcs, p)) { |
|
|
|
|
int score; |
|
|
|
|
struct diff_filespec *source = p->filespec; |
|
|
|
|
|
|
|
|
@ -309,34 +310,15 @@ static int find_identical_files(struct hash_table *srcs,
@@ -309,34 +310,15 @@ static int find_identical_files(struct hash_table *srcs,
|
|
|
|
|
return renames; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int free_similarity_list(void *p, void *unused) |
|
|
|
|
static void insert_file_table(struct hashmap *table, int index, struct diff_filespec *filespec) |
|
|
|
|
{ |
|
|
|
|
while (p) { |
|
|
|
|
struct file_similarity *entry = p; |
|
|
|
|
p = entry->next; |
|
|
|
|
free(entry); |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void insert_file_table(struct hash_table *table, int index, struct diff_filespec *filespec) |
|
|
|
|
{ |
|
|
|
|
void **pos; |
|
|
|
|
unsigned int hash; |
|
|
|
|
struct file_similarity *entry = xmalloc(sizeof(*entry)); |
|
|
|
|
|
|
|
|
|
entry->index = index; |
|
|
|
|
entry->filespec = filespec; |
|
|
|
|
entry->next = NULL; |
|
|
|
|
|
|
|
|
|
hash = hash_filespec(filespec); |
|
|
|
|
pos = insert_hash(hash, entry, table); |
|
|
|
|
|
|
|
|
|
/* We already had an entry there? */ |
|
|
|
|
if (pos) { |
|
|
|
|
entry->next = *pos; |
|
|
|
|
*pos = entry; |
|
|
|
|
} |
|
|
|
|
hashmap_entry_init(entry, hash_filespec(filespec)); |
|
|
|
|
hashmap_add(table, entry); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
@ -349,11 +331,10 @@ static void insert_file_table(struct hash_table *table, int index, struct diff_f
@@ -349,11 +331,10 @@ static void insert_file_table(struct hash_table *table, int index, struct diff_f
|
|
|
|
|
static int find_exact_renames(struct diff_options *options) |
|
|
|
|
{ |
|
|
|
|
int i, renames = 0; |
|
|
|
|
struct hash_table file_table; |
|
|
|
|
struct hashmap file_table; |
|
|
|
|
|
|
|
|
|
/* Add all sources to the hash table */ |
|
|
|
|
init_hash(&file_table); |
|
|
|
|
preallocate_hash(&file_table, rename_src_nr); |
|
|
|
|
hashmap_init(&file_table, NULL, rename_src_nr); |
|
|
|
|
for (i = 0; i < rename_src_nr; i++) |
|
|
|
|
insert_file_table(&file_table, i, rename_src[i].p->one); |
|
|
|
|
|
|
|
|
@ -361,11 +342,8 @@ static int find_exact_renames(struct diff_options *options)
@@ -361,11 +342,8 @@ static int find_exact_renames(struct diff_options *options)
|
|
|
|
|
for (i = 0; i < rename_dst_nr; i++) |
|
|
|
|
renames += find_identical_files(&file_table, i, options); |
|
|
|
|
|
|
|
|
|
/* Free source file_similarity chains */ |
|
|
|
|
for_each_hash(&file_table, free_similarity_list, options); |
|
|
|
|
|
|
|
|
|
/* .. and free the hash data structure */ |
|
|
|
|
free_hash(&file_table); |
|
|
|
|
/* Free the hash data structure and entries */ |
|
|
|
|
hashmap_free(&file_table, 1); |
|
|
|
|
|
|
|
|
|
return renames; |
|
|
|
|
} |
|
|
|
|