全局重置git分支(适用于所有用户)
在我们当前的工作流程中,我们有两个主要的git分支:全局重置git分支(适用于所有用户),git,github,git-branch,remote-branch,Git,Github,Git Branch,Remote Branch,在我们当前的工作流程中,我们有两个主要的git分支: master-稳定释放分支 测试-每个人都在测试他们的代码吗 现在,每个开发人员都会为他们开发的每个功能创建新的分支。完成后,他们将其合并到测试中,当我们的QA说可以开始时,他们将其分支合并到主,并部署到生产中 随着时间的推移,我们的测试分支会被从未投入生产的提交所污染。被抛弃的特性,被重写而不是被修复的东西,以及其他东西 为了使master和testing保持某种一致的状态,我们希望不时“重置”testing。现在,我们通过完全删除测试并将
master
-稳定释放分支
测试
-每个人都在测试他们的代码吗
现在,每个开发人员都会为他们开发的每个功能创建新的分支。完成后,他们将其合并到测试中
,当我们的QA说可以开始时,他们将其分支合并到主
,并部署到生产中
随着时间的推移,我们的测试分支会被从未投入生产的提交所污染。被抛弃的特性,被重写而不是被修复的东西,以及其他东西
为了使master
和testing
保持某种一致的状态,我们希望不时“重置”testing
。现在,我们通过完全删除测试
并将其从master
重新分支来实现这一点
这里的大问题是,我们需要确保每个开发人员也删除其本地测试分支,并签出它的新副本。
如果一个开发人员忘记了这样做,并再次推动测试,那么我们试图摆脱的所有肮脏的提交都会回来
是否有任何方法可以将服务器上的分支以分发给所有用户的方式重置
一个可接受的解决方案是将测试
分支置于一种状态,在这种状态下,没有人可以在不进行本地重置的情况下再推动它。但是我想不出一个方法来做这件事
在主控
和测试
之间创建差异并恢复提交不是一个选项,因为这会防止每个提交再次进入测试
理想情况下,我会有一个定期执行重置的脚本,在每个用户本地环境上不需要交互(除了git pull
)
随着时间的推移,我们的测试分支会被从未投入生产的承诺所污染。被抛弃的特性,被重写而不是被修复的东西,以及其他东西
这怎么可能?显然,如果某个特性被放弃,那么您也应该将其从您的测试分支中删除,因为它似乎是您的看门人。基本上,如果你说你的测试分支被时间污染了,那么它就违背了测试分支的全部目的,因为现在你正在测试一些不代表你想要推送到生产环境中的代码的东西
如果某件事没有成功,那么开发人员应该恢复他的更改,并将提交推送到测试分支,在那里更改也会恢复
在您的场景中,您应该从测试合并到生产,要么全部合并,要么不合并
随着时间的推移,我们的测试分支会被从未投入生产的承诺所污染。被抛弃的特性,被重写而不是被修复的东西,以及其他东西
这怎么可能?显然,如果某个特性被放弃,那么您也应该将其从您的测试分支中删除,因为它似乎是您的看门人。基本上,如果你说你的测试分支被时间污染了,那么它就违背了测试分支的全部目的,因为现在你正在测试一些不代表你想要推送到生产环境中的代码的东西
如果某件事没有成功,那么开发人员应该恢复他的更改,并将提交推送到测试分支,在那里更改也会恢复
在您的场景中,您应该从测试合并到生产,要么全部合并,要么不合并。简短的回答是“不,您不能这样做”
请记住,每个克隆都是一个完整的独立实体1,除了它的来源
和一些初始分支状态(取决于克隆选项)之外,它与从中克隆的源存储库几乎没有什么不同。2一旦有人拿起名为测试
的分支并将其命名为来源/测试
:
- 他们有你给他们的承诺;及
- 他们有一个名为
origin/testing
的引用(“远程跟踪分支”),当他们连接到远程origin
时,他们的git将自动更新,甚至在接到指示时删除
到目前为止还不错,这个“自动修剪”动作听起来很棒。如果您能说服他们将remote.origin.prune
设置为true
:
$ git config remote.origin.prune true
然后,一旦删除名为testing
的分支,它们的origin/testing
将在下一次git fetch origin
时自动消失
当他们创建名为testing
的分支时,问题就出现了。他们的git不会删除此分支,除非他们要求删除。就git而言,它们的私有分支就是它们的私有分支。你无法说服他们的git删除他们的私有测试
,正如你无法说服他们的git删除他们的私有实验-22
。他们创造了它;这是他们的仓库;他们控制着它
(请注意,他们还可以控制自动修剪,因为他们可以git-config
远程.origin.prune
设置,或者在任何时候设置为false
。该设置是为了方便他们,而不是为了方便你。它与remote.origin.fetch
设置一起使用,他们可以更改这些设置以使自己的e> git fetch
更改了它的功能;它的初始默认设置是运行git clone时创建的
您可以继续使用此模型,前提是您让所有开发人员自行控制删除或清理此分支标签。但这不是解决方法。相反,您应该使用另一种模型:为您正在进行的新(和不同)开发线的开发人员创建新的、不同的分支标签
例如,您可能有dev-feature-X
作为临时分支,您的
git checkout master
git checkout -b new_testing
git merge -s ours testing # this creates a merge commit, but
# its tree is that of the current work-tree
# which in our case is the same as master
git checkout testing
git merge ours_testing
git branch -d new_testing
* (testing) merge
|\
| * (master) last commit on master
* | last commit on testing
| |
#!/bin/sh
# Do not permit merges from unwanted history
#set -x
err=0
while read old new ref; do # for each pushed ref
[[ ${old%[^0]*} = $old ]] && continue # new branches aren't checked.
nomerge=$(git for-each-ref refs/do-not-merge --format='%(objectname)^!')
if [[ $( git rev-list --count --ancestry-path --boundary $old..$new $nomerge
) != $( git rev-list --count --ancestry-path --boundary $old..$new ) ]]; then
echo "$ref doesn't allow merges from outdated history"
err=1
fi
done
exit $err
# why it works:
# if adding nomerge commits' parents as ancestors has any effect, then the
# nomerge commits are reachable without going through $old, i.e. they're
# in some merged history. So check whether adding the abandoned commits as
# explicit ancestors to the push makes them show up, and refuse it if so.
git config alias.no-further-merges-from \
'!f() { git update-ref "refs/do-not-merge/$1-@`date +%Y-%m-%dT%H%M%S`" "$1"; }; f'
git no-further-merges-from testing
git checkout -B testing master
git no-further-merges-from 'testing@{last october 31}'