From: Junio C Hamano Date: Sun, 18 Nov 2018 09:23:56 +0000 (+0900) Subject: Merge branch 'ra/rev-parse-exclude-glob' X-Git-Tag: v2.20.0-rc0~16 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/c72431ffc9b48e8b9009e1f95afa9db9d87b099a?ds=inline;hp=-c Merge branch 'ra/rev-parse-exclude-glob' "rev-parse --exclude= --branches=" etc. did not quite work, which has been corrected. * ra/rev-parse-exclude-glob: refs: fix some exclude patterns being ignored refs: show --exclude failure with --branches/tags/remotes=glob --- c72431ffc9b48e8b9009e1f95afa9db9d87b099a diff --combined refs.c index 17e4307f31,539f385f61..f9936355cd --- a/refs.c +++ b/refs.c @@@ -217,6 -217,7 +217,7 @@@ char *resolve_refdup(const char *refnam /* The argument to filter_refs */ struct ref_filter { const char *pattern; + const char *prefix; each_ref_fn *fn; void *cb_data; }; @@@ -296,6 -297,8 +297,8 @@@ static int filter_refs(const char *refn if (wildmatch(filter->pattern, refname, 0)) return 0; + if (filter->prefix) + skip_prefix(refname, filter->prefix, &refname); return filter->fn(refname, oid, flags, filter->cb_data); } @@@ -458,6 -461,7 +461,7 @@@ int for_each_glob_ref_in(each_ref_fn fn } filter.pattern = real_pattern.buf; + filter.prefix = prefix; filter.fn = fn; filter.cb_data = cb_data; ret = for_each_ref(filter_refs, &filter); @@@ -624,7 -628,6 +628,7 @@@ int dwim_log(const char *str, int len, static int is_per_worktree_ref(const char *refname) { return !strcmp(refname, "HEAD") || + starts_with(refname, "refs/worktree/") || starts_with(refname, "refs/bisect/") || starts_with(refname, "refs/rewritten/"); } @@@ -641,34 -644,13 +645,34 @@@ static int is_pseudoref_syntax(const ch return 1; } +static int is_main_pseudoref_syntax(const char *refname) +{ + return skip_prefix(refname, "main-worktree/", &refname) && + *refname && + is_pseudoref_syntax(refname); +} + +static int is_other_pseudoref_syntax(const char *refname) +{ + if (!skip_prefix(refname, "worktrees/", &refname)) + return 0; + refname = strchr(refname, '/'); + if (!refname || !refname[1]) + return 0; + return is_pseudoref_syntax(refname + 1); +} + enum ref_type ref_type(const char *refname) { if (is_per_worktree_ref(refname)) return REF_TYPE_PER_WORKTREE; if (is_pseudoref_syntax(refname)) return REF_TYPE_PSEUDOREF; - return REF_TYPE_NORMAL; + if (is_main_pseudoref_syntax(refname)) + return REF_TYPE_MAIN_PSEUDOREF; + if (is_other_pseudoref_syntax(refname)) + return REF_TYPE_OTHER_PSEUDOREF; + return REF_TYPE_NORMAL; } long get_files_ref_lock_timeout_ms(void) @@@ -724,7 -706,7 +728,7 @@@ static int write_pseudoref(const char * pseudoref); rollback_lock_file(&lock); goto done; - } else if (oidcmp(&actual_old_oid, old_oid)) { + } else if (!oideq(&actual_old_oid, old_oid)) { strbuf_addf(err, _("unexpected object ID when writing '%s'"), pseudoref); rollback_lock_file(&lock); @@@ -766,7 -748,7 +770,7 @@@ static int delete_pseudoref(const char } if (read_ref(pseudoref, &actual_old_oid)) die(_("could not read ref '%s'"), pseudoref); - if (oidcmp(&actual_old_oid, old_oid)) { + if (!oideq(&actual_old_oid, old_oid)) { error(_("unexpected object ID when deleting '%s'"), pseudoref); rollback_lock_file(&lock); @@@ -897,13 -879,13 +901,13 @@@ static int read_ref_at_ent(struct objec */ if (!is_null_oid(&cb->ooid)) { oidcpy(cb->oid, noid); - if (oidcmp(&cb->ooid, noid)) + if (!oideq(&cb->ooid, noid)) warning(_("log for ref %s has gap after %s"), cb->refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822))); } else if (cb->date == cb->at_time) oidcpy(cb->oid, noid); - else if (oidcmp(noid, cb->oid)) + else if (!oideq(noid, cb->oid)) warning(_("log for ref %s unexpectedly ended on %s"), cb->refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822))); @@@ -1416,50 -1398,17 +1420,50 @@@ struct ref_iterator *refs_ref_iterator_ * non-zero value, stop the iteration and return that value; * otherwise, return 0. */ +static int do_for_each_repo_ref(struct repository *r, const char *prefix, + each_repo_ref_fn fn, int trim, int flags, + void *cb_data) +{ + struct ref_iterator *iter; + struct ref_store *refs = get_main_ref_store(r); + + if (!refs) + return 0; + + iter = refs_ref_iterator_begin(refs, prefix, trim, flags); + + return do_for_each_repo_ref_iterator(r, iter, fn, cb_data); +} + +struct do_for_each_ref_help { + each_ref_fn *fn; + void *cb_data; +}; + +static int do_for_each_ref_helper(struct repository *r, + const char *refname, + const struct object_id *oid, + int flags, + void *cb_data) +{ + struct do_for_each_ref_help *hp = cb_data; + + return hp->fn(refname, oid, flags, hp->cb_data); +} + static int do_for_each_ref(struct ref_store *refs, const char *prefix, each_ref_fn fn, int trim, int flags, void *cb_data) { struct ref_iterator *iter; + struct do_for_each_ref_help hp = { fn, cb_data }; if (!refs) return 0; iter = refs_ref_iterator_begin(refs, prefix, trim, flags); - return do_for_each_ref_iterator(iter, fn, cb_data); + return do_for_each_repo_ref_iterator(the_repository, iter, + do_for_each_ref_helper, &hp); } int refs_for_each_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data) @@@ -1504,11 -1453,12 +1508,11 @@@ int refs_for_each_fullref_in(struct ref return do_for_each_ref(refs, prefix, fn, 0, flag, cb_data); } -int for_each_replace_ref(struct repository *r, each_ref_fn fn, void *cb_data) +int for_each_replace_ref(struct repository *r, each_repo_ref_fn fn, void *cb_data) { - return do_for_each_ref(get_main_ref_store(r), - git_replace_ref_base, fn, - strlen(git_replace_ref_base), - DO_FOR_EACH_INCLUDE_BROKEN, cb_data); + return do_for_each_repo_ref(r, git_replace_ref_base, fn, + strlen(git_replace_ref_base), + DO_FOR_EACH_INCLUDE_BROKEN, cb_data); } int for_each_namespaced_ref(each_ref_fn fn, void *cb_data) @@@ -2087,12 -2037,10 +2091,12 @@@ cleanup int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data) { struct ref_iterator *iter; + struct do_for_each_ref_help hp = { fn, cb_data }; iter = refs->be->reflog_iterator_begin(refs); - return do_for_each_ref_iterator(iter, fn, cb_data); + return do_for_each_repo_ref_iterator(the_repository, iter, + do_for_each_ref_helper, &hp); } int for_each_reflog(each_ref_fn fn, void *cb_data) diff --combined t/t6018-rev-list-glob.sh index 270e579c2d,7dc6cbdc42..bb5aeac07f --- a/t/t6018-rev-list-glob.sh +++ b/t/t6018-rev-list-glob.sh @@@ -36,7 -36,13 +36,13 @@@ test_expect_success 'setup' git tag foo/bar master && commit master3 && git update-ref refs/remotes/foo/baz master && - commit master4 + commit master4 && + git update-ref refs/remotes/upstream/one subspace/one && + git update-ref refs/remotes/upstream/two subspace/two && + git update-ref refs/remotes/upstream/x subspace-x && + git tag qux/one subspace/one && + git tag qux/two subspace/two && + git tag qux/x subspace-x ' test_expect_success 'rev-parse --glob=refs/heads/subspace/*' ' @@@ -141,18 -147,54 +147,66 @@@ test_expect_success 'rev-parse accumula compare rev-parse "--exclude=refs/remotes/* --exclude=refs/tags/* --all" --branches ' +test_expect_success 'rev-parse --branches clears --exclude' ' + compare rev-parse "--exclude=* --branches --branches" "--branches" +' + +test_expect_success 'rev-parse --tags clears --exclude' ' + compare rev-parse "--exclude=* --tags --tags" "--tags" +' + +test_expect_success 'rev-parse --all clears --exclude' ' + compare rev-parse "--exclude=* --all --all" "--all" +' + + test_expect_success 'rev-parse --exclude=glob with --branches=glob' ' + compare rev-parse "--exclude=subspace-* --branches=sub*" "subspace/one subspace/two" + ' + + test_expect_success 'rev-parse --exclude=glob with --tags=glob' ' + compare rev-parse "--exclude=qux/? --tags=qux/*" "qux/one qux/two" + ' + + test_expect_success 'rev-parse --exclude=glob with --remotes=glob' ' + compare rev-parse "--exclude=upstream/? --remotes=upstream/*" "upstream/one upstream/two" + ' + + test_expect_success 'rev-parse --exclude=ref with --branches=glob' ' + compare rev-parse "--exclude=subspace-x --branches=sub*" "subspace/one subspace/two" + ' + + test_expect_success 'rev-parse --exclude=ref with --tags=glob' ' + compare rev-parse "--exclude=qux/x --tags=qux/*" "qux/one qux/two" + ' + + test_expect_success 'rev-parse --exclude=ref with --remotes=glob' ' + compare rev-parse "--exclude=upstream/x --remotes=upstream/*" "upstream/one upstream/two" + ' + + test_expect_success 'rev-list --exclude=glob with --branches=glob' ' + compare rev-list "--exclude=subspace-* --branches=sub*" "subspace/one subspace/two" + ' + + test_expect_success 'rev-list --exclude=glob with --tags=glob' ' + compare rev-list "--exclude=qux/? --tags=qux/*" "qux/one qux/two" + ' + + test_expect_success 'rev-list --exclude=glob with --remotes=glob' ' + compare rev-list "--exclude=upstream/? --remotes=upstream/*" "upstream/one upstream/two" + ' + + test_expect_success 'rev-list --exclude=ref with --branches=glob' ' + compare rev-list "--exclude=subspace-x --branches=sub*" "subspace/one subspace/two" + ' + + test_expect_success 'rev-list --exclude=ref with --tags=glob' ' + compare rev-list "--exclude=qux/x --tags=qux/*" "qux/one qux/two" + ' + + test_expect_success 'rev-list --exclude=ref with --remotes=glob' ' + compare rev-list "--exclude=upstream/x --remotes=upstream/*" "upstream/one upstream/two" + ' + test_expect_success 'rev-list --glob=refs/heads/subspace/*' ' compare rev-list "subspace/one subspace/two" "--glob=refs/heads/subspace/*" @@@ -245,7 -287,7 +299,7 @@@ test_expect_success 'rev-list --tags=fo test_expect_success 'rev-list --tags' ' - compare rev-list "foo/bar" "--tags" + compare rev-list "foo/bar qux/x qux/two qux/one" "--tags" ' @@@ -267,7 -309,7 +321,7 @@@ test_expect_success 'rev-list accumulat compare rev-list "--exclude=refs/remotes/* --exclude=refs/tags/* --all" --branches ' -test_expect_failure 'rev-list should succeed with empty output on empty stdin' ' +test_expect_success 'rev-list should succeed with empty output on empty stdin' ' git rev-list --stdin actual && test_must_be_empty actual ' @@@ -304,7 -346,7 +358,7 @@@ test_expect_success 'shortlog accepts - "master other/three someref subspace-x subspace/one subspace/two" \ "--glob=heads/*" && compare shortlog foo/bar --tags=foo && - compare shortlog foo/bar --tags && + compare shortlog "foo/bar qux/one qux/two qux/x" --tags && compare shortlog foo/baz --remotes=foo '