How to push specific branch to remote with go-git

huangapple go评论66阅读模式
英文:

How to push specific branch to remote with go-git

问题

什么是使用go-git将特定的本地分支推送到特定远程仓库的规范方法?

我有一个已经用go-git检出和打开的本地仓库:

repo, err := git.PlainOpen("my-repo")

该仓库有一个默认的origin远程仓库。

我正在尝试将该仓库的内容同步到另一个名为mirror的远程仓库,所以我添加了这个远程仓库:

repo.CreateRemote(&config.RemoteConfig{
    Name: "mirror",
    URLs: []string{"git@github.com:foo/mirror.git"},
})

首先,我从origin远程仓库获取仓库内容:

err = remote.Fetch(&git.FetchOptions{
    RemoteName: "origin",
    Tags:       git.AllTags,
})

...然后使用remote.List()来获取所有感兴趣的分支和标签。

最后一步是将这些分支推送到mirror远程仓库,并根据映射重写分支名称。例如,将检出的refs/remotes/origin/master分支作为refs/heads/master推送到mirror远程仓库的main分支。因此,我遍历这些分支,并尝试逐个推送它们:

refSpec := config.RefSpec(fmt.Sprintf(
    "+%s:refs/remotes/mirror/%s",
    localBranch.Name().String(),
    // 映射分支名称,例如 master -> main
    mapBranch(remoteBranch.Name().Short()),
))
err = repo.Push(&git.PushOptions{
    RemoteName: "mirror",
    Force:      true,
    RefSpecs:   []config.RefSpec{refSpec},
    Atomic:     true,
})

但是这会导致git.NoErrAlreadyUpToDate错误,并且在mirror远程仓库上没有任何操作发生。

英文:

What is the canonical way to push specific single local branch to specific remote with go-git?

I have a local repository checked out and opened with go-git

repo, err := git.PlainOpen("my-repo")

The repo has default origin remote.

I'm trying to sync contents of this repository to another remote mirror, so I'm adding the remote

repo.CreateRemote(&config.RemoteConfig{
				Name: "mirror",
				URLs: []string{"git@github.com:foo/mirror.git"},
			})

First I fetch repo contents from origin

err = remote.Fetch(&git.FetchOptions{
				RemoteName: "origin",
				Tags:       git.AllTags,
			})

... and do a discovery of all branches and tags of interest with remote.List()

Final step is pushing the branches to mirror, while rewriting branch names based on a map. E.g. refs/remotes/origin/master checked out as refs/heads/master should be pushed to mirror remote as main. Therefore I'm iterating over the branches and trying to push them one by one:

refSpec := config.RefSpec(fmt.Sprintf(
				"+%s:refs/remotes/mirror/%s",
				localBranch.Name().String(),
                // map branch names, e.g. master -> main
				mapBranch(remoteBranch.Name().Short()),
			))
err = repo.Push(&git.PushOptions{
				RemoteName: "mirror",
				Force:      true,
				RefSpecs:   []config.RefSpec{refSpec},
				Atomic:     true,
			})

But this results in git.NoErrAlreadyUpToDate and there's nothing happening on the mirror remote.

答案1

得分: 2

refSpec在将单个分支推送到远程时,不应该采用+refs/heads/localBranchName:refs/remotes/remoteName/remoteBranchName的格式,如这里所示:

// RefSpec是从本地分支到远程引用的映射。
...
// 例如:"+refs/heads/*:refs/remotes/origin/*"
//
// https://git-scm.com/book/en/v2/Git-Internals-The-Refspec
type RefSpec string

而应该采用以下格式:

"+refs/heads/localBranchName:refs/heads/remoteBranchName"

请参考示例

    refSpecStr := fmt.Sprintf(
	    "+%s:refs/heads/%s",
		localBranch.Name().String(),
		mapBranch(remoteBranch.Name().Short()),
	)
	refSpec := config.RefSpec(refSpecStr)
	log.Infof("Pushing %s", refSpec)
	err = repo.Push(&git.PushOptions{
		RemoteName: "mirror",
		Force:      true,
		RefSpecs:   []config.RefSpec{refSpec},
		Atomic:     true,
	})
英文:

The refSpec, when pushing single branch to a remote, should NOT be in format +refs/heads/localBranchName:refs/remotes/remoteName/remoteBranchName as indicate e.g. here:

// RefSpec is a mapping from local branches to remote references.
...
// eg.: "+refs/heads/*:refs/remotes/origin/*"
//
// https://git-scm.com/book/en/v2/Git-Internals-The-Refspec
type RefSpec string

but as

"+refs/heads/localBranchName:refs/heads/remoteBranchName"

instead. See example:

    refSpecStr := fmt.Sprintf(
	    "+%s:refs/heads/%s",
		localBranch.Name().String(),
		mapBranch(remoteBranch.Name().Short()),
	)
	refSpec := config.RefSpec(refSpecStr)
	log.Infof("Pushing %s", refSpec)
	err = repo.Push(&git.PushOptions{
		RemoteName: "mirror",
		Force:      true,
		RefSpecs:   []config.RefSpec{refSpec},
		Atomic:     true,
	})

huangapple
  • 本文由 发表于 2023年3月11日 09:56:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/75702337.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定