为什么我们永远不要对已推送的提交使用rebase [英] Why should we never use rebase with commits that have been pushed

查看:178
本文介绍了为什么我们永远不要对已推送的提交使用rebase的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍然可以通过VSTS和Git弄湿我的脚.我了解master分支中的更改需要进入feature分支的情况,但是这些提醒"或提示对我而言仍然没有意义. 以下声明是什么意思? https://docs.microsoft.com/zh-cn/vsts/git/tutorial/rebase?tabs = visual-studio

Im still getting my feet wet with VSTS and Git. I understand the scenario where changes in the master branch need to get into the feature branch, but these "reminders" or tips dont make sense to me yet. What is meant by the statement below? https://docs.microsoft.com/en-us/vsts/git/tutorial/rebase?tabs=visual-studio

[quote]

从不对已推送并与其他人共享的提交进行重新基准化.这 此规则的唯一例外是,当您确定自己身上没有人时 团队正在使用您提交的提交或分支.

Never rebase commits that have been pushed and shared with others. The only exception to this rule is when you are certain no one on your team is using the commits or the branch you pushed.

经过进一步的阅读,并且来自SVN,我认为我明白了为什么做出上述声明:

After reading a bit further, and coming from SVN, I think I see why the above statement was made:

切勿强行推动其他人正在处理的分支.只能用力推 您独自使用的分支机构.

Never force push a branch that others are working on. Only force push branches that you alone work with.

这与SVN的情况相似":(1)您有一个本地分支,其他人正在处理它,然后(2)直接在主干中进行错误修复,然后(3)将这些更改合并到一起到您的本地分支机构,然后(4)在本地分支机构中提交更新,从而迫使在该本地分支机构上工作的其他任何人都获取更新,并可能发生合并冲突

This would be "similar" to a situation with SVN where:(1) you have a local branch that others are working on and then (2) make a bug fix directly in trunk, then (3) merge those changes down to your local branch and (4) commit the updates in the local branch, thus forcing anyone else working on that local branch to get the update and potentially have a merge conflict

推荐答案

Ashish Mathew的答案,该链接并带有引号Pro Git书中的内容是正确的,但是您可能需要更多的背景才能真正理解.但是,我首先要说从不"这个词太强了.可以在一种情况下对已发布的提交进行基准重设:每个必须处理所产生的问题的人都已经事先同意处理所产生的问题.

Ashish Mathew's answer, which links to and quotes from the Pro Git book, is correct, but you may need a lot more background to really understand it. But I'd like to start out by saying that the word "never" is too strong. It's OK to rebase published commits under one condition: that everyone who will have to deal with the problems created, has agreed in advance to deal with the problems created.

但是,这样做会带来什么问题呢?答案就是这样:变基通过复制提交起作用.

But what, then, are the problems created by doing this? The answer is in that quote: rebase works by copying commits.

对于每个提交,Git都有一个真实的真实名称",即该提交的哈希ID.真实的名称(哈希ID)是Git如何查找底层数据,以及当您将两个Git彼此连接时如何传输数据. (实际上,尽管您自己将主要处理提交,但是这些哈希ID用于Git的所有四种内部对象类型.)

Git has one real "true name" for each commit, which is that commit's hash ID. That true name—the hash ID—is how Git finds the underlying data, and how, when you connect two Gits to each other, they transfer the data. (In fact, these hash IDs are used for all four of Git's internal object types, though you yourself will mostly deal with commits.)

任何给定提交的哈希ID都是唯一的,并且显然完全是随机的-但实际上,它是完全确定性的,是根据提交内部的数据计算得出的. (这是该数据的密码散列.)因此,您的Git可以连接到整个宇宙中任何地方的任何其他Git,并且如果您的Git在另一个Git上发出像8279ed033f703d4115bee620dccd32a9ec94d9aa这样的原始哈希ID,则两个Git可以立即判断是否他们都有提交,也没有.如果两个Git都有提交,则无事可做.但是如果只有一个 Git拥有提交,则另一个Git会要求获取副本.

The hash ID for any given commit is unique, and apparently totally random—but in fact, it's completely deterministic, having been computed from the data inside the commit. (It's a cryptograph hash of that data.) Hence your Git can connect to any other Git anywhere in the entire universe, and if your Git waves a raw hash ID like 8279ed033f703d4115bee620dccd32a9ec94d9aa at the other Git, the two Gits can immediately tell whether they both have that commit, or not. If both Gits have the commit, there's nothing to do; but if only one Git has the commit, the other Git will ask to get a copy.

