什么是`git checkout --orphan`命令?它的用途是什么?

84

我刚刚发现了git checkout --orphan这个命令,但是我不知道如何使用它。它的帮助页面说它会创建一个新的没有父分支的分支

master分支中,我尝试过git checkout --orphan br,结果只看到工作目录中的文件变成了“要提交的更改”,而git log则显示fatal: bad default revision 'HEAD'

那么使用git checkout --orphan有什么优势呢?

5个回答

103
git checkout --orphan的核心用途是在非新建存储库上创建一个类似于git init状态的分支。
如果没有这个能力,你所有的git分支都将有一个共同的祖先,即你的初始提交。这是一种常见情况,但并不是唯一的情况。例如,git允许您在单个存储库中将多个独立项目作为不同的分支进行跟踪。
这就是为什么您的文件被报告为“要提交的更改”的原因:在git init状态下,尚未创建第一个提交,因此所有文件对于git来说都是新文件。

1
在非新存储库上创建类似于git init状态的分支,什么情况下这样做有用? - Unknow0059
1
在某些情况下,您可能希望保留特定分支的文件并截断存储库的历史记录。我目前处于这样一种情况,必须截断git历史记录以缩小该存储库的大小,因为我的Azure应用服务没有足够的空间来容纳超过16 GB的提交历史记录。 - SouravOrii
另一个用例是删除提交历史记录并保持您的代码当前状态,对吗?此外,还有什么? - Gel
提示:因为我只想要一个没有历史记录和任何文件的空分支(在.NET Core重构之后): 创建新分支后,使用以下命令: git checkout --orphan <branchname> 您将获得一个没有历史记录但与起始分支相同文件的新分支。 要删除所有文件,请使用以下命令: git rm -rf . (注意点号,并确保您真正处于正确的分支中;-) 结果是一个没有文件和历史记录的分支。 - golfo
请为我顶置评论。 - Abdel Shokair
为什么你不直接创建一个新的仓库呢?这个命令看起来完全多余。 - undefined

23
它被例如GitHub Pages使用,该网站将存储库的网站放在存储库中,但在单独的分支上。 除了该网站的历史记录外,在此分支上不需要存储任何内容。

7
我们正在从私有仓库迁移到公共仓库,由于提交的信息包含敏感信息,我们想要将一个分支重置为"new"并将其作为空白分支推送。以下是此流程的典型方式: 如何在Github上删除所有提交历史记录?

1

在我看来,这个命令可能会有些令人惊讶。您可能对此命令有两种非常不同的期望:

  1. 使用截断的历史记录进行全新的开始(相同的树)
  2. 完全全新的开始(新树;您必须从头开始添加文件)

1:它实际上做了什么

正如JB.所解释的那样,git checkout --orphan <branch name>将会:

  1. 将您放在一个孤立分支上,这是一个尚未有任何提交的分支
  2. 暂存您来自的树(如果您在master上,则为master^{tree}
  3. 保留任何未暂存和未跟踪的文件

这意味着您之前所在的提交的和您创建的紧随其后的提交的树将是相等的:[1]

$ # Let’s say that you’re currently on `master`
$ git checkout --orphan orphan
$ git commit --message 'A new start'
$ git diff master

由于树相等,差异不会给出输出。

这实际上截断了您在master上拥有的所有提交。(当然,master还在那里。)

2:你可能期望它做什么

这是我期望它能做到的:

  1. 将您放在一个孤立的分支上
  2. 给你一个空树

使用案例可能是添加一些文件,以记录一些库级 metadata,例如分支元数据。[2]

结果,您可以使用git switch --orphan <branch name>来完成此任务,因为它几乎可以做到我期望的git checkout --orphan <branch name>所做的事情。

  1. 将您放在一个孤立的分支上
  2. 从树中删除所有已跟踪的文件,但保留未跟踪的文件
    • 这意味着您的新树将包含通过像 .gitignore 这样的方式忽略的所有内容
    • 如果要删除所有这些未跟踪的文件,请使用 git clean --force -d

但请注意,此命令在撰写本文时(Git 2.40.0)被标记为“实验性”。

使用 git checkout --orphan <branch name> 完成相同的操作

也许您不想使用实验性命令。如果您想要从头开始创建一个新树,则 man git checkout 推荐您执行以下命令:

git checkout --orphan orphan
git rm -rf .

然后你也可以这样做(由我添加):

git clean --force -d

注释

  1. 嗯,我猜实际上它们会是完全相同的树,因为它们具有相同的哈希值。 :)

  2. 执行以下操作:

     $ <创建孤立分支>
     $ vim branch-descriptions.txt
     $ git add branch-descriptions.txt
     $ git commit --message "Init: descriptions"
    

1
这是一个很棒的答案。我会用它来创建发布版本分支。+1 - Konrad Viltersten

0
另一个可能有用的用例是构建用于测试的机器或虚拟实例,这些机器需要特定的.git文件夹设置(例如用户、远程URL),并且由于空间限制而丢弃所有历史记录。这通常是旧版设置的情况,不使用 Docker 等容器。
通常会为专用部署分支执行此操作,而不是处理主分支。一旦新分支被推送到远程,就在实例上执行以下操作:
git clone [remote-url] --branch [name] --single-branch [folder]

当直接使用主分支(不建议)时,浅克隆是更好的选择:

git clone -–depth [depth] [remote-url]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接