object-store.h: move for_each_alternate_ref() from transport.h

There's nothing inherently transport-related about enumerating the alternate ref tips. The code has lived in transport.[ch] because the only use so far had been advertising available tips during transport. But it could be used for more, and a future patch will teach rev-list to access these refs. Let's move it alongside the other alt-odb code, declaring it in object-store.h with the implementation in sha1-file.c. This lets us drop the inclusion of transport.h from receive-pack, which perhaps shows how it was misplaced (though receive-pack is about transporting objects, transport.h is mostly about the client side). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Jul 1, 2019 at 09:17 UTC 709dfa69908c9448db91a9bcc96941549be6421e
5 files changed +99 -100
builtin/receive-pack.c
-1
@@ -12,7 +12,6 @@
12 #include "object.h"
13 #include "remote.h"
14 #include "connect.h"
15 -#include "transport.h"
15 #include "string-list.h"
16 #include "sha1-array.h"
17 #include "connected.h"
object-store.h
+2
@@ -33,6 +33,8 @@ void prepare_alt_odb(struct repository *r);
33 char *compute_alternate_path(const char *path, struct strbuf *err);
34 typedef int alt_odb_fn(struct object_directory *, void *);
35 int foreach_alt_odb(alt_odb_fn, void*);
36 +typedef void alternate_ref_fn(const struct object_id *oid, void *);
37 +void for_each_alternate_ref(alternate_ref_fn, void *);
38
39 /*
40 * Add the directory to the on-disk alternates file; the new entry will also
sha1-file.c
+97
@@ -743,6 +743,103 @@ out:
743 return ref_git;
744 }
745
746 +static void fill_alternate_refs_command(struct child_process *cmd,
747 + const char *repo_path)
748 +{
749 + const char *value;
750 +
751 + if (!git_config_get_value("core.alternateRefsCommand", &value)) {
752 + cmd->use_shell = 1;
753 +
754 + argv_array_push(&cmd->args, value);
755 + argv_array_push(&cmd->args, repo_path);
756 + } else {
757 + cmd->git_cmd = 1;
758 +
759 + argv_array_pushf(&cmd->args, "--git-dir=%s", repo_path);
760 + argv_array_push(&cmd->args, "for-each-ref");
761 + argv_array_push(&cmd->args, "--format=%(objectname)");
762 +
763 + if (!git_config_get_value("core.alternateRefsPrefixes", &value)) {
764 + argv_array_push(&cmd->args, "--");
765 + argv_array_split(&cmd->args, value);
766 + }
767 + }
768 +
769 + cmd->env = local_repo_env;
770 + cmd->out = -1;
771 +}
772 +
773 +static void read_alternate_refs(const char *path,
774 + alternate_ref_fn *cb,
775 + void *data)
776 +{
777 + struct child_process cmd = CHILD_PROCESS_INIT;
778 + struct strbuf line = STRBUF_INIT;
779 + FILE *fh;
780 +
781 + fill_alternate_refs_command(&cmd, path);
782 +
783 + if (start_command(&cmd))
784 + return;
785 +
786 + fh = xfdopen(cmd.out, "r");
787 + while (strbuf_getline_lf(&line, fh) != EOF) {
788 + struct object_id oid;
789 + const char *p;
790 +
791 + if (parse_oid_hex(line.buf, &oid, &p) || *p) {
792 + warning(_("invalid line while parsing alternate refs: %s"),
793 + line.buf);
794 + break;
795 + }
796 +
797 + cb(&oid, data);
798 + }
799 +
800 + fclose(fh);
801 + finish_command(&cmd);
802 +}
803 +
804 +struct alternate_refs_data {
805 + alternate_ref_fn *fn;
806 + void *data;
807 +};
808 +
809 +static int refs_from_alternate_cb(struct object_directory *e,
810 + void *data)
811 +{
812 + struct strbuf path = STRBUF_INIT;
813 + size_t base_len;
814 + struct alternate_refs_data *cb = data;
815 +
816 + if (!strbuf_realpath(&path, e->path, 0))
817 + goto out;
818 + if (!strbuf_strip_suffix(&path, "/objects"))
819 + goto out;
820 + base_len = path.len;
821 +
822 + /* Is this a git repository with refs? */
823 + strbuf_addstr(&path, "/refs");
824 + if (!is_directory(path.buf))
825 + goto out;
826 + strbuf_setlen(&path, base_len);
827 +
828 + read_alternate_refs(path.buf, cb->fn, cb->data);
829 +
830 +out:
831 + strbuf_release(&path);
832 + return 0;
833 +}
834 +
835 +void for_each_alternate_ref(alternate_ref_fn fn, void *data)
836 +{
837 + struct alternate_refs_data cb;
838 + cb.fn = fn;
839 + cb.data = data;
840 + foreach_alt_odb(refs_from_alternate_cb, &cb);
841 +}
842 +
843 int foreach_alt_odb(alt_odb_fn fn, void *cb)
844 {
845 struct object_directory *ent;
transport.c
-97
@@ -1380,100 +1380,3 @@ char *transport_anonymize_url(const char *url)
1380 literal_copy:
1381 return xstrdup(url);
1382 }
1383 -
1384 -static void fill_alternate_refs_command(struct child_process *cmd,
1385 - const char *repo_path)
1386 -{
1387 - const char *value;
1388 -
1389 - if (!git_config_get_value("core.alternateRefsCommand", &value)) {
1390 - cmd->use_shell = 1;
1391 -
1392 - argv_array_push(&cmd->args, value);
1393 - argv_array_push(&cmd->args, repo_path);
1394 - } else {
1395 - cmd->git_cmd = 1;
1396 -
1397 - argv_array_pushf(&cmd->args, "--git-dir=%s", repo_path);
1398 - argv_array_push(&cmd->args, "for-each-ref");
1399 - argv_array_push(&cmd->args, "--format=%(objectname)");
1400 -
1401 - if (!git_config_get_value("core.alternateRefsPrefixes", &value)) {
1402 - argv_array_push(&cmd->args, "--");
1403 - argv_array_split(&cmd->args, value);
1404 - }
1405 - }
1406 -
1407 - cmd->env = local_repo_env;
1408 - cmd->out = -1;
1409 -}
1410 -
1411 -static void read_alternate_refs(const char *path,
1412 - alternate_ref_fn *cb,
1413 - void *data)
1414 -{
1415 - struct child_process cmd = CHILD_PROCESS_INIT;
1416 - struct strbuf line = STRBUF_INIT;
1417 - FILE *fh;
1418 -
1419 - fill_alternate_refs_command(&cmd, path);
1420 -
1421 - if (start_command(&cmd))
1422 - return;
1423 -
1424 - fh = xfdopen(cmd.out, "r");
1425 - while (strbuf_getline_lf(&line, fh) != EOF) {
1426 - struct object_id oid;
1427 - const char *p;
1428 -
1429 - if (parse_oid_hex(line.buf, &oid, &p) || *p) {
1430 - warning(_("invalid line while parsing alternate refs: %s"),
1431 - line.buf);
1432 - break;
1433 - }
1434 -
1435 - cb(&oid, data);
1436 - }
1437 -
1438 - fclose(fh);
1439 - finish_command(&cmd);
1440 -}
1441 -
1442 -struct alternate_refs_data {
1443 - alternate_ref_fn *fn;
1444 - void *data;
1445 -};
1446 -
1447 -static int refs_from_alternate_cb(struct object_directory *e,
1448 - void *data)
1449 -{
1450 - struct strbuf path = STRBUF_INIT;
1451 - size_t base_len;
1452 - struct alternate_refs_data *cb = data;
1453 -
1454 - if (!strbuf_realpath(&path, e->path, 0))
1455 - goto out;
1456 - if (!strbuf_strip_suffix(&path, "/objects"))
1457 - goto out;
1458 - base_len = path.len;
1459 -
1460 - /* Is this a git repository with refs? */
1461 - strbuf_addstr(&path, "/refs");
1462 - if (!is_directory(path.buf))
1463 - goto out;
1464 - strbuf_setlen(&path, base_len);
1465 -
1466 - read_alternate_refs(path.buf, cb->fn, cb->data);
1467 -
1468 -out:
1469 - strbuf_release(&path);
1470 - return 0;
1471 -}
1472 -
1473 -void for_each_alternate_ref(alternate_ref_fn fn, void *data)
1474 -{
1475 - struct alternate_refs_data cb;
1476 - cb.fn = fn;
1477 - cb.data = data;
1478 - foreach_alt_odb(refs_from_alternate_cb, &cb);
1479 -}
transport.h
-2
@@ -262,6 +262,4 @@ int transport_refs_pushed(struct ref *ref);
262 void transport_print_push_status(const char *dest, struct ref *refs,
263 int verbose, int porcelain, unsigned int *reject_reasons);
264
265 -typedef void alternate_ref_fn(const struct object_id *oid, void *);
266 -void for_each_alternate_ref(alternate_ref_fn, void *);
265 #endif