如何创建一个新的(并且是空的!)“ root”分支?

我想在这个 git 存储库中定义一个新的“ root”分支。我所说的“ root”分支是指完全独立于存储库 1中的所有其他分支的分支。

不幸的是,即使是在回购提交树的最底层的提交(我们称之为 A)也包含大量文件(这是在一个已经相当成熟的项目上初始化的存储库)。

这意味着,即使我将 A作为新分支的 <start-point>,这个新分支也不会从头开始,而是包含在 A中提交的所有文件。

有没有什么方法可以在这个存储库中创建一个完全空的分支,使 <start-point>尽可能接近 A


1 BTW,这是 没有等价于创建一个新的回购协议。由于许多原因,单独的回购不太方便。


编辑 : 好的,这是我根据 [ em > vcsjones ]的回答所做的:

# save rev of the current earliest commit
OLDBASE=$(git rev-list --max-parents=0 HEAD)


# create a new orphan branch and switch to it
git checkout --orphan newbranch
# make sure it's empty
git rm -rf .


# create a new empty commit in the new branch, and
# save its rev in NEWBASE
git commit --allow-empty -m 'base commit (empty)'
NEWBASE=$(git rev-list HEAD)


# specify $NEWBASE as the new parent for $OLDBASE, and
# run filter-branch on the original branch
echo "$OLDBASE $NEWBASE" > .git/info/grafts
git checkout master
git filter-branch


# NOTE: this assumes that the original repo had only one
# branch; if not, a git-filter-branch -f <branch> command
# need to be run for each additional branch.


rm .git/info/grafts

虽然这个过程有点复杂,但是最终的结果是 空的基提交,它可以作为任何新的“从头开始的分支”的 <start-point>; 接下来需要做的就是

git checkout -b cleanslate $(git rev-list --max-parents=0 HEAD)

在未来,我将一直创建这样的新存储库:

git init
git commit --allow-empty -m 'base commit (empty)'

... 因此第一次提交是 空荡荡的,并且始终可以启动一个新的独立分支。(我知道,这将是一个非常罕见的设施,但它是相当容易使其随时可用。)

44104 次浏览

创建分支时使用 --orphan:

git checkout --orphan YourBranchName

这将创建一个没有提交的新分支,但是所有的文件都将被暂存。这时候你就可以把它们移除了。
(“ delete them”: git reset --hard将清空索引,留下一个空的工作树)

查看 手册以了解更多关于孤儿的信息。

添加到已接受的答案-最佳实践恢复到清洁状态是创建 最初的空提交,这样您就可以轻松地重新基地,同时设置您的分支为后代。另外,由于您想要一个干净的状态,您可能已经提交了不应该提交的文件,所以您必须将它们从索引中删除。考虑到这些因素,你应该:

$ git checkout --orphan dev2
Switched to a new branch 'dev2'
$ git reset # unstage all the files, you probably don't want to commit all of them
$ git commit --allow-empty -m 'Initial empty commit'
[dev2 (root-commit) a515c28] Initial empty commit

如果您使用 git 2.23或更高版本,您可能会习惯于使用 ABC0和 git restore而不是 git checkout。如果是这样,则标志与 这个答案中提到的相同。

git switch --orphan YourBranchHere

有没有什么方法可以在这个存储库中创建一个完全空的分支。

实际使用的命令(对于 Git 2.28 +)是:

git switch --discard-changes --orphan newBranch
# or
git switch -f --orphan newBranch

git switch 可从 Git 2.23(2019年8月)获得,并取代了 旧的令人困惑的 git checkout命令

但是我建议使用 Git 2.28(Q32020) ,因为 git switch --discard-changes --orphan已经在该版本中进行了优化。

第八季,第33集提交8186128(2020年5月21日) by 卡尔森(bk2204)
(朱尼奥 · C · 哈马诺 gitster犯罪合并,2020年6月9日)

builtin/checkout : 简化元数据初始化

签名: Brian M. Carlson
审核人: Derrick Stolee

当我们在 reset_tree,中调用 init_checkout_metadata时,我们希望传递有问题的提交的对象 ID,以便它可以被传递给过滤器,或者如果没有提交,则传递给树。

我们预料到了后一种情况,它可能发生在签出代码的其他地方,但不能发生在这里。

唯一没有提交对象的情况是在使用 --orphan调用 git switch时。

而且,我们只能在没有提交对象的情况下使用 --force--discard-changes来访问这个代码路径。

在这种情况下,没有必要使用提交或树来初始化签出元数据,因为

  • (a)没有提交,只有空树,和
  • (b)我们将永远不会使用这些数据,因为在检出没有文件的分支时,没有文件会被弄脏。

在这种情况下,传递全零对象 ID,因为我们只需要一些值,这是一个有效的指针。

测试:

git switch master
echo foo >foo.txt
git switch --discard-changes --orphan new-orphan2
git ls-files >tracked-files
# test_must_be_empty tracked-files