如何确保队友不会通过重写历史记录来搞砸git

如何确保队友不会通过重写历史记录来搞砸git

本文介绍了如何确保队友不会通过重写历史记录来搞砸git repo?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常的建议似乎不是在提交完成后重新设置,重置或执行其他历史重写操作。

建议执行所有操作在你自己的机器上进行这些切割和切割,但是一旦你推动它,就让它变成现实。



这是有道理的。



但是这个政策如何执行?对于多个开发人员,我们如何确保没有人这样做?



似乎应该有一种方式让git以编程方式知道它是否重写了历史记录已经推过。



如果没有内置,看起来应该有一种方法来编写脚本来检查它。



理想情况下,人们不会被允许做任何重写历史的事情。它会返回一个错误。



如果这是不可能的,那么至少人们会被阻止推动任何重写历史的事情。



这是可行的吗?

解决方案

一个可能的解决方案是:





 #!/ usr / bin / env ruby​​ 
$ b base_branch = ARGV [0]
如果ARGV [1]
topic_branch = ARGV [1]
else
topic_branch = HEAD
结束

target_shas =`git rev-list#{base_branch} ..#{topic_branch}`.split(\\\

remote_refs =`git branch -r`.split \\\
)。map {| r | r.strip}

target_shas.each do | sha |
remote_refs.each do | remote_ref |
shas_pushed =`git rev-list ^#{sha} ^ @ refs / remotes /#{remote_ref}`
如果shas_pushed.split(\\\
)。include?(sha)
puts[POLICY] Commit#{sha}已经被推送到#{remote_ref}
exit 1
end
end
end

但这仍然是一个客户端解决方案,可以规避,并且必须通过回购部署/激活回收。



在服务器端,这并不容易实现(在配置 receive.denyNonFastForwards 之外)。



但是,既然git 1.8.5,而不是简单的 git push --force (rebase之后),你现在可以做一个

至少,您知道您的强制推送是否会导致问题。



但这仍然是用户必须考虑的事情。


Common advice seems to be not to rebase, reset, or perform other "history-rewriting" operations after commits have been pushed.

The recommendation is to perform all these kinds of slicing and dicing on your own machine, but then once you've pushed it, to just let it be.

This makes sense.

But how can this policy be enforced? With multiple developers, how can we make sure that nobody does this?

It seems there should be a way for git to programmatically know if it is rewriting history on something that is already pushed.

If this isn't built in, it seems there should be a way to write a script that would check for this.

Ideally, people would not be permitted to do anything that rewrites history on something that was committed. It would return an error.

If that isn't possible, then at least people would be blocked from pushing anything that rewrites history.

Is this doable?

解决方案

One possible solution is a client side hook (pre-rebase):

#!/usr/bin/env ruby

base_branch = ARGV[0]
if ARGV[1]
  topic_branch = ARGV[1]
else
  topic_branch = "HEAD"
end

target_shas = `git rev-list #{base_branch}..#{topic_branch}`.split("\n")
remote_refs = `git branch -r`.split("\n").map { |r| r.strip }

target_shas.each do |sha|
  remote_refs.each do |remote_ref|
    shas_pushed = `git rev-list ^#{sha}^@ refs/remotes/#{remote_ref}`
    if shas_pushed.split("\n").include?(sha)
      puts "[POLICY] Commit #{sha} has already been pushed to #{remote_ref}"
      exit 1
    end
  end
end

But that remains a client-side solution, which can be circumvented, and has to be deployed/activated repos by repos.

On the server side, this is not easy to enforce (beside the config receive.denyNonFastForwards).

But since git 1.8.5, instead of a simple git push --force (after rebase), you now can do a git push --force-with-lease.

At least, you know if your force push will cause problem or not.

But that remains something a user has to think to do.

这篇关于如何确保队友不会通过重写历史记录来搞砸git repo?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 17:10