Git远程仓库支持多个URL的配置方法Multiple URLs in Git Remote
文章介绍了Git远程仓库支持多个URL的技术实现方式。传统上Git远程只包含单个URL,但现在可以通过特定配置实现多个URL同时指向不同代码托管平台(如Codeberg)。这种配置允许开发者在不同平台间灵活切换,同时保持本地仓库的统一管理。
作者 Susam Pal,2026年4月29日
通常一个 Git 远程仓库只包含一个 URL。例如,当我们克隆一个仓库时,会自动创建一个名为 origin 的远程,并将其 URL 设置为上游仓库的位置。例如:
$ git remote -v
origin https://codeberg.org/spxy/spica.git (fetch)
origin https://codeberg.org/spxy/spica.git (push)
$ sed '/remote/,$!d' .git/config
[remote "origin"]
url = https://codeberg.org/spxy/spica.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main一个可能不太为人所知的细节是,我们可以为一个远程设置多个 URL。例如:
$ git remote set-url origin --add https://github.com/spxy/spica.git
$ git remote -v
origin https://codeberg.org/spxy/spica.git (fetch)
origin https://codeberg.org/spxy/spica.git (push)
origin https://github.com/spxy/spica.git (push)
$ sed '/remote/,$!d' .git/config
[remote "origin"]
url = https://codeberg.org/spxy/spica.git
fetch = +refs/heads/*:refs/remotes/origin/*
url = https://github.com/spxy/spica.git
[branch "main"]
remote = origin
merge = refs/heads/main从上述输出可以看出,当同一个远程配置了多个 URL 时,第一个 URL 会成为 fetch(获取)URL,而所有 URL 都会成为 push(推送)URL。例如:
$ git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 327 bytes | 109.00 KiB/s, done.
From https://codeberg.org/spxy/spica
d473dde..31db503 main -> origin/main
Updating d473dde..31db503
Fast-forward
README.md | 1 +
1 file changed, 1 insertion(+)
$ git log --oneline
31db503 (HEAD -> main, origin/main, origin/HEAD) Explain that Spica is a binary star system
d473dde Create README.md上述输出确认了 fetch 操作是从第一个远程 URL 执行的。尽管输出显示 origin 包含了提交 31db503,但 origin 的所有远程位置可能尚未接收到该提交。由于我们没有配置 pushurl,默认情况下推送会发送到所有远程 URL。例如:
$ echo 'It is about 250 light years away from the Sun.' >> README.md
$ git add README.md
$ git commit -m 'Mention distance from the Sun'
[main 816998d] Mention distance from the Sun
1 file changed, 1 insertion(+)
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 10 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 325 bytes | 325.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
To https://codeberg.org/spxy/spica.git
31db503..816998d main -> main
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 10 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (9/9), 791 bytes | 791.00 KiB/s, done.
Total 9 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (2/2), done.
To https://github.com/spxy/spica.git
* [new branch] main -> main
$ git log --oneline
816998d (HEAD -> main, origin/main, origin/HEAD) Mention distance from the Sun
31db503 Explain that Spica is a binary star system
d473dde Create README.md可以按如下方式设置 pushurl:
$ git remote set-url --push origin https://github.com/spxy/spica.git
$ git remote -v
origin https://codeberg.org/spxy/spica.git (fetch)
origin https://github.com/spxy/spica.git (push)
$ sed '/remote/,$!d' .git/config
[remote "origin"]
url = https://codeberg.org/spxy/spica.git
fetch = +refs/heads/*:refs/remotes/origin/*
url = https://github.com/spxy/spica.git
pushurl = https://github.com/spxy/spica.git
[branch "main"]
remote = origin
merge = refs/heads/main当设置了一个或多个 pushurl 时,推送只会发送到这些指定的位置。而获取(fetch)仍会继续像之前一样从第一个 URL 进行。
$ echo 'Its two stars orbit each other roughly every four days.' >> README.md
$ git add README.md
$ git commit -m 'Mention the four-day orbital period'
[main 2e9f4e8] Mention the four-day orbital period
1 file changed, 1 insertion(+)
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 10 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 342 bytes | 342.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/spxy/spica.git
816998d..2e9f4e8 main -> main
$ git log --oneline
2e9f4e8 (HEAD -> main, origin/main, origin/HEAD) Mention the four-day orbital period
816998d Mention distance from the Sun
31db503 Explain that Spica is a binary star system
d473dde Create README.md注意在这种情况下,新的提交仅被推送到第二个远程 URL。如果我们执行 pull 操作,Git 将从第一个远程 URL 获取更改,并将 origin/main 分支回退到该位置的最新提交。例如:
$ git pull
From https://codeberg.org/spxy/spica
+ 2e9f4e8...816998d main -> origin/main (forced update)
Already up to date.
$ git log --oneline
2e9f4e8 (HEAD -> main) Mention the four-day orbital period
816998d (origin/main, origin/HEAD) Mention distance from the Sun
31db503 Explain that Spica is a binary star system
d473dde Create README.md因此,配置单独的 pushurl 需要谨慎。它仅在少数特定场景下有用,例如从一个我们想当作只读的主仓库获取内容,同时向镜像仓库推送更改的情况。
pushurl 与普通远程 URL 的区别在 Git 2.54.0 的 man git-fetch 和 man git-push 手册中也有说明:
<pushurl> 仅用于推送操作。它是可选的,默认为 <URL>。推送到远程会影响所有定义的 pushurls,或者在没有定义 pushurls 时影响所有定义的 urls。然而,获取操作只有在定义了多个 urls 时才会仅从第一个定义的 url 获取。
需要完整排版与评论请前往来源站点阅读。