doc: git-push: rewrite refspec specification

From user feedback, there was a request for examples, as well as a comment that one person found "If git push [<repository>] without any <refspec> argument is set to update some ref at the destination with <src> with remote.<repository>.push configuration variable..." impossible to understand. To make the section easier to navigate, create a list of every possible refspec form, with examples for each form as well as 2 forms which were previously missing (patterns and negative refspecs). Made a few changes to use more familiar language, but ultimately refspecs are a pretty advanced feature so I've mostly left the terminology alone. Signed-off-by: Julia Evans <julia@jvns.ca> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Julia Evans committed Sep 23, 2025 at 18:10 UTC 657586a5a6ddfa1d6c732b8b0f4670d198a4be02
1 file changed +58 -47
Documentation/git-push.adoc
+58 -47
@@ -55,54 +55,65 @@ OPTIONS[[OPTIONS]]
55
56 <refspec>...::
57 Specify what destination ref to update with what source object.
58 - The format of a <refspec> parameter is an optional plus
59 - `+`, followed by the source object <src>, followed
60 - by a colon `:`, followed by the destination ref <dst>.
61 -+
62 -The <src> is often the name of the branch you would want to push, but
63 -it can be any arbitrary "SHA-1 expression", such as `master~4` or
64 -`HEAD` (see linkgit:gitrevisions[7]).
65 -+
66 -The <dst> tells which ref on the remote side is updated with this
67 -push. Arbitrary expressions cannot be used here, an actual ref must
68 -be named.
69 -If `git push [<repository>]` without any `<refspec>` argument is set to
70 -update some ref at the destination with `<src>` with
71 -`remote.<repository>.push` configuration variable, `:<dst>` part can
72 -be omitted--such a push will update a ref that `<src>` normally updates
73 -without any `<refspec>` on the command line. Otherwise, missing
74 -`:<dst>` means to update the same ref as the `<src>`.
75 -+
76 -If <dst> doesn't start with `refs/` (e.g. `refs/heads/master`) we will
77 -try to infer where in `refs/*` on the destination <repository> it
78 -belongs based on the type of <src> being pushed and whether <dst>
79 -is ambiguous.
58 +
81 ---
82 -* If <dst> unambiguously refers to a ref on the <repository> remote,
83 - then push to that ref.
84 -
85 -* If <src> resolves to a ref starting with refs/heads/ or refs/tags/,
86 - then prepend that to <dst>.
87 -
88 -* Other ambiguity resolutions might be added in the future, but for
89 - now any other cases will error out with an error indicating what we
90 - tried, and depending on the `advice.pushUnqualifiedRefname`
91 - configuration (see linkgit:git-config[1]) suggest what refs/
92 - namespace you may have wanted to push to.
93 -
94 -Pushing an empty <src> allows you to delete the <dst> ref from the
95 -remote repository. Deletions are always accepted without a leading `+`
96 -in the refspec (or `--force`), except when forbidden by configuration
97 -or hooks. See `receive.denyDeletes` in linkgit:git-config[1] and
98 -`pre-receive` and `update` in linkgit:githooks[5].
99 -+
100 -The special refspec `:` (or `+:` to allow non-fast-forward updates)
101 -directs Git to push "matching" branches: for every branch that exists on
102 -the local side, the remote side is updated if a branch of the same name
103 -already exists on the remote side.
104 -+
105 -`tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
59 +The format for a refspec is [+]<src>[:<dst>], for example `main`,
60 +`main:other`, or `HEAD^:refs/heads/main`.
61 ++
62 +The `<src>` is often the name of the local branch to push, but it can be
63 +any arbitrary "SHA-1 expression" (see linkgit:gitrevisions[7]).
64 ++
65 +The `<dst>` determines what ref to update on the remote side. It must be the
66 +name of a branch, tag, or other ref, not an arbitrary expression.
67 ++
68 +The `+` is optional and does the same thing as `--force`.
69 ++
70 +You can write a refspec using the fully expanded form (for
71 +example `refs/heads/main:refs/heads/main`) which specifies the exact source
72 +and destination, or with a shorter form (for example `main` or
73 +`main:other`). Here are the rules for how refspecs are expanded,
74 +as well as various other special refspec forms:
75 ++
76 + * `<src>` without a `:<dst>` means to update the same ref as the
77 + `<src>`, unless the `remote.<repository>.push` configuration specifies a
78 + different <dst>. For example, if `main` is a branch, then the refspec
79 + `main` expands to `main:refs/heads/main`.
80 + * If `<dst>` unambiguously refers to a ref on the <repository> remote,
81 + then expand it to that ref. For example, if `v1.0` is a tag on the
82 + remote, then `HEAD:v1.0` expands to `HEAD:refs/tags/v1.0`.
83 + * If `<src>` resolves to a ref starting with `refs/heads/` or `refs/tags/`,
84 + then prepend that to <dst>. For example, if `main` is a branch, then
85 + `main:other` expands to `main:refs/heads/other`
86 + * The special refspec `:` (or `+:` to allow non-fast-forward updates)
87 + directs Git to push "matching" branches: for every branch that exists on
88 + the local side, the remote side is updated if a branch of the same name
89 + already exists on the remote side.
90 + * <src> may contain a * to indicate a simple pattern match.
91 + This works like a glob that matches any ref matching the pattern.
92 + There must be only one * in both the `<src>` and `<dst>`.
93 + It will map refs to the destination by replacing the * with the
94 + contents matched from the source. For example, `refs/heads/*:refs/heads/*`
95 + will push all branches.
96 + * A refspec starting with `^` is a negative refspec.
97 + This specifies refs to exclude. A ref will be considered to
98 + match if it matches at least one positive refspec, and does not
99 + match any negative refspec. Negative refspecs can be pattern refspecs.
100 + They must only contain a `<src>`.
101 + Fully spelled out hex object names are also not supported.
102 + For example, `git push origin 'refs/heads/*' '^refs/heads/dev-*'`
103 + will push all branches except for those starting with `dev-`
104 + * If `<src>` is empty, it deletes the `<dst>` ref from the remote
105 + repository. For example, `git push origin :dev` will
106 + delete the `dev` branch.
107 + * `tag <tag>` expands to `refs/tags/<tag>:refs/tags/<tag>`.
108 + This is technically a special syntax for `git push` and not a refspec,
109 + since in `git push origin tag v1.0` the arguments `tag` and `v1.0`
110 + are separate.
111 + * If the refspec can't be expanded unambiguously, error out
112 + with an error indicating what was tried, and depending
113 + on the `advice.pushUnqualifiedRefname` configuration (see
114 + linkgit:git-config[1]) suggest what refs/ namespace you may have
115 + wanted to push to.
116 +
117 Not all updates are allowed: see PUSH RULES below for the details.
118
119 --all::