|
81 | 81 | // |
82 | 82 | // Fetch 1 or more objects. If a cache-server is configured, |
83 | 83 | // try it first. Optionally fallback to the main Git server. |
| 84 | +// |
84 | 85 | // Create 1 or more loose objects and/or packfiles in the |
85 | | -// requested shared-cache directory (given on the command |
86 | | -// line and which is reported at the beginning of the |
87 | | -// response). |
| 86 | +// shared-cache ODB. (The pathname of the selected ODB is |
| 87 | +// reported at the beginning of the response; this should |
| 88 | +// match the pathname given on the command line). |
88 | 89 | // |
89 | 90 | // git> get |
90 | 91 | // git> <oid> |
@@ -641,26 +642,88 @@ static int option_parse_cache_server_mode(const struct option *opt, |
641 | 642 | } |
642 | 643 |
|
643 | 644 | /* |
644 | | - * Let command line args override "gvfs.sharedcache" config setting. |
| 645 | + * Let command line args override "gvfs.sharedcache" config setting |
| 646 | + * and override the value set by git_default_config(). |
| 647 | + * |
| 648 | + * The command line is parsed *AFTER* the config is loaded, so |
| 649 | + * prepared_alt_odb() has already been called any default or inherited |
| 650 | + * shared-cache has already been set. |
645 | 651 | * |
646 | | - * It would be nice to move this to parse-options.c as an |
647 | | - * OPTION_PATHNAME handler. And maybe have flags for exists() |
648 | | - * and is_directory(). |
| 652 | + * We have a chance to override it here. |
649 | 653 | */ |
650 | 654 | static int option_parse_shared_cache_directory(const struct option *opt, |
651 | 655 | const char *arg, int unset) |
652 | 656 | { |
| 657 | + struct strbuf buf_arg = STRBUF_INIT; |
| 658 | + |
653 | 659 | if (unset) /* should not happen */ |
654 | 660 | return error(_("missing value for switch '%s'"), |
655 | 661 | opt->long_name); |
656 | 662 |
|
657 | | - if (!is_directory(arg)) |
658 | | - return error(_("value for switch '%s' is not a directory: '%s'"), |
659 | | - opt->long_name, arg); |
| 663 | + strbuf_addstr(&buf_arg, arg); |
| 664 | + if (strbuf_normalize_path(&buf_arg) < 0) { |
| 665 | + /* |
| 666 | + * Pretend command line wasn't given. Use whatever |
| 667 | + * settings we already have from the config. |
| 668 | + */ |
| 669 | + strbuf_release(&buf_arg); |
| 670 | + return 0; |
| 671 | + } |
| 672 | + strbuf_trim_trailing_dir_sep(&buf_arg); |
| 673 | + |
| 674 | + if (!strbuf_cmp(&buf_arg, &gvfs_shared_cache_pathname)) { |
| 675 | + /* |
| 676 | + * The command line argument matches what we got from |
| 677 | + * the config, so we're already setup correctly. (And |
| 678 | + * we have already verified that the directory exists |
| 679 | + * on disk.) |
| 680 | + */ |
| 681 | + strbuf_release(&buf_arg); |
| 682 | + return 0; |
| 683 | + } |
| 684 | + |
| 685 | + else if (!gvfs_shared_cache_pathname.len) { |
| 686 | + /* |
| 687 | + * A shared-cache was requested and we did not inherit one. |
| 688 | + * Try it, but let alt_odb_usable() secretly disable it if |
| 689 | + * it cannot create the directory on disk. |
| 690 | + */ |
| 691 | + strbuf_addbuf(&gvfs_shared_cache_pathname, &buf_arg); |
660 | 692 |
|
661 | | - gvfs_shared_cache_pathname = arg; |
| 693 | + odb_add_to_alternates_memory(the_repository->objects, buf_arg.buf); |
662 | 694 |
|
663 | | - return 0; |
| 695 | + strbuf_release(&buf_arg); |
| 696 | + return 0; |
| 697 | + } |
| 698 | + |
| 699 | + else { |
| 700 | + /* |
| 701 | + * The requested shared-cache is different from the one |
| 702 | + * we inherited. Replace the inherited value with this |
| 703 | + * one, but smartly fallback if necessary. |
| 704 | + */ |
| 705 | + struct strbuf buf_prev = STRBUF_INIT; |
| 706 | + |
| 707 | + strbuf_addbuf(&buf_prev, &gvfs_shared_cache_pathname); |
| 708 | + |
| 709 | + strbuf_setlen(&gvfs_shared_cache_pathname, 0); |
| 710 | + strbuf_addbuf(&gvfs_shared_cache_pathname, &buf_arg); |
| 711 | + |
| 712 | + odb_add_to_alternates_memory(the_repository->objects, buf_arg.buf); |
| 713 | + |
| 714 | + /* |
| 715 | + * alt_odb_usable() releases gvfs_shared_cache_pathname |
| 716 | + * if it cannot create the directory on disk, so fallback |
| 717 | + * to the previous choice when it fails. |
| 718 | + */ |
| 719 | + if (!gvfs_shared_cache_pathname.len) |
| 720 | + strbuf_addbuf(&gvfs_shared_cache_pathname, |
| 721 | + &buf_prev); |
| 722 | + |
| 723 | + strbuf_release(&buf_arg); |
| 724 | + strbuf_release(&buf_prev); |
| 725 | + return 0; |
| 726 | + } |
664 | 727 | } |
665 | 728 |
|
666 | 729 | /* |
@@ -961,24 +1024,20 @@ static void approve_cache_server_creds(void) |
961 | 1024 | } |
962 | 1025 |
|
963 | 1026 | /* |
964 | | - * Select the ODB directory where we will write objects that we |
965 | | - * download. If was given on the command line or define in the |
966 | | - * config, use the local ODB (in ".git/objects"). |
| 1027 | + * Get the pathname to the ODB where we write objects that we download. |
967 | 1028 | */ |
968 | 1029 | static void select_odb(void) |
969 | 1030 | { |
970 | | - const char *odb_path = NULL; |
| 1031 | + odb_prepare_alternates(the_repository->objects); |
971 | 1032 |
|
972 | 1033 | strbuf_init(&gh__global.buf_odb_path, 0); |
973 | 1034 |
|
974 | | - if (gvfs_shared_cache_pathname && *gvfs_shared_cache_pathname) |
975 | | - odb_path = gvfs_shared_cache_pathname; |
976 | | - else { |
977 | | - odb_prepare_alternates(the_repository->objects); |
978 | | - odb_path = the_repository->objects->sources->path; |
979 | | - } |
980 | | - |
981 | | - strbuf_addstr(&gh__global.buf_odb_path, odb_path); |
| 1035 | + if (gvfs_shared_cache_pathname.len) |
| 1036 | + strbuf_addbuf(&gh__global.buf_odb_path, |
| 1037 | + &gvfs_shared_cache_pathname); |
| 1038 | + else |
| 1039 | + strbuf_addstr(&gh__global.buf_odb_path, |
| 1040 | + the_repository->objects->sources->path); |
982 | 1041 | } |
983 | 1042 |
|
984 | 1043 | /* |
|
0 commit comments