如何创建一个新的(和空!)“根”分支?

时间:2013-02-22 22:37:58

标签: git

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

不幸的是,甚至在repo的提交树的最基础上的提交(让我们称之为A)包含很多文件(这是一个在已经相当成熟的项目上初始化的存储库)。

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

我是否可以通过某种方式在此存储库中创建完全裸分支,<start-point>尽可能接近A


1 BTW,这 相当于创建一个新的仓库。由于很多原因,单独的回购将不太方便。


编辑:好的,这就是我所做的,基于 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)'

...以便第一次提交为空,并始终可用于启动新的独立分支。 (我知道,这将是一个非常需要的设施,但它很容易让它随时可用。)

4 个答案:

答案 0 :(得分:183)

创建分支时使用--orphan

git checkout --orphan YourBranchName

这将创建一个零提交的新分支,但是所有文件都将被暂存。那时你可以删除它们 (“删除它们”:git reset --hard将清空索引,为您留下一个空的工作树)

请查看man page结帐,了解有关--orphan。

的更多信息

答案 1 :(得分:6)

要添加到已接受的答案 - best practice以恢复清洁状态,请创建an initial empty commit,这样您就可以在为子孙后代设置分支时轻松进行变基。另外,因为你想要一个干净的状态,你可能已经提交了你不应该提交的文件,所以你必须从索引中删除它们。考虑到这些,你应该:

$ 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

答案 2 :(得分:2)

如果您使用git 2.23或更高版本,则可能会习惯于git switch and git restore而不是git checkout。如果是这样,则该标志与this answer中提到的标志相同。

git switch --orphan YourBranchHere

答案 3 :(得分:1)

有什么方法可以在此存储库中创建一个完全裸露的分支。

实际使用的命令(与Git 2.28+一起使用)是:

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

git switch可从Git 2.23(2019年8月)开始使用,并取代old confusing git checkout command

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

请参见commit 8d3e33dcommit 8186128brian m. carlson (bk2204)(2020年5月21日)。
(由Junio C Hamano -- gitster --commit ded44af中合并,2020年6月9日)

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

签名人:brian m。卡尔森
作者:Derrick Stolee

当我们在init_checkout_metadata中调用reset_tree,时,我们希望传递所涉及的提交的对象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