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