summaryrefslogtreecommitdiff
path: root/read-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'read-cache.c')
-rw-r--r--read-cache.c149
1 files changed, 60 insertions, 89 deletions
diff --git a/read-cache.c b/read-cache.c
index 35e5657877..f4c31a68c8 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -4,23 +4,34 @@
* Copyright (C) Linus Torvalds, 2005
*/
#include "cache.h"
+#include "alloc.h"
#include "config.h"
+#include "date.h"
#include "diff.h"
#include "diffcore.h"
+#include "hex.h"
#include "tempfile.h"
#include "lockfile.h"
#include "cache-tree.h"
#include "refs.h"
#include "dir.h"
+#include "object-file.h"
#include "object-store.h"
+#include "oid-array.h"
#include "tree.h"
#include "commit.h"
#include "blob.h"
+#include "environment.h"
+#include "gettext.h"
+#include "mem-pool.h"
+#include "object-name.h"
#include "resolve-undo.h"
#include "run-command.h"
#include "strbuf.h"
+#include "trace2.h"
#include "varint.h"
#include "split-index.h"
+#include "symlinks.h"
#include "utf8.h"
#include "fsmonitor.h"
#include "thread-utils.h"
@@ -29,6 +40,7 @@
#include "csum-file.h"
#include "promisor-remote.h"
#include "hook.h"
+#include "wrapper.h"
/* Mask for the name length in ce_flags in the on-disk index */
@@ -263,7 +275,7 @@ static int ce_compare_link(const struct cache_entry *ce, size_t expected_size)
if (strbuf_readlink(&sb, ce->name, expected_size))
return -1;
- buffer = read_object_file(&ce->oid, &type, &size);
+ buffer = repo_read_object_file(the_repository, &ce->oid, &type, &size);
if (buffer) {
if (size == sb.len)
match = memcmp(buffer, sb.buf, size);
@@ -488,87 +500,30 @@ int ie_modified(struct index_state *istate,
return 0;
}
-int base_name_compare(const char *name1, size_t len1, int mode1,
- const char *name2, size_t len2, int mode2)
+static int cache_name_stage_compare(const char *name1, int len1, int stage1,
+ const char *name2, int len2, int stage2)
{
- 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);
+ cmp = name_compare(name1, len1, name2, len2);
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;
-}
-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)
+ if (stage1 < stage2)
return -1;
- if (len1 > len2)
+ if (stage1 > stage2)
return 1;
return 0;
}
-int cache_name_stage_compare(const char *name1, int len1, int stage1, const char *name2, int len2, int stage2)
+int cmp_cache_name_compare(const void *a_, const void *b_)
{
- int cmp;
-
- cmp = name_compare(name1, len1, name2, len2);
- if (cmp)
- return cmp;
+ const struct cache_entry *ce1, *ce2;
- if (stage1 < stage2)
- return -1;
- if (stage1 > stage2)
- return 1;
- return 0;
+ 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));
}
static int index_name_stage_pos(struct index_state *istate,
@@ -2628,7 +2583,7 @@ int repo_index_has_changes(struct repository *repo,
if (tree)
cmp = tree->object.oid;
- if (tree || !get_oid_tree("HEAD", &cmp)) {
+ if (tree || !repo_get_oid_tree(repo, "HEAD", &cmp)) {
struct diff_options opt;
repo_diff_setup(repo, &opt);
@@ -2901,6 +2856,16 @@ static int record_ieot(void)
return !git_config_get_index_threads(&val) && val != 1;
}
+enum write_extensions {
+ WRITE_NO_EXTENSION = 0,
+ WRITE_SPLIT_INDEX_EXTENSION = 1<<0,
+ WRITE_CACHE_TREE_EXTENSION = 1<<1,
+ WRITE_RESOLVE_UNDO_EXTENSION = 1<<2,
+ WRITE_UNTRACKED_CACHE_EXTENSION = 1<<3,
+ WRITE_FSMONITOR_EXTENSION = 1<<4,
+};
+#define WRITE_ALL_EXTENSIONS ((enum write_extensions)-1)
+
/*
* On success, `tempfile` is closed. If it is the temporary file
* of a `struct lock_file`, we will therefore effectively perform
@@ -2909,7 +2874,7 @@ static int record_ieot(void)
* rely on it.
*/
static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
- int strip_extensions, unsigned flags)
+ enum write_extensions write_extensions, unsigned flags)
{
uint64_t start = getnanotime();
struct hashfile *f;
@@ -2947,7 +2912,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
}
if (!istate->version)
- istate->version = get_index_format_default(the_repository);
+ istate->version = get_index_format_default(r);
/* demote version 3 to version 2 when the latter suffices */
if (istate->version == 3 || istate->version == 2)
@@ -3082,8 +3047,8 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
return -1;
}
- if (!strip_extensions && istate->split_index &&
- !is_null_oid(&istate->split_index->base_oid)) {
+ if (write_extensions & WRITE_SPLIT_INDEX_EXTENSION &&
+ istate->split_index) {
struct strbuf sb = STRBUF_INIT;
if (istate->sparse_index)
@@ -3097,7 +3062,8 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
if (err)
return -1;
}
- if (!strip_extensions && !drop_cache_tree && istate->cache_tree) {
+ if (write_extensions & WRITE_CACHE_TREE_EXTENSION &&
+ !drop_cache_tree && istate->cache_tree) {
struct strbuf sb = STRBUF_INIT;
cache_tree_write(&sb, istate->cache_tree);
@@ -3107,7 +3073,8 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
if (err)
return -1;
}
- if (!strip_extensions && istate->resolve_undo) {
+ if (write_extensions & WRITE_RESOLVE_UNDO_EXTENSION &&
+ istate->resolve_undo) {
struct strbuf sb = STRBUF_INIT;
resolve_undo_write(&sb, istate->resolve_undo);
@@ -3118,7 +3085,8 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
if (err)
return -1;
}
- if (!strip_extensions && istate->untracked) {
+ if (write_extensions & WRITE_UNTRACKED_CACHE_EXTENSION &&
+ istate->untracked) {
struct strbuf sb = STRBUF_INIT;
write_untracked_extension(&sb, istate->untracked);
@@ -3129,7 +3097,8 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
if (err)
return -1;
}
- if (!strip_extensions && istate->fsmonitor_last_update) {
+ if (write_extensions & WRITE_FSMONITOR_EXTENSION &&
+ istate->fsmonitor_last_update) {
struct strbuf sb = STRBUF_INIT;
write_fsmonitor_extension(&sb, istate);
@@ -3203,8 +3172,10 @@ static int commit_locked_index(struct lock_file *lk)
return commit_lock_file(lk);
}
-static int do_write_locked_index(struct index_state *istate, struct lock_file *lock,
- unsigned flags)
+static int do_write_locked_index(struct index_state *istate,
+ struct lock_file *lock,
+ unsigned flags,
+ enum write_extensions write_extensions)
{
int ret;
int was_full = istate->sparse_index == INDEX_EXPANDED;
@@ -3222,7 +3193,7 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l
*/
trace2_region_enter_printf("index", "do_write_index", the_repository,
"%s", get_lock_file_path(lock));
- ret = do_write_index(istate, lock->tempfile, 0, flags);
+ ret = do_write_index(istate, lock->tempfile, write_extensions, flags);
trace2_region_leave_printf("index", "do_write_index", the_repository,
"%s", get_lock_file_path(lock));
@@ -3251,7 +3222,7 @@ static int write_split_index(struct index_state *istate,
{
int ret;
prepare_to_write_split_index(istate);
- ret = do_write_locked_index(istate, lock, flags);
+ ret = do_write_locked_index(istate, lock, flags, WRITE_ALL_EXTENSIONS);
finish_writing_split_index(istate);
return ret;
}
@@ -3326,7 +3297,7 @@ static int write_shared_index(struct index_state *istate,
trace2_region_enter_printf("index", "shared/do_write_index",
the_repository, "%s", get_tempfile_path(*temp));
- ret = do_write_index(si->base, *temp, 1, flags);
+ ret = do_write_index(si->base, *temp, WRITE_NO_EXTENSION, flags);
trace2_region_leave_printf("index", "shared/do_write_index",
the_repository, "%s", get_tempfile_path(*temp));
@@ -3403,9 +3374,8 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
if ((!si && !test_split_index_env) ||
alternate_index_output ||
(istate->cache_changed & ~EXTMASK)) {
- if (si)
- oidclr(&si->base_oid);
- ret = do_write_locked_index(istate, lock, flags);
+ ret = do_write_locked_index(istate, lock, flags,
+ ~WRITE_SPLIT_INDEX_EXTENSION);
goto out;
}
@@ -3431,8 +3401,8 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
/* Same initial permissions as the main .git/index file */
temp = mks_tempfile_sm(git_path("sharedindex_XXXXXX"), 0, 0666);
if (!temp) {
- oidclr(&si->base_oid);
- ret = do_write_locked_index(istate, lock, flags);
+ ret = do_write_locked_index(istate, lock, flags,
+ ~WRITE_SPLIT_INDEX_EXTENSION);
goto out;
}
ret = write_shared_index(istate, &temp, flags);
@@ -3553,7 +3523,8 @@ void *read_blob_data_from_index(struct index_state *istate,
}
if (pos < 0)
return NULL;
- data = read_object_file(&istate->cache[pos]->oid, &type, &sz);
+ data = repo_read_object_file(the_repository, &istate->cache[pos]->oid,
+ &type, &sz);
if (!data || type != OBJ_BLOB) {
free(data);
return NULL;