summaryrefslogtreecommitdiff
path: root/sha1-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'sha1-file.c')
-rw-r--r--sha1-file.c127
1 files changed, 111 insertions, 16 deletions
diff --git a/sha1-file.c b/sha1-file.c
index 888b6024d5..188de57634 100644
--- a/sha1-file.c
+++ b/sha1-file.c
@@ -30,8 +30,8 @@
#include "mergesort.h"
#include "quote.h"
#include "packfile.h"
-#include "fetch-object.h"
#include "object-store.h"
+#include "promisor-remote.h"
/* The maximum size for an object header. */
#define MAX_HEADER_LEN 32
@@ -55,7 +55,6 @@
"\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72" \
"\x18\x13"
-const unsigned char null_sha1[GIT_MAX_RAWSZ];
const struct object_id null_oid;
static const struct object_id empty_tree_oid = {
EMPTY_TREE_SHA1_BIN_LITERAL
@@ -743,6 +742,104 @@ out:
return ref_git;
}
+static void fill_alternate_refs_command(struct child_process *cmd,
+ const char *repo_path)
+{
+ const char *value;
+
+ if (!git_config_get_value("core.alternateRefsCommand", &value)) {
+ cmd->use_shell = 1;
+
+ argv_array_push(&cmd->args, value);
+ argv_array_push(&cmd->args, repo_path);
+ } else {
+ cmd->git_cmd = 1;
+
+ argv_array_pushf(&cmd->args, "--git-dir=%s", repo_path);
+ argv_array_push(&cmd->args, "for-each-ref");
+ argv_array_push(&cmd->args, "--format=%(objectname)");
+
+ if (!git_config_get_value("core.alternateRefsPrefixes", &value)) {
+ argv_array_push(&cmd->args, "--");
+ argv_array_split(&cmd->args, value);
+ }
+ }
+
+ cmd->env = local_repo_env;
+ cmd->out = -1;
+}
+
+static void read_alternate_refs(const char *path,
+ alternate_ref_fn *cb,
+ void *data)
+{
+ struct child_process cmd = CHILD_PROCESS_INIT;
+ struct strbuf line = STRBUF_INIT;
+ FILE *fh;
+
+ fill_alternate_refs_command(&cmd, path);
+
+ if (start_command(&cmd))
+ return;
+
+ fh = xfdopen(cmd.out, "r");
+ while (strbuf_getline_lf(&line, fh) != EOF) {
+ struct object_id oid;
+ const char *p;
+
+ if (parse_oid_hex(line.buf, &oid, &p) || *p) {
+ warning(_("invalid line while parsing alternate refs: %s"),
+ line.buf);
+ break;
+ }
+
+ cb(&oid, data);
+ }
+
+ fclose(fh);
+ finish_command(&cmd);
+ strbuf_release(&line);
+}
+
+struct alternate_refs_data {
+ alternate_ref_fn *fn;
+ void *data;
+};
+
+static int refs_from_alternate_cb(struct object_directory *e,
+ void *data)
+{
+ struct strbuf path = STRBUF_INIT;
+ size_t base_len;
+ struct alternate_refs_data *cb = data;
+
+ if (!strbuf_realpath(&path, e->path, 0))
+ goto out;
+ if (!strbuf_strip_suffix(&path, "/objects"))
+ goto out;
+ base_len = path.len;
+
+ /* Is this a git repository with refs? */
+ strbuf_addstr(&path, "/refs");
+ if (!is_directory(path.buf))
+ goto out;
+ strbuf_setlen(&path, base_len);
+
+ read_alternate_refs(path.buf, cb->fn, cb->data);
+
+out:
+ strbuf_release(&path);
+ return 0;
+}
+
+void for_each_alternate_ref(alternate_ref_fn fn, void *data)
+{
+ struct alternate_refs_data cb;
+ cb.fn = fn;
+ cb.data = data;
+ foreach_alt_odb(refs_from_alternate_cb, &cb);
+}
+
int foreach_alt_odb(alt_odb_fn fn, void *cb)
{
struct object_directory *ent;
@@ -854,12 +951,8 @@ void *xmmap_gently(void *start, size_t length,
mmap_limit_check(length);
ret = mmap(start, length, prot, flags, fd, offset);
- if (ret == MAP_FAILED) {
- if (!length)
- return NULL;
- release_pack_memory(length);
- ret = mmap(start, length, prot, flags, fd, offset);
- }
+ if (ret == MAP_FAILED && !length)
+ ret = NULL;
return ret;
}
@@ -1377,16 +1470,17 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid,
}
/* Check if it is a missing object */
- if (fetch_if_missing && repository_format_partial_clone &&
+ if (fetch_if_missing && has_promisor_remote() &&
!already_retried && r == the_repository &&
!(flags & OBJECT_INFO_SKIP_FETCH_OBJECT)) {
/*
- * TODO Investigate having fetch_object() return
- * TODO error/success and stopping the music here.
- * TODO Pass a repository struct through fetch_object,
- * such that arbitrary repositories work.
+ * TODO Investigate checking promisor_remote_get_direct()
+ * TODO return value and stopping on error here.
+ * TODO Pass a repository struct through
+ * promisor_remote_get_direct(), such that arbitrary
+ * repositories work.
*/
- fetch_objects(repository_format_partial_clone, real, 1);
+ promisor_remote_get_direct(r, real, 1);
already_retried = 1;
continue;
}
@@ -1505,7 +1599,8 @@ void *read_object_file_extended(struct repository *r,
return NULL;
}
-void *read_object_with_reference(const struct object_id *oid,
+void *read_object_with_reference(struct repository *r,
+ const struct object_id *oid,
const char *required_type_name,
unsigned long *size,
struct object_id *actual_oid_return)
@@ -1521,7 +1616,7 @@ void *read_object_with_reference(const struct object_id *oid,
int ref_length = -1;
const char *ref_type = NULL;
- buffer = read_object_file(&actual_oid, &type, &isize);
+ buffer = repo_read_object_file(r, &actual_oid, &type, &isize);
if (!buffer)
return NULL;
if (type == required_type) {