(转移始终是一种方式:git fetch让您的Git调用另一个Git并从其中下载项目 ,而git push让您的Git调用另一个Git并发送项目 .根本没有理由不能同时做这两个事情,但是所有命令都是在考虑到单向传输的情况下编写的.)

(The transfer is always one way: git fetch has your Git call up another Git and download items from them, while git push has your Git call up another Git and send items to them. There's no fundamental reason you couldn't do both at the same time, but the commands are all written with unidirectional transfer in mind.)

这种执行非常简单的有/无"交换的能力是Git如何仅快速转移所需对象的方法:即使您拥有相当庞大的存储库(例如Linux内核的存储库), ,今天,提交超过700k,存储库数据库约为2.4 GB,git fetch命令很快:

This ability to do a very simple have/want exchange is how Git can rapidly transfer only the necessary objects: even if you have a fairly fat repository such as that for the Linux kernel—weighing in, today, at over 700k commits and about 2.4 GB of repository database—the git fetch command is quick:

$ time git fetch

real    0m0.457s
user    0m0.228s
sys 0m0.087s
$ 

(今天早上我运行了一个更早的git fetch,这要慢很多,因为自去年下半年以来我一直没有更新此内核副本.这花费了大约3秒的CPU时间和大约10.5秒的实时时间. ,带来11853个对象.)

(I ran an earlier git fetch this morning, which was a lot slower as I had not updated this copy of the kernel since late last year. That one took about 3 seconds of CPU time and about 10.5 seconds of real time, to bring over 11853 objects.)

无论如何,这一切的简短版本是Git倾向于像源代码控制系统的Borg:无论您拥有什么 ,当我将Git连接到您的Git时,我都会添加您拥有的所有我不拥有的东西 我的存储库.我保持以前的一切!

Anyway, the short version of all of this is that Git tends to be like the Borg of source control systems: whatever you have, when I connect my Git to yours, I add everything you have that I don't to my repository. I keep everything I had before!

因此,如果您对已发布的提交使用git rebase-我现在拥有的提交,因为我早些时候从您那里得到的-您将像引用中一样将您现有的提交中的一些复制到您认为是的新提交中新的和改进的.然后,您将切换到新的提交,放弃已复制的令人讨厌的旧提交.当我将 my Git连接到您的 Git时,我将得到 新旧版本.

So, if you use git rebase on published commits—commits that I have now, because I got them from you earlier—you will, as in the quote, copy some of your existing commits to new commits that you think are new-and-improved. You will then switch to the new commits, abandoning the yucky old ones that you've copied. When I connect my Git to your Git, I'll end up with both the old and the new.

这看起来还不错,但是问题是我的Git将存储库中的 all 提交视为珍贵,所以现在我既有旧的又有新的.我没有放弃旧的.如果我已经建立了使用您的旧提交的新提交,那么现在我就必须以某种方式将我已经创建的工作与您复制的工作区分开来.

That doesn't seem so bad—but the problem is that my Git treats all commits in my repository as precious, so now I have both the old ones and the new ones. I haven't abandoned the old ones. If I've built new commits that use your old ones, I now have to somehow separate the work I've built from the work you've copied.

有些工具可以帮助您解决这一问题,尤其是git rebase --fork-point,但是它们并不是有史以来最美妙的事情.在我收到您的重新提交的提交后,它们需要相当快地使用,以使其有效.因此,我需要(最好是提前)知道您将对发布的工作进行重新定位(您已经拥有的提交),以便我准备做必须做的任何工作来为重新设置基础我的工作,用于您的基础工作.

There are tools that can help with this—particularly git rebase --fork-point—but they're not the most wonderful things ever. They need to be used fairly quickly, right after I pick up your rebased commits, to be effective. So I will need to know, preferably in advance, that you will be rebasing your published work—your commits that I already have—so that I am prepared to do anything I must do to rebase my work on your rebased work.

如果我们都已经事先同意这一点,并且我们都知道该怎么做,那么 可以很好地为已发布的提交重新设置基础.如果不是,那么,您可能正在为别人做很多工作,也许是许多别人",他们可能不知道如何使用(不是很好)的工具来处理某件事情. 上游变基".

If we have all agreed to this in advance, and we all know how to do it, then it is OK to rebase your published commits. If not, well, you might be making a lot of work for someone else, perhaps many "someone else"s, who may not know how to use the (not so great) tools for dealing with an "upstream rebase".

这篇关于为什么我们永远不要对已推送的提交使用rebase的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