推送除了特定分支以外的所有分支

7
我和我的队友正在使用OpenShift进行同一项目的开发。我们有几个分支需要在服务器上,所以我们使用push --all命令。我和我的队友都希望拥有本地分支(叫做LocalTest),用于本地测试和开发。问题是当我们使用push --all命令时,会为所有分支创建一个包含LocalTest的远程分支。
顺便说一下,有时候我们需要将其他分支合并到我们的本地分支中,特别是在从服务器拉取新提交后,还想要挑选或合并(很少)其他分支中的提交到我们的本地分支,然后再推送到服务器。
是否有像git push --all except branch-name这样的git命令?对于我们的问题,最好的解决方案是什么?

我忘了指出,有时候我们需要将其他分支合并到我们的本地分支中,特别是在从服务器拉取它们的新提交之后。这对于2个克隆是完全兼容的,所以不用担心。 - VonC
还想从我们的本地分支中挑选或者合并(很少)到其他分支,与两个克隆版本完全兼容。 - VonC
@Lonely 我明白我的回答并不符合你的期望,但它仍然是一个有效的方法/解决方案,不应该被点踩。 - VonC
@VonC 谢谢您的快速反馈,但期望的结果应该是 git push --all except branch-name 的方向。我也会很高兴使用与复杂/级联 git/bash 命令相关联的别名。因为我几乎每天都需要在每个项目中使用它(有多个分支和多个项目..),git push --all except master 也是一个不错的开始.. - user3025289
4个回答

2
这个最简单的方法是将push.default设置为matching。 想要推送的任何分支,请给它们与上游仓库匹配的名称。不想推送的分支,请给它们不存在的名称。然后你只需要使用裸命令git push即可。 如果你想在本地仅使用上游分支的版本,请给它一个不匹配的名称,例如git checkout -b local/master origin/master

请给我们更多的例子。 - Seyed Ali Roshan
你想要推送到 origin 的分支,你需要给它们与 origin 上相同的名称。你不想推送的分支,你需要给它们一个不同的名称,一个在 origin 上不存在的名称。这就是如何从 push.defaultmatching 中排除本地分支的方法,你需要给它一个不匹配其他仓库中任何分支的名称。在 Git 中,分支名称严格限制于仓库本地,你可以随意命名本地分支。重要的是提交历史记录,而不是它们在这个或那个仓库中的名称。 - jthill

1

git push --all except master也是一个不错的开始

问题是:refspec模式相当有限。

refspec文档很清楚:

您无法在模式中使用部分通配符,因此这将是无效的:

fetch = +refs/heads/qa*:refs/remotes/origin/qa*

然而,你可以使用命名空间(或目录)来实现类似的功能。如果你拥有一个推送一系列分支的QA团队,并且你想获取主分支和任何QA团队的分支,但不想获取其他分支,则可以使用以下配置部分:
[remote "origin"]
    url = https://github.com/schacon/simplegit-progit
    fetch = +refs/heads/master:refs/remotes/origin/master
    fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*

如果你有一个复杂的工作流程,其中有一个QA团队推送分支、开发人员推送分支和集成团队在远程分支上推送和协作,那么你可以通过这种方式轻松地对它们进行命名空间管理。
这种方法同样适用于git push,使用remote.<name>.push条目。
这样,一个默认的git push只会推送所需的refspecs...前提是排除的分支位于一个单独的命名空间中。
而且这仍然是一种白名单方法:你必须为每个命名空间列出想要推送的分支,并留下不想要的那个命名空间。
工作示例:
cd /path/to/repos
git init example
echo test>afile
git add .
git commit -m "First commit in master"
git checkout -b private/abranch
echo abranch>>afile
git add .
git commit -m "First commit in a private branch"
git checkout master

cd ..
git init --bare example.git
cd example
git remote add origin ../example.git

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

0

一个解决方案是拥有一个专门的本地克隆,其中只有LocalTest

您可以从当前本地克隆中进行push --all,其中包含所有分支。

有时我们想将其他分支(特别是它们的新提交)合并到我们的本地分支,因此没有专用的本地克隆不是一个好主意

这是个好主意:您可以将第一个克隆作为第二个克隆(具有本地测试分支)的远程添加。
这意味着您可以随时从第一个克隆中获取任何分支,并将它们合并到LocalTest分支中。


或者,您可以尝试防止推送一个分支(使用pre-push钩子),但这将导致所有push --all失败,这是不切实际的。


有时候我们想要将其他分支(特别是它们的新提交)合并到我们的本地分支,因此为专门的本地克隆不是一个好主意。 - Seyed Ali Roshan
@SeyedAliRoshan 我已经编辑了我的答案以回应你的评论。 - VonC
我认为我们必须把这个作为最后的解决方案,因为有时我们想要从本地分支中挑选提交到其他分支,而按照你的想法,我们首先必须推送到我们的第一个克隆,然后再推送到服务器。 - Seyed Ali Roshan
@SeyedAliRoshan 不,你的第一个克隆也可以从第二个克隆中获取并挑选所需的内容。再次强调,这是一个简单实用的解决方案,可以让工作继续进行。 - VonC

0

你可以随时找到适合自己的方式。你可以在git bash中使用这个一行代码。

git push origin $(echo "$(git branch)" | sed 's/*//' | sed 's/<excluded_branch_name>//')

例如,当我想要推送除主分支以外的所有内容时,我使用这个命令。
git push origin $(echo "$(git branch)" | sed 's/*//' | sed 's/master//')

您可以添加尽可能多的管道sed命令应用程序,如需需要。 $(... | sed 's/<your_branch_name>// ...)

该命令的工作方式如下:

git branch列出所有本地分支,包括主分支和当前分支旁边的“*”字符。 echo再次输出输出。首先,sed删除*字符,然后我使用sed将其他分支名称替换为空字符串。该命令的输出将是除已删除分支之外的所有分支列表。这通过$(...)语法作为参数传递给git push origin


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接