@matheusbsbs / matheus-bagliano / commits / 0ab9e1e8cd
Fork 0

Add 'df_name_compare()' helper function

This new helper is identical to base_name_compare(), except it compares conflicting directory/file entries as equal in order to help handling DF conflicts (thus the name). Note that while a directory name compares as equal to a regular file with the new helper, they then individually compare _differently_ to a filename that has a dot after the basename (because '\0' < '.' < '/'). So a directory called "foo/" will compare equal to a file "foo", even though "foo.c" will compare after "foo" and before "foo/" This will be used by routines that want to traverse the git namespace but then handle conflicting entries together when possible. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Linus Torvalds committed Mar 5, 2008 at 18:25 UTC 0ab9e1e8cdaefdd33bf24bb0be0ec766483f8bbe
2 files changed +36
cache.h
+1
@@ -536,6 +536,7 @@ extern int create_symref(const char *ref, const char *refs_heads_master, const c
536 extern int validate_headref(const char *ref);
537
538 extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
539 +extern int df_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
540 extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2);
541
542 extern void *read_object_with_reference(const unsigned char *sha1,
read-cache.c
+35
@@ -351,6 +351,41 @@ int base_name_compare(const char *name1, int len1, int mode1,
351 return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0;
352 }
353
354 +/*
355 + * df_name_compare() is identical to base_name_compare(), except it
356 + * compares conflicting directory/file entries as equal. Note that
357 + * while a directory name compares as equal to a regular file, they
358 + * then individually compare _differently_ to a filename that has
359 + * a dot after the basename (because '\0' < '.' < '/').
360 + *
361 + * This is used by routines that want to traverse the git namespace
362 + * but then handle conflicting entries together when possible.
363 + */
364 +int df_name_compare(const char *name1, int len1, int mode1,
365 + const char *name2, int len2, int mode2)
366 +{
367 + int len = len1 < len2 ? len1 : len2, cmp;
368 + unsigned char c1, c2;
369 +
370 + cmp = memcmp(name1, name2, len);
371 + if (cmp)
372 + return cmp;
373 + /* Directories and files compare equal (same length, same name) */
374 + if (len1 == len2)
375 + return 0;
376 + c1 = name1[len];
377 + if (!c1 && S_ISDIR(mode1))
378 + c1 = '/';
379 + c2 = name2[len];
380 + if (!c2 && S_ISDIR(mode2))
381 + c2 = '/';
382 + if (c1 == '/' && !c2)
383 + return 0;
384 + if (c2 == '/' && !c1)
385 + return 0;
386 + return c1 - c2;
387 +}
388 +
389 int cache_name_compare(const char *name1, int flags1, const char *name2, int flags2)
390 {
391 int len1 = flags1 & CE_NAMEMASK;