今天在帮助朋友解决 git 问题时,我不得不介绍一个需要与 master
分支完全分开的分支。这个分支的内容确实与在 master
分支上开发的内容不同,但它们将在以后合并到 master
分支中。
我记得阅读 John Wiegley 的Git from the bottom up,分支本质上是遵循特定约定的提交的标签,以及提交如何绑定到文件树以及可选地绑定到父提交。我们使用 git 的管道创建了对现有存储库的无父提交:
所以我们摆脱了索引中的所有文件......
$ git rm -rf .
...从压缩包中提取目录和文件,将它们添加到索引中...
$ git add .
...并创建了一个树对象...
$ git write-tree
(git-write-tree
告诉我们创建的树对象的 sha1sum。)
然后,我们提交了树,没有指定父提交......
$ echo "Imported project foo" | git commit-tree $TREE
(git-commit-tree
告诉我们创建的提交对象的 sha1sum。)
...并创建了一个指向我们新创建的提交的新分支。
$ git update-ref refs/heads/other-branch $COMMIT
最后,我们返回 master
分支继续在那里工作。
$ git checkout -f master
这似乎按计划进行。但这显然不是我向刚开始使用 git 的人推荐的那种程序,委婉地说。有没有一种更简单的方法来创建一个与存储库中迄今为止发生的一切完全无关的新分支?
有一个新功能(自 V1.7.2 起)使此任务比其他任何答案中的任务更高级一些。
git checkout
现在支持 --orphan
选项。从 man page:
git checkout [-q] [-f] [-m] --orphan <new_branch> [<start_point>]
创建一个名为
这并没有完全满足询问者的要求,因为它从 <start_point>
填充索引和工作树(因为这毕竟是一个结帐命令)。唯一需要的其他操作是从工作树和索引中删除任何不需要的项目。不幸的是,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's answer 中的命令序列基本相同,只是没有使用可怕的管道命令。
git symbolic-ref HEAD refs/heads/newbranch
rm .git/index
git clean -fdx
<do work>
git add your files
git commit -m 'Initial commit'
rm .git/index
很丑 :-)
尽管使用 git symbolic-ref
和删除索引的解决方案有效,但创建 new 存储库可能概念上更干净
$ 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 让这种事情成为可能,但为什么不能更容易呢?
git branch
列出分支并通过 git checkout BRANCH_NAME
在它们之间切换。
当前选择的答案是正确的,我只是巧合地补充一下......
这实际上正是 github.com 允许用户通过一个名为 gh-pages
的孤立分支为他们的存储库创建 Github 页面的方式。这里给出并解释了漂亮的步骤:
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 等)并提交和推送。利润。
请注意,您还可以在您的存储库中 designate a /docs folder 作为 Github 用于构建网站的“项目站点”的来源。
希望这可以帮助!
在最近的 Git 版本中,至少是 2.27,这可以使用 switch
命令干净地实现:
git switch --orphan <new-branch>
官方文档:https://www.git-scm.com/docs/git-switch
Github 有一个名为 Project Pages 的功能,您可以在其中在项目中创建一个特定的命名分支,以提供将由 Github 提供的文件。他们的指令如下:
$ cd /path/to/fancypants
$ git symbolic-ref HEAD refs/heads/gh-pages
$ rm .git/index
$ git clean -fdx
从那里你有一个空的存储库,然后你可以添加你的新内容。
有时我只想立即在项目中创建空分支然后开始工作,我将执行以下命令:
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"
如果您的现有内容已经提交,您现在(Git 2.18 Q2 2018)可以将其提取到自己的新孤立分支中,因为“git rebase -i --root
”的实现已更新为更多地使用序列器机制。
该定序器就是现在的allowing to transplant the whole topology of commit graph elsewhere。
请参阅 Johannes Schindelin (dscho
) 的 commit 8fa6eea、commit 9c85a1c、commit ebddf39、commit 21d0764、commit d87d48b、commit ba97aea(2018 年 5 月 3 日)。
(由 Junio C Hamano -- gitster
-- 在 commit c5aa4bc 中合并,2018 年 5 月 30 日)
sequencer:允许引入新的根提交新创建的根提交。现在可以通过在选择想要成为根提交的提交之前插入命令 reset [new root] 来实现。例子:
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] 不是(部分)有效的引用名称:在引用名称中,左括号和空格都是非法的。
创建一个单独的存储库对我来说效果很好。不必担心
在其他地方创建一个新的空仓库。将 master 分支重命名为 master 以外的任何东西,即 gh-pages 开始你的孤儿工作。将您的工作提交到新存储库中的唯一分支。将新分支推送到包含原始主分支的同一个远程仓库。
此方法在以下内容中有所提及:
https://gitlab.com/tortoisegit/tortoisegit/-/issues/1090#note_77403778
https://gist.github.com/chrisjacob/1086274/382ef1ccc22b57b9b1f0e3a362b39e806b9ba04c
在 http://wingolog.org/archives/2008/10/14/merging-in-unrelated-git-branches 找到了这个脚本,它工作得很好!
#!/bin/bash
set -e
if test -z "$2" -o -n "$3"; then
echo "usage: $0 REPO BRANCHNAME" >&2
exit 1
fi
repo=$1
branch=$2
git fetch "$repo" "$branch"
head=$(git rev-parse HEAD)
fetched=$(git rev-parse FETCH_HEAD)
headref=$(git rev-parse --symbolic-full-name HEAD)
git checkout $fetched .
tree=$(git write-tree)
newhead=$(echo "merged in branch '$branch' from $repo" | git commit-tree $tree -p $head -p $fetched)
git update-ref $headref $newhead $head
git reset --hard $headref
git fetch $REMOTE $REMOTE_BRANCH:$LOCAL_BRANCH
也可以达到同样的效果。我错过了什么吗?
不定期副业成功案例分享
( git checkout master && git merge --no-commit "orphan-branch" )
使用 git-reset 或使用索引可以使用一些类似的技巧。但这取决于您所需的工作流程。git merge
上使用--no-commit
将实现此目的。您可能需要使用git reset origin/master
跟进,以便您的下一次提交转到您想要的位置,但是您的孤立分支中的文件将显示为“未跟踪文件”,除非您还将它们包含在您的 .gitignore 文件中。