跳到主要内容

Git 推送映射配置

提示

remote.<name>.push 用于给某个 remote 显式声明一条"本地分支 → 远端分支"的推送映射(push refspec)。一旦配置了它,裸git push 会忽略 push.default,改为始终按这条固定映射推送,与当前所在分支无关

语法

git config remote.<name>.push <src>:<dst>
  • <name>:remote 名称,如 origin
  • <src>:本地 ref,通常写作 refs/heads/<本地分支名>,也可以用 HEAD 表示"当前所在分支"
  • <dst>:远端 ref,通常写作 refs/heads/<远端分支名>
  • : 是分隔符,含义是"把 <src> 推送到 <dst>"

配置之后,裸 git push(不带任何参数)在语义上等价于:

git push <name> <src>:<dst>

落地位置:.git/config

git config remote.<name>.push <src>:<dst> 本质上只是在修改仓库的 .git/config 文件(加 --global 则写入 ~/.gitconfig),在对应 remote 的配置段里追加一行 push = <src>:<dst>。例如原本的 .git/config 是:

[remote "origin"]
url = git@github.com:acme/webapp.git
fetch = +refs/heads/*:refs/remotes/origin/*

执行:

git config remote.origin.push refs/heads/dev:refs/heads/dev

后会变成:

[remote "origin"]
url = git@github.com:acme/webapp.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/dev:refs/heads/dev

也可以跳过 git config 命令,直接用编辑器打开 .git/config 手动加上 push = ... 这一行,效果完全一样。删除时同理,把这一行删掉,或者执行 git config --unset remote.origin.push。下面每个场景都会同时给出对应命令和它在 .git/config 中的落地内容。

常见写法对照

配置含义
remote.origin.push refs/heads/dev:refs/heads/devgit push 始终推送本地 dev 到远端 dev
remote.origin.push refs/heads/master:refs/heads/mastergit push 始终推送本地 master 到远端 master,与当前所在分支无关
remote.origin.push refs/heads/*:refs/heads/*git push 推送所有本地分支到远端同名分支(类似旧版 push.default=matching
remote.origin.push HEAD:refs/heads/release不管当前在哪个分支,都把它推到远端固定的 release 分支
不配置遵循 push.default(现代 Git 默认 simple,即推当前分支到同名远端分支)

配置案例

场景一:本地任意分支统一发布到固定分支

某些团队希望"不管在哪个本地分支上开发,裸 git push 都统一推到远端的 staging 分支",可以这样配置:

git config remote.origin.push HEAD:refs/heads/staging

.git/config 变化:

[remote "origin"]
url = git@github.com:acme/webapp.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = HEAD:refs/heads/staging

效果:

git checkout feature-x
git push # 实际执行:本地 feature-x → 远端 staging

场景二:把裸 git push 锁定为固定分支

假设仓库地址为 git@github.com:acme/webapp.git,团队约定只能通过固定流程发布 master,希望即使有人在其他分支下手滑执行了裸 git push,也不会误推到错误的远端分支,可以这样配置:

git config remote.origin.push refs/heads/master:refs/heads/master

.git/config 变化:

[remote "origin"]
url = git@github.com:acme/webapp.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/master

配置后,无论当前在哪个分支,裸 git push 都只会尝试把本地 master 推到远端 master

git checkout dev
git push --dry-run
To github.com:acme/webapp.git
! [rejected] master -> master (non-fast-forward)

可以看到即便当前在 dev 分支,实际尝试推送的仍是 master -> master(上例中因为本地 master 落后于远端而被拒绝)。如果这不是预期行为,说明当前不需要这条固定映射,直接移除即可:

git config --unset remote.origin.push
备注

这条配置会让裸 git push 的行为脱离"推当前分支"的直觉——不管在哪个分支下执行,结果都只跟 master 有关。团队协作时容易造成困惑(比如以为在推 dev,实际什么都没推上去或推错了分支),务必在仓库 README 或团队文档中注明;如果只是偶尔需要把某个分支推到远端,用 git push origin <branch> 显式指定即可绕开这条固定映射,不需要专门为此改配置。

场景三:配合多个 remote 使用

一个仓库可以同时配置多个 remote,比如常见的 fork 协作模式:

git remote add origin git@github.com:my-name/webapp.git
git remote add upstream git@github.com:acme/webapp.git

remote.<name>.push按 remote 独立配置的,不同 remote 互不影响。比如只想在推送到 upstream 时固定映射到 main,而 origin 保持默认行为:

git config remote.upstream.push refs/heads/main:refs/heads/main

.git/config 会有两个独立的 [remote ...] 段,只有 upstream 那段带 push

[remote "origin"]
url = git@github.com:my-name/webapp.git
fetch = +refs/heads/*:refs/remotes/origin/*

[remote "upstream"]
url = git@github.com:acme/webapp.git
fetch = +refs/heads/*:refs/remotes/upstream/*
push = refs/heads/main:refs/heads/main

此时:

git push origin # 遵循 push.default,推当前分支到 origin 同名分支
git push upstream # 忽略当前分支,固定推送 main -> main

再比如一个仓库同时对接 GitHub 和 GitLab 两个远端做双向备份:

git remote add origin git@github.com:acme/webapp.git
git remote add mirror git@gitlab.com:acme/webapp.git

如果希望裸 git push 只推送到 origin(默认行为即可),备份仓库通过显式命令单独同步,则不需要给 mirror 配置 remote.mirror.push,直接用:

git push mirror HEAD:refs/heads/dev

即可按需推送,不影响 origin 的默认推送行为。

备注

remote.<name>.push 可以配置多条(多次执行 git config --add remote.<name>.push <src>:<dst>),此时裸 git push 会依次按所有映射规则推送,适合"一次裸 push 同时更新多个远端分支"的场景。落到 .git/config 里就是同一个 remote 段下出现多行 push

[remote "origin"]
url = git@github.com:acme/webapp.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/dev:refs/heads/dev
push = refs/heads/dev:refs/heads/backup-dev

参考