24
24
#include "submodule.h"
25
25
#include "gvfs.h"
26
26
27
+ struct path_hashmap_entry {
28
+ struct hashmap_entry entry ;
29
+ char path [FLEX_ARRAY ];
30
+ };
31
+
32
+ static unsigned int (* pathhash )(const char * path );
33
+ static int (* pathcmp )(const char * a , const char * b );
34
+
35
+ static int path_hashmap_cmp (const void * a , const void * b , const void * key )
36
+ {
37
+ const struct path_hashmap_entry * one = a ;
38
+ const struct path_hashmap_entry * two = b ;
39
+
40
+ return pathcmp (one -> path , two -> path );
41
+ }
42
+
27
43
static void flush_output (struct merge_options * o )
28
44
{
29
45
if (o -> buffer_output < 2 && o -> obuf .len ) {
@@ -315,29 +331,26 @@ static int save_files_dirs(const unsigned char *sha1,
315
331
struct strbuf * base , const char * path ,
316
332
unsigned int mode , int stage , void * context )
317
333
{
334
+ struct path_hashmap_entry * entry ;
335
+
318
336
int baselen = base -> len ;
319
337
struct merge_options * o = context ;
320
338
321
339
strbuf_addstr (base , path );
322
340
323
- if (S_ISDIR (mode ))
324
- string_list_insert (& o -> current_directory_set , base -> buf );
325
- else
326
- string_list_insert (& o -> current_file_set , base -> buf );
341
+ FLEX_ALLOC_MEM (entry , path , base -> buf , base -> len );
342
+ hashmap_entry_init (entry , pathhash (entry -> path ));
343
+ hashmap_add (& o -> current_file_dir_set , entry );
327
344
328
345
strbuf_setlen (base , baselen );
329
346
return (S_ISDIR (mode ) ? READ_TREE_RECURSIVE : 0 );
330
347
}
331
348
332
- static int get_files_dirs (struct merge_options * o , struct tree * tree )
349
+ static void get_files_dirs (struct merge_options * o , struct tree * tree )
333
350
{
334
- int n ;
335
351
struct pathspec match_all ;
336
352
memset (& match_all , 0 , sizeof (match_all ));
337
- if (read_tree_recursive (tree , "" , 0 , 0 , & match_all , save_files_dirs , o ))
338
- return 0 ;
339
- n = o -> current_file_set .nr + o -> current_directory_set .nr ;
340
- return n ;
353
+ read_tree_recursive (tree , "" , 0 , 0 , & match_all , save_files_dirs , o );
341
354
}
342
355
343
356
/*
@@ -649,6 +662,7 @@ static void add_flattened_path(struct strbuf *out, const char *s)
649
662
650
663
static char * unique_path (struct merge_options * o , const char * path , const char * branch )
651
664
{
665
+ struct path_hashmap_entry * entry ;
652
666
struct strbuf newpath = STRBUF_INIT ;
653
667
int suffix = 0 ;
654
668
size_t base_len ;
@@ -657,14 +671,18 @@ static char *unique_path(struct merge_options *o, const char *path, const char *
657
671
add_flattened_path (& newpath , branch );
658
672
659
673
base_len = newpath .len ;
660
- while (string_list_has_string (& o -> current_file_set , newpath .buf ) ||
661
- string_list_has_string (& o -> current_directory_set , newpath .buf ) ||
674
+ FLEX_ALLOC_MEM (entry , path , newpath .buf , newpath .len );
675
+ hashmap_entry_init (entry , pathhash (entry -> path ));
676
+ while (hashmap_get (& o -> current_file_dir_set , entry , NULL ) ||
662
677
(!o -> call_depth && file_exists (newpath .buf ))) {
663
678
strbuf_setlen (& newpath , base_len );
664
679
strbuf_addf (& newpath , "_%d" , suffix ++ );
680
+ free (entry );
681
+ FLEX_ALLOC_MEM (entry , path , newpath .buf , newpath .len );
682
+ hashmap_entry_init (entry , pathhash (entry -> path ));
665
683
}
666
684
667
- string_list_insert (& o -> current_file_set , newpath . buf );
685
+ hashmap_add (& o -> current_file_dir_set , entry );
668
686
return strbuf_detach (& newpath , NULL );
669
687
}
670
688
@@ -1933,8 +1951,9 @@ int merge_trees(struct merge_options *o,
1933
1951
if (unmerged_cache ()) {
1934
1952
struct string_list * entries , * re_head , * re_merge ;
1935
1953
int i ;
1936
- string_list_clear (& o -> current_file_set , 1 );
1937
- string_list_clear (& o -> current_directory_set , 1 );
1954
+
1955
+ hashmap_init (& o -> current_file_dir_set , path_hashmap_cmp , 512 );
1956
+
1938
1957
get_files_dirs (o , head );
1939
1958
get_files_dirs (o , merge );
1940
1959
@@ -1943,17 +1962,21 @@ int merge_trees(struct merge_options *o,
1943
1962
re_head = get_renames (o , head , common , head , merge , entries );
1944
1963
re_merge = get_renames (o , merge , common , head , merge , entries );
1945
1964
clean = process_renames (o , re_head , re_merge );
1946
- if (clean < 0 )
1947
- return clean ;
1965
+ if (clean < 0 ) {
1966
+ goto cleanup ;
1967
+ }
1968
+
1948
1969
for (i = entries -> nr - 1 ; 0 <= i ; i -- ) {
1949
1970
const char * path = entries -> items [i ].string ;
1950
1971
struct stage_data * e = entries -> items [i ].util ;
1951
1972
if (!e -> processed ) {
1952
1973
int ret = process_entry (o , path , e );
1953
1974
if (!ret )
1954
1975
clean = 0 ;
1955
- else if (ret < 0 )
1956
- return ret ;
1976
+ else if (ret < 0 ) {
1977
+ clean = ret ;
1978
+ goto cleanup ;
1979
+ }
1957
1980
}
1958
1981
}
1959
1982
for (i = 0 ; i < entries -> nr ; i ++ ) {
@@ -1963,13 +1986,19 @@ int merge_trees(struct merge_options *o,
1963
1986
entries -> items [i ].string );
1964
1987
}
1965
1988
1989
+ cleanup :
1966
1990
string_list_clear (re_merge , 0 );
1967
1991
string_list_clear (re_head , 0 );
1968
1992
string_list_clear (entries , 1 );
1993
+
1994
+ hashmap_free (& o -> current_file_dir_set , 1 );
1969
1995
1970
1996
free (re_merge );
1971
1997
free (re_head );
1972
1998
free (entries );
1999
+
2000
+ if (clean < 0 )
2001
+ return clean ;
1973
2002
}
1974
2003
else
1975
2004
clean = 1 ;
@@ -2167,8 +2196,10 @@ void init_merge_options(struct merge_options *o)
2167
2196
if (o -> verbosity >= 5 )
2168
2197
o -> buffer_output = 0 ;
2169
2198
strbuf_init (& o -> obuf , 0 );
2170
- string_list_init (& o -> current_file_set , 1 );
2171
- string_list_init (& o -> current_directory_set , 1 );
2199
+
2200
+ pathhash = ignore_case ? strihash : strhash ;
2201
+ pathcmp = ignore_case ? strcasecmp : strcmp ;
2202
+
2172
2203
string_list_init (& o -> df_conflict_file_set , 1 );
2173
2204
}
2174
2205
0 commit comments