Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tree.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2023-05-10 02:45:45 +0300
committerJunio C Hamano <gitster@pobox.com>2023-05-10 02:45:46 +0300
commitccd12a3d6cc62f51b746654ae56e26d92f89ba92 (patch)
tree5cdf347138b5307f5a8d4120b7c6b13453ac12ed /tree.c
parentab828cde84c7cafb9942048d8e24ace9c625a041 (diff)
parente3a3f5edf52c7f6161b167058b4d7c3a31dc0c3b (diff)
Merge branch 'en/header-split-cache-h-part-2'
More header clean-up. * en/header-split-cache-h-part-2: (22 commits) reftable: ensure git-compat-util.h is the first (indirect) include diff.h: reduce unnecessary includes object-store.h: reduce unnecessary includes commit.h: reduce unnecessary includes fsmonitor: reduce includes of cache.h cache.h: remove unnecessary headers treewide: remove cache.h inclusion due to previous changes cache,tree: move basic name compare functions from read-cache to tree cache,tree: move cmp_cache_name_compare from tree.[ch] to read-cache.c hash-ll.h: split out of hash.h to remove dependency on repository.h tree-diff.c: move S_DIFFTREE_IFXMIN_NEQ define from cache.h dir.h: move DTYPE defines from cache.h versioncmp.h: move declarations for versioncmp.c functions from cache.h ws.h: move declarations for ws.c functions from cache.h match-trees.h: move declarations for match-trees.c functions from cache.h pkt-line.h: move declarations for pkt-line.c functions from cache.h base85.h: move declarations for base85.c functions from cache.h copy.h: move declarations for copy.c functions from cache.h server-info.h: move declarations for server-info.c functions from cache.h packfile.h: move pack_window and pack_entry from cache.h ...
Diffstat (limited to 'tree.c')
-rw-r--r--tree.c72
1 files changed, 65 insertions, 7 deletions
diff --git a/tree.c b/tree.c
index e9d51ce2e0..0dd2029a8a 100644
--- a/tree.c
+++ b/tree.c
@@ -1,4 +1,4 @@
-#include "cache.h"
+#include "git-compat-util.h"
#include "cache-tree.h"
#include "hex.h"
#include "tree.h"
@@ -94,14 +94,72 @@ int read_tree(struct repository *r,
return ret;
}
-int cmp_cache_name_compare(const void *a_, const void *b_)
+int base_name_compare(const char *name1, size_t len1, int mode1,
+ const char *name2, size_t len2, int mode2)
{
- const struct cache_entry *ce1, *ce2;
+ unsigned char c1, c2;
+ size_t len = len1 < len2 ? len1 : len2;
+ int cmp;
+
+ cmp = memcmp(name1, name2, len);
+ if (cmp)
+ return cmp;
+ c1 = name1[len];
+ c2 = name2[len];
+ if (!c1 && S_ISDIR(mode1))
+ c1 = '/';
+ if (!c2 && S_ISDIR(mode2))
+ c2 = '/';
+ return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0;
+}
+
+/*
+ * df_name_compare() is identical to base_name_compare(), except it
+ * compares conflicting directory/file entries as equal. Note that
+ * while a directory name compares as equal to a regular file, they
+ * then individually compare _differently_ to a filename that has
+ * a dot after the basename (because '\0' < '.' < '/').
+ *
+ * This is used by routines that want to traverse the git namespace
+ * but then handle conflicting entries together when possible.
+ */
+int df_name_compare(const char *name1, size_t len1, int mode1,
+ const char *name2, size_t len2, int mode2)
+{
+ unsigned char c1, c2;
+ size_t len = len1 < len2 ? len1 : len2;
+ int cmp;
+
+ cmp = memcmp(name1, name2, len);
+ if (cmp)
+ return cmp;
+ /* Directories and files compare equal (same length, same name) */
+ if (len1 == len2)
+ return 0;
+ c1 = name1[len];
+ if (!c1 && S_ISDIR(mode1))
+ c1 = '/';
+ c2 = name2[len];
+ if (!c2 && S_ISDIR(mode2))
+ c2 = '/';
+ if (c1 == '/' && !c2)
+ return 0;
+ if (c2 == '/' && !c1)
+ return 0;
+ return c1 - c2;
+}
- ce1 = *((const struct cache_entry **)a_);
- ce2 = *((const struct cache_entry **)b_);
- return cache_name_stage_compare(ce1->name, ce1->ce_namelen, ce_stage(ce1),
- ce2->name, ce2->ce_namelen, ce_stage(ce2));
+int name_compare(const char *name1, size_t len1, const char *name2, size_t len2)
+{
+ size_t min_len = (len1 < len2) ? len1 : len2;
+ int cmp = memcmp(name1, name2, min_len);
+ if (cmp)
+ return cmp;
+ if (len1 < len2)
+ return -1;
+ if (len1 > len2)
+ return 1;
+ return 0;
}
struct tree *lookup_tree(struct repository *r, const struct object_id *oid)