| 2773 | } |
| 2774 | |
| 2775 | enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs, |
| 2776 | const struct string_list *refnames, |
| 2777 | const struct string_list *extras, |
| 2778 | const struct string_list *skip, |
| 2779 | struct ref_transaction *transaction, |
| 2780 | unsigned int initial_transaction, |
| 2781 | struct strbuf *err) |
| 2782 | { |
| 2783 | struct strbuf dirname = STRBUF_INIT; |
| 2784 | struct strbuf referent = STRBUF_INIT; |
| 2785 | struct string_list_item *item; |
| 2786 | struct ref_iterator *iter = NULL; |
| 2787 | struct strset conflicting_dirnames; |
| 2788 | struct strset dirnames; |
| 2789 | int ret = REF_TRANSACTION_ERROR_NAME_CONFLICT; |
| 2790 | |
| 2791 | /* |
| 2792 | * For the sake of comments in this function, suppose that |
| 2793 | * refname is "refs/foo/bar". |
| 2794 | */ |
| 2795 | |
| 2796 | assert(err); |
| 2797 | |
| 2798 | strset_init(&conflicting_dirnames); |
| 2799 | strset_init(&dirnames); |
| 2800 | |
| 2801 | for_each_string_list_item(item, refnames) { |
| 2802 | const size_t *update_idx = (size_t *)item->util; |
| 2803 | const char *refname = item->string; |
| 2804 | const char *extra_refname; |
| 2805 | struct object_id oid; |
| 2806 | unsigned int type; |
| 2807 | const char *slash; |
| 2808 | |
| 2809 | strbuf_reset(&dirname); |
| 2810 | |
| 2811 | for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) { |
| 2812 | /* |
| 2813 | * Just saying "Is a directory" when we e.g. can't |
| 2814 | * lock some multi-level ref isn't very informative, |
| 2815 | * the user won't be told *what* is a directory, so |
| 2816 | * let's not use strerror() below. |
| 2817 | */ |
| 2818 | int ignore_errno; |
| 2819 | |
| 2820 | /* Expand dirname to the new prefix, not including the trailing slash: */ |
| 2821 | strbuf_add(&dirname, refname + dirname.len, slash - refname - dirname.len); |
| 2822 | |
| 2823 | /* |
| 2824 | * We are still at a leading dir of the refname (e.g., |
| 2825 | * "refs/foo"; if there is a reference with that name, |
| 2826 | * it is a conflict, *unless* it is in skip. |
| 2827 | */ |
| 2828 | if (skip && string_list_has_string(skip, dirname.buf)) |
| 2829 | continue; |
| 2830 | |
| 2831 | /* |
| 2832 | * If we've already seen the directory we don't need to |
no test coverage detected