Skip to content

Remote::push rejects the refs/tags/* glob used by Push with tags #34

Description

@noyobo

What happened?

Toolbar Push → Push with tags fails with:

not a valid reference 'refs/tags/*'; class=Invalid (3)

Expected: the current branch plus local tags are pushed, the same way git push --tags expands the glob locally.

Environment

  • AngKorGit 0.16.0 (tauri.conf.json)
  • macOS
  • Embedding: Tauri / WKWebView (same git2 Remote::push path)

Steps

  1. Open a repository that has at least one local tag not yet on origin.
  2. Toolbar Push → Push with tags.
  3. The command errors with the message above. A plain Push (no tags) on the same repo succeeds.

Repository shape

Any repo with a reachable origin and a local refs/tags/* name is enough. Not specific to submodules, large history, or a particular host.

What this is not

  • Not auth / HTTP status — the failure is GIT_ERROR_INVALID before a useful receive-pack.
  • Not “no tags to push”. The glob is rejected even when tags exist.
  • Not Force Push. The tags refspec is unforced; only the branch spec gets +.

push_refspecs in apps/desktop/src-tauri/src/core/remote.rs appends refs/tags/*:refs/tags/* when with_tags is set. Git’s CLI expands that glob to named refs before talking to the remote. libgit2 Remote::push() looks up the source as a literal reference, and * is not a valid ref name. Single-tag push_tag already uses refs/tags/{name}:refs/tags/{name} and does not hit this.


Options we considered

  • Keep the glob. Matches git push --tags on paper, but libgit2 does not expand push-side globs, so the command stays broken.
  • Enumerate local tags into named refspecs (refs/tags/v1.0.0:refs/tags/v1.0.0, …). Same shape as push_tag, no extra ls-remote. Cost: a repo with hundreds of tags sends hundreds of specs; tags already on the remote are offered again (usually no-ops).
  • Enumerate only tags missing on the remote (one ls-remote, same idea as an unpushed-tags inventory). Fewer specs; extra network round-trip before every Push with tags, and a moved local tag still needs a non-fast-forward decision.
  • Shell out to git push --tags. Avoids the libgit2 gap; splits the push path away from the rest of remote::push.

What we verified works

Against a local bare remote we listed tags with Repository::tag_foreach, built one named refspec per tag, and called Remote::push with the branch spec plus those names. A lightweight v1.0.0 arrived on the remote.

We did not try annotated tags, tags whose remote tip already differs, or running the 0.16.0 app binary itself — only the engine path above.


Questions for the maintainer

  1. Was refs/tags/*:refs/tags/* meant as git’s --tags equivalent, or is there a libgit2 API we missed that expands push globs?
  2. If you enumerate names, should Push with tags send every local tag, or only tags the remote does not already advertise?
  3. Should a moved local tag (same name, different oid) fail as non-fast-forward, or is Force on the branch supposed to apply to tags as well? Today the + prefix is only on the branch spec.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions