今天在帮助一个有git问题的朋友时,我不得不介绍一个需要与master分支完全分开的分支。
该分支的内容确实与
已在master分支上开发,但稍后将被合并到master分支中。

我记得从底部阅读John Wiegley的《 Git》
如何
本质上来说,分支是遵循特定约定的提交的标签,以及如何将提交与文件树绑定,以及可选地
与父提交。我们使用git的管道来创建对
现有存储库的无父母提交:

,因此我们删除了索引中的所有文件...

$ git rm -rf .


...从压缩包中提取目录和文件,并将它们添加到
索引中...

$ git add .


...并创建了一个树对象...

$ git write-tree


git-write-tree告诉我们所创建的树对象的sha1sum。)

然后,我们承诺树,而未指定父提交...

git-commit-tree告诉我们创建的提交对象的sha1sum。)

.. ,并创建了一个指向我们新创建的分支的新分支。

$ echo "Imported project foo" | git commit-tree $TREE


最后,我们返回到master分支继续在那里工作。

$ git update-ref refs/heads/other-branch $COMMIT


这似乎已按计划进行。但这显然不是我要推荐给刚开始使用git的人使用的程序的类型,请放一点。有没有更简单的方法来创建与分支中到目前为止发生的一切完全不相关的
新分支?

#1 楼

有一个新功能(自V1.7.2起),使此任务比任何其他答案中的功能都高一点。

git checkout现在支持--orphan选项。在手册页中:

git checkout [-q] [-f] [-m] --orphan <new_branch> [<start_point>]


创建一个新的孤立分支,名为
,从
开始并切换到它。在新分支上进行的第一次提交
将没有父母,这将是新历史的根源
与所有其他分支断开连接,并且


这并不能完全满足要求者的要求,因为它从<start_point>填充了索引和工作树(因为毕竟这是一个checkout命令)。唯一需要执行的其他操作是从工作树和索引中删除所有不需要的项目。不幸的是,git reset --hard不起作用,但是可以代替使用git rm -rf .(我相信这等效于其他答案中给出的rm .git/index; git clean -fdx)。


总结:

git checkout --orphan newbranch
git rm -rf .
<do work>
git add your files
git commit -m 'Initial commit'


我未指定<start_point>,因为它默认为HEAD,无论如何我们都不在乎。这个序列与Artem的答案中的命令序列本质上是相同的,只是不求助于可怕的管道命令。

评论


您是否知道可以创建一个孤立分支,当您从另一个“树”中签出任何分支时,该分支保持可见状态?

– JJD
2011年6月7日在16:38

@JJD:我想您想要的是git merge。 (git checkout master && git merge --no-commit“ orphan-branch”)使用git-reset或使用索引可以使用一些类似的技巧。但这取决于您所需的工作流程。

– phord
2011-09-29 23:40



@Matthew这是git 1.7.2的变更日志。

– JJD
2011-09-30 10:05

@phord我或多或少地认为孤立对象包含与项目源代码分开的单元测试或文档之类的东西。

– JJD
2011年9月30日上午10:19

@JJD:除非我误解了我,否则我给的脚本应该给你想要的东西。当您说“保持可见”时,是否意味着即使您签出了另一个分支,文件仍将保留在工作目录中?在git merge上使用--no-commit将实现此目的。您可能需要跟进git reset origin / master,以便下次提交到您想要的位置,但是孤立分支中的文件将显示为“未跟踪的文件”,除非您也将它们包括在.gitignore文件中。

– phord
2011年10月3日在18:24

#2 楼

来自Git社区书:

git symbolic-ref HEAD refs/heads/newbranch 
rm .git/index 
git clean -fdx 
<do work> 
git add your files 
git commit -m 'Initial commit'


评论


对于现代版本的git,下一个答案更好。

–kikito
2012年4月3日21:50

@kikito:回复:“下一个答案更好”……在SO上的排序不稳定。您能否添加指向您认为更好的答案的链接。

– David J.
2014年1月8日在16:09

我指的是stackoverflow.com/a/4288660/312586。您是对的,我不应该说“下一个”。当我发表评论时,它的得分低于此答案。

–kikito
2014年1月8日在16:32

rm .git / index难看:-)

– Ciro Santilli郝海东冠状病六四事件法轮功
15年9月28日在8:03

这对于“我想提交到分支,如果以前不存在则创建它”的情况更好用

– max630
15年10月13日在6:51

#3 楼

尽管使用git symbolic-ref并除去索引的解决方案行之有效,但从概念上讲,创建新存储库可能更干净

$ cd /path/to/unrelated
$ git init
[edit and add files]
$ git add .
$ git commit -m "Initial commit of unrelated"
[master (root-commit) 2a665f6] Initial commit of unrelated
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 foo


然后从中获取

$ cd /path/to/repo
$ git fetch /path/to/unrelated master:unrelated-branch
warning: no common commits
remote: Counting objects: 3, done.
Unpacking objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
From /path/to/unrelated
 * [new branch]      master     -> unrelated-branch


现在您可以删除/ path / to / unrelated

评论


在我看来,一个干净的概念将涉及git branch或git checkout的选项。我很高兴git使这种事情成为可能,但是为什么不更容易呢?

– hillu
09年9月6日在12:05

因为它是,应该是一件罕见的事情。如果您有不相关的事物分支,它通常属于不相关的存储库,而不是将其填充到现有的存储库中(尽管有例外)。

–雅库布·纳朗斯基(JakubNarębski)
09年9月6日于13:05

+1。对于其他git新手,您显然可以通过git branch列出分支,并通过git checkout BRANCH_NAME在它们之间切换。

–akavel
2011年12月14日上午10:08

谢谢你,我不会自己考虑的。这特别有用,因为它可以维护其他存储库的历史记录(如果有的话)。

–BM5k
2012年7月8日在18:21

#4 楼

Github具有一项称为“项目页面”的功能,您可以在项目中创建一个特定的命名分支以提供将由Github服务的文件。他们的说明如下:

$ cd /path/to/fancypants
$ git symbolic-ref HEAD refs/heads/gh-pages
$ rm .git/index
$ git clean -fdx


从那里您有一个空的存储库,然后可以向其中添加新内容。

#5 楼

当前选择的答案是正确的,我将恰好添加......

这实际上正是github.com如何让用户通过名为gh-pages的孤立分支为其存储库创建Github Pages的方式。 />以下给出了漂亮的步骤并进行了解释:

https://help.github.com/articles/creating-project-pages-manually

基本上是git命令进行如下设置:



git checkout --orphan gh-pages(在您的存储库上创建一个名为gh-pages的无父母分支)

git rm -rf .(删除任何分支工作树中的文件)

rm '.gitignore'(甚至是gitignore)
现在添加网站内容(添加index.html等)并提交并推送。
利润。
>
请注意,您还可以在回购中指定一个/ docs文件夹作为Github用于构建网站的“项目站点”的来源。

希望这会有所帮助!

#6 楼

有时我只是想立即在项目中创建一个空分支,然后开始工作,我只是执行以下命令:

git checkout --orphan unrelated.branch.name
git rm --cached -r .
echo "init unrelated branch" > README.md
git add README.md
git commit -m "init unrelated branch"


#7 楼

在最新的Git版本(至少为2.27)中,可以使用switch命令完全实现此目的:
git switch --orphan <new-branch>

官方文档:https://www.git-scm.com/docs/git-switch

#8 楼

如果您已经提交了现有内容,则现在(Git 2.18 Q2 2018)可以将其提取到其自己的新的孤立分支中,因为“ git rebase -i --root”的实现已更新为更多使用定序器机制。
>
该定序器现在允许将提交图的整个拓扑移植到其他位置。

请参见commit 8fa6eea,commit 9c85a1c,commit ebddf39,commit 21d0764,commit d87d48b,commit ba97aea(03由Johannes Schindelin(dscho)(2018年5月30日由Junio C Hamano合并-gitster-在commit c5aa4bc中合并,2018年5月30日)
/>
在新设计的--rebase-merges模式的上下文中,
专用于允许自由更改现有分支拓扑
,用户可能希望将提交提取到完全新鲜的
/>以新创建的根落实开始的分支。

现在可以通过在前面插入命令reset [new root]来实现
pick想要成为根提交的提交。示例:


reset [new root]
pick 012345 a commit that is about to become a root commit
pick 234567 this commit will have the previous one as parent



这与reset命令的其他用法不冲突,因为
[new root]不是(一部分)有效的引用名称:引用名称中的左括号
和空格都是非法的。


#9 楼

在http://wingolog.org/archives/2008/10/14/merging-in-unrelated-git-branches中找到了此脚本,它的工作原理非常好!

评论


我相信使用git fetch $ REMOTE $ REMOTE_BRANCH:$ LOCAL_BRANCH可以达到相同的效果。我想念什么吗?

– hillu
2010年8月25日下午6:41

#10 楼

创建一个单独的存储库对我来说效果很好。不必担心

在其他地方创建新的空仓库。
将master分支重命名为master以外的其他名称,即gh-pages

开始孤立工作。
将工作提交到新存储库中的唯一分支。
将新分支推到包含原始主分支的同一远程仓库中。

以下方法中提到了此方法:

https://gitlab.com/tortoisegit/tortoisegit/-/issues/1090#note_77403778
https://gist.github.com/chrisjacob / 1086274 / 382ef1ccc22b57b9b1f0e3a362b39e806b9ba04c