diff options
| author | Julia Evans <julia@jvns.ca> | 2025-09-23 18:10:49 +0000 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2025-09-24 12:29:34 -0700 |
| commit | 657586a5a6ddfa1d6c732b8b0f4670d198a4be02 (patch) | |
| tree | fc9fd4b32a46c9e6f482cd00593be21b8f29fb59 | |
| parent | cc1cc31e2a46e33941840bbb2026fff2d0532b2b (diff) | |
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>
| -rw-r--r-- | Documentation/git-push.adoc | 105 |
1 files changed, 58 insertions, 47 deletions
diff --git a/Documentation/git-push.adoc b/Documentation/git-push.adoc index cf506ab8b4..cc5cadcdfc 100644 --- a/Documentation/git-push.adoc +++ b/Documentation/git-push.adoc @@ -55,54 +55,65 @@ OPTIONS[[OPTIONS]] <refspec>...:: Specify what destination ref to update with what source object. - The format of a <refspec> parameter is an optional plus - `+`, followed by the source object <src>, followed - by a colon `:`, followed by the destination ref <dst>. -+ -The <src> is often the name of the branch you would want to push, but -it can be any arbitrary "SHA-1 expression", such as `master~4` or -`HEAD` (see linkgit:gitrevisions[7]). -+ -The <dst> tells which ref on the remote side is updated with this -push. Arbitrary expressions cannot be used here, an actual ref must -be named. -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, `:<dst>` part can -be omitted--such a push will update a ref that `<src>` normally updates -without any `<refspec>` on the command line. Otherwise, missing -`:<dst>` means to update the same ref as the `<src>`. -+ -If <dst> doesn't start with `refs/` (e.g. `refs/heads/master`) we will -try to infer where in `refs/*` on the destination <repository> it -belongs based on the type of <src> being pushed and whether <dst> -is ambiguous. + --- -* If <dst> unambiguously refers to a ref on the <repository> remote, - then push to that ref. - -* If <src> resolves to a ref starting with refs/heads/ or refs/tags/, - then prepend that to <dst>. - -* Other ambiguity resolutions might be added in the future, but for - now any other cases will error out with an error indicating what we - tried, and depending on the `advice.pushUnqualifiedRefname` - configuration (see linkgit:git-config[1]) suggest what refs/ - namespace you may have wanted to push to. - -Pushing an empty <src> allows you to delete the <dst> ref from the -remote repository. Deletions are always accepted without a leading `+` -in the refspec (or `--force`), except when forbidden by configuration -or hooks. See `receive.denyDeletes` in linkgit:git-config[1] and -`pre-receive` and `update` in linkgit:githooks[5]. -+ -The special refspec `:` (or `+:` to allow non-fast-forward updates) -directs Git to push "matching" branches: for every branch that exists on -the local side, the remote side is updated if a branch of the same name -already exists on the remote side. -+ -`tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`. +The format for a refspec is [+]<src>[:<dst>], for example `main`, +`main:other`, or `HEAD^:refs/heads/main`. ++ +The `<src>` is often the name of the local branch to push, but it can be +any arbitrary "SHA-1 expression" (see linkgit:gitrevisions[7]). ++ +The `<dst>` determines what ref to update on the remote side. It must be the +name of a branch, tag, or other ref, not an arbitrary expression. ++ +The `+` is optional and does the same thing as `--force`. ++ +You can write a refspec using the fully expanded form (for +example `refs/heads/main:refs/heads/main`) which specifies the exact source +and destination, or with a shorter form (for example `main` or +`main:other`). Here are the rules for how refspecs are expanded, +as well as various other special refspec forms: ++ + * `<src>` without a `:<dst>` means to update the same ref as the + `<src>`, unless the `remote.<repository>.push` configuration specifies a + different <dst>. For example, if `main` is a branch, then the refspec + `main` expands to `main:refs/heads/main`. + * If `<dst>` unambiguously refers to a ref on the <repository> remote, + then expand it to that ref. For example, if `v1.0` is a tag on the + remote, then `HEAD:v1.0` expands to `HEAD:refs/tags/v1.0`. + * If `<src>` resolves to a ref starting with `refs/heads/` or `refs/tags/`, + then prepend that to <dst>. For example, if `main` is a branch, then + `main:other` expands to `main:refs/heads/other` + * The special refspec `:` (or `+:` to allow non-fast-forward updates) + directs Git to push "matching" branches: for every branch that exists on + the local side, the remote side is updated if a branch of the same name + already exists on the remote side. + * <src> may contain a * to indicate a simple pattern match. + This works like a glob that matches any ref matching the pattern. + There must be only one * in both the `<src>` and `<dst>`. + It will map refs to the destination by replacing the * with the + contents matched from the source. For example, `refs/heads/*:refs/heads/*` + will push all branches. + * A refspec starting with `^` is a negative refspec. + This specifies refs to exclude. A ref will be considered to + match if it matches at least one positive refspec, and does not + match any negative refspec. Negative refspecs can be pattern refspecs. + They must only contain a `<src>`. + Fully spelled out hex object names are also not supported. + For example, `git push origin 'refs/heads/*' '^refs/heads/dev-*'` + will push all branches except for those starting with `dev-` + * If `<src>` is empty, it deletes the `<dst>` ref from the remote + repository. For example, `git push origin :dev` will + delete the `dev` branch. + * `tag <tag>` expands to `refs/tags/<tag>:refs/tags/<tag>`. + This is technically a special syntax for `git push` and not a refspec, + since in `git push origin tag v1.0` the arguments `tag` and `v1.0` + are separate. + * If the refspec can't be expanded unambiguously, error out + with an error indicating what was tried, and depending + on the `advice.pushUnqualifiedRefname` configuration (see + linkgit:git-config[1]) suggest what refs/ namespace you may have + wanted to push to. + Not all updates are allowed: see PUSH RULES below for the details. --all:: |
