git 创建一个空分支?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37792828/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create an empty branch?
提问by panthro
I have a git repo containing a project. I now am going to do a massive overhaul of the project.
我有一个包含项目的 git repo。我现在要对该项目进行大规模的检修。
How can I create a new branch for this overhaul that is blank? Then when complete. How can I switch this branch to master?
我如何为这个空白的大修创建一个新分支?然后当完成。如何将此分支切换到主分支?
回答by Gregg
use the checkout --orphan command
使用 checkout --orphan 命令
git checkout --orphan MyNewBranch
git reset -- *
git ls-files
see also this link https://git-scm.com/book/en/v2/Git-Tools-Replace
回答by torek
Gregg's answerand the linked possible-duplicateboth suggest using git checkout --orphan
(the linked question dates back to when --orphan
was relatively new).
格雷格的回答和链接的可能重复都建议使用git checkout --orphan
(链接的问题可以追溯到--orphan
相对较新的时候)。
In a comment, exxeccsuggested creating a branch from some existing commit, deleting all the contents (e.g., git rm -r .
), and going on from there.
在评论中,exexecc建议从一些现有提交创建一个分支,删除所有内容(例如,git rm -r .
),然后从那里继续。
Both methods are valid and workable. So which one shouldyou use? The answer to that depends not on what you want to do right now, but rather what you want to do and see later. The key is, as usual, Git's commit graph. (To spoil the effect somewhat, but be more useful as an answer, I'd say "go with orphan" since you may need to defer this decision, and "orphan" gives you more options later. Read on to see what I am talking about.)
这两种方法都是有效且可行的。那么你应该使用哪一个?这个问题的答案不取决于您现在想做什么,而是取决于您想做什么并稍后查看。像往常一样,关键是 Git 的提交图。(为了稍微破坏效果,但作为答案更有用,我会说“选择孤儿”,因为您可能需要推迟此决定,而“孤儿”稍后会为您提供更多选择。继续阅读以了解我是什么谈论。)
An orphan branch is a new root commit
孤儿分支是一个新的根提交
When you view Git's commit graph,git log
starts with the currentcommit by default, or the tip-most commit of any named branch. (Then it goes on to ruin this sensible behavior by sorting commits by date, but that's a different problem, and if the dates themselves are sensible, this "ruining" has basically no effect and it's actually all still sensible.) Hence we start with the current, or most recent on some branch(es), commits, and work backwards in time to a root commit.
当您查看 Git 的提交图时,默认情况下git log
从当前提交或任何命名分支的最尖端提交开始。(然后它继续通过按日期对提交进行排序来破坏这种明智的行为,但这是一个不同的问题,如果日期本身是合理的,那么这种“破坏”基本上没有影响,实际上仍然是明智的。)因此我们从某些分支上的当前或最近一次提交,并及时向后工作到根提交。
A root commit is simply a commit with no parents. It is a starting point in time. It has descendents—commits that come after it, that are derived fromit—but it has no ancestors. It was created from scratch; it has no preceding history.
根提交只是一个没有父母的提交。这是时间的起点。它有后代——在它之后的提交,从它派生——但它没有祖先。它是从头开始创建的;它没有以前的历史。
This may be true of a rewrite (massive overhaul, in the original problem description).
这可能适用于重写(大规模检修,在原始问题描述中)。
Or, it may not. Sure, it's a rewrite—but there wassomething before. There wereprevious commits. Maybe you should include them.
或者,它可能不会。当然,这是一个重写,但为某件事之前。还有人先前提交。也许你应该包括他们。
Any other commit has history
任何其他提交都有历史记录
If you make, as a non-root commit, a commit that empties out the previous version (and has nothing at all, or a simple skeleton, or perhaps even a new, rewritten implementation), you will, in the future, be able to scan back in time, to a point before this fresh start. That will, in fact, be more accurate. Moreover, it will allow you to merge this into other branches, with Git showing you conflicts for files modified or created since the "fresh start" point.
如果您以非root 用户的身份进行提交,该提交会清空以前的版本(并且根本没有任何内容,或者一个简单的框架,甚至可能是一个新的、重写的实现),那么将来您将能够及时扫描,回到这个新开始之前的某个点。事实上,这会更准确。此外,它还允许您将其合并到其他分支中,Git 会显示自“新开始”点以来修改或创建的文件的冲突。
Suppose, for instance, that the project in question has one major branch, and this is the one you intend to rewrite, but it also has one side branch for some experimentation. If that experimentation proves successful, it might be nice, some time later, to bring some or all of that work back into the rewrite as well. If your rewrite starts by emptying things out and then replacing, a simple git merge
of the experimental branch will give you conflicts of the form "modified by them, deleted by us" for each file with changes in it.
例如,假设所讨论的项目有一个主要分支,这是您打算重写的分支,但它也有一个侧分支用于一些实验。如果该实验证明是成功的,那么一段时间后,将部分或全部工作也带回重写中可能会很好。如果您的重写从清空内容然后替换开始,一个简单git merge
的实验分支将为您提供“由他们修改,由我们删除”形式的冲突,用于每个文件中的更改。
In any case, git log
will be able to show you the true history: that, at some point, you did this massive rewrite. That true history may have some value. (Though, as is true of all code history, sometimes the value may be more negative than positive. :-) )
无论如何,git log
将能够向您展示真实的历史:在某些时候,您进行了大规模的重写。那个真实的历史可能有一些价值。(虽然,正如所有代码历史一样,有时该值可能比正值更负。:-))
Getting the best of both worlds
两全其美
Despite the possible advantages I suggest above for notusing an orphan branch, I recommend the orphan branch method. The reason is that this lets you defer the decision. Here is the basic idea.
尽管我在上面建议不使用孤儿分支有可能的优势,但我还是推荐孤儿分支方法。原因是这可以让您推迟决定。这是基本思想。
In the new orphan branch, which has a completely independent history—incidentally, you can make this in a completely independent repositoryas well, obviating the need for git checkout --orphan
—you can develop the overhauled, rewritten version from scratch. Then, at some point, you deem it ready for replacing the old version. At this point, you can merge the two branches (or the two repositories) even though they have no common base. You simply need to make a new commit with two parents: the first parent is the current tip of the rewritten branch, and the second parent is the original (un-rewritten) version.
在新的孤儿分支中,它具有完全独立的历史——顺便说一句,您也可以在一个完全独立的存储库中创建它,从而避免需要git checkout --orphan
——您可以从头开始开发经过大修、重写的版本。然后,在某个时候,您认为它已准备好替换旧版本。此时,您可以合并两个分支(或两个存储库),即使它们没有共同的基础。您只需要使用两个父项进行新提交:第一个父项是重写分支的当前提示,第二个父项是原始(未重写)版本。
This second parent commit can either be the original version as it stands now, at the point the two are being "merged", or a commit as of the time the rewrite project started.
第二个父提交可以是现在的原始版本,在两者被“合并”时,或者在重写项目开始时提交。
I put "merged" in quotes here only because the treefor the merge commit will simply be the rewrite version. We will ignore the old version's sourceentirely. The point of the new merge commit is simply to join up the histories of the two lines of development, and to imply (by making the branch name, master
for instance, point to the new merge commit) that the new version is now in charge, as it were.
我在这里将“合并”放在引号中只是因为合并提交的树将只是重写版本。我们将完全忽略旧版本的来源。新的合并提交的目的只是将两条开发线的历史连接起来,并暗示(通过使分支名称,master
例如,指向新的合并提交)现在由新版本负责,原来如此。
(This kind of merge is made by the -s ours
strategy, although there is a relatively easy way to make it manually as well. If you want to make this merge directly on master
you will need the equivalent of -s theirs
instead, which requires the manual method. To do it with -s ours
, make the merge on the orphan branch, then shuffle branch names around. If you have put the new orphan-branch version in an orphan—separate—repository, simply add the new repository as an extra remote, fetch the new version, and then make the merge commit as usual.)
(这种merge是由-s ours
策略做的,虽然也有比较简单的手工做的方式。如果你想直接在上面做这个merge,master
你需要等价的-s theirs
替代,这需要手动的方法。要做到它与-s ours
,在孤立分支上进行合并,然后将分支名称混在一起。如果您将新的孤立分支版本放在孤立的独立存储库中,只需将新存储库添加为额外的远程存储库,获取新版本,然后像往常一样进行合并提交。)