162

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

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

这意味着,即使我A作为新分支<start-point>A.

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


1顺便说一句,这等于创建一个新的仓库。由于很多原因,单独的回购会不太方便。


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

4 回答 4

259

--orphan创建分支时使用:

git checkout --orphan YourBranchName

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

查看手册页以了解有关 --orphan 的更多信息。

于 2013-02-22T22:41:09.207 回答
18

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

$ 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
于 2017-10-24T16:57:20.997 回答
6

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

实际使用的命令(使用 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(2020 年第三季度),因为git switch --discard-changes --orphan在该版本中已经过优化。

请参阅提交 8d3e33d提交 8186128(2020 年 5 月 21 日),作者是brian m。卡尔森 ( bk2204)
(由Junio C Hamano 合并 -- gitster--ded44af 提交中,2020 年 6 月 9 日)

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

签字人:brian m. carlson
审核人:Derrick Stolee

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

我们预料到后一种情况,它可能会出现在结帐代码的其他地方,但不会出现在这里。

我们没有提交对象的唯一情况是git switch使用--orphan.

此外,我们只能在没有提交对象的情况下使用--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
于 2020-06-13T15:42:18.903 回答
4

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

git switch --orphan YourBranchHere
于 2020-03-23T20:37:01.433 回答