不删除提交历史记录的情况下移除/隐藏git分支

49

情况:

我有一个主存储库,其中包含一个主开发分支和许多“实验”分支(例如exp1exp2)。这些实验分支的目的是作为生成数值结果的实验的占位符。我记录实验分支的分支名称(和提交ID),以便我可以返回到提交以查看精确的代码和结果背后的历史。

但是,现在有太多的实验分支,很难看到主树了。因此,我正在重新思考保留每个结果集(即每个实验)背后的代码的策略。显然,我可以只保存每个分支的工作目录,但是保留提交历史记录也会很好。

可能的解决方案:

处理这个问题的一种方法是将实验分支移动到它们自己的独立存储库中,每个存储库都根据开发分支提交历史记录中适当节点的子节点进行根源。下面是我的意思的说明:

enter image description here

单击此处以获取图像的较大版本(在imgur.com上)。

例如,对于分支exp1,我想将提交A->B->C导出到以提交A为根的单独存储库中。然后,我可以记录提交P1的哈希值,以便知道exp1分支是从哪里派生的。

问题:

我该怎么做?

更好的问题:

另一方面,我强烈怀疑有一个更好的策略来做我想做的事情,即为了进行视觉检查而减少树形结构的混乱,但保留到先前分支的占位符以便需要时返回它们。那么,有人可以推荐一种策略吗?


2
我只是保留一个单独的“存档”远程仓库,将旧分支推送到该仓库,然后从本地仓库中删除它们。 - Ajedi32
@Ajedi32 那听起来是一个不错的主意。我该如何在我的 git log 命令中排除那个远程 repo 呢?例如,通常我运行 git log --oneline --graph --decorate --all。我如何修改这个 git log 命令以显示给定的远程 repo? - synaptik
2
只是一个问题:听起来好像你保留exp分支只是为了以防后面需要找到提交。为什么不直接打标签,而不是保留分支呢? - sleske
但是现在有这么多实验分支,以至于很难看到主干了。你所说的“看到主干”具体是什么意思?你到底如何“看到”这棵树?你只是查看git branch输出,并不想看到所有那些额外的分支吗? - Gabriel Staples
显示剩余4条评论
1个回答

45
这里有一种替代方案:在删除分支名称之前使用非分支引用保存分支尖端。
由于这些是非分支引用,它们不会出现在`git branch`的输出中,也不会出现在`git log --branches`和`gitk --branches`等内容中。但是,它们将显示在`--all`列表中,并保留存储库对象。
要创建或更新非分支引用,请使用git update-ref。选择refs/内的命名空间,您认为不会与将来的某些用途冲突(当前用途为refs/heads/用于分支,refs/tags/用于标签,refs/remotes/用于远程分支,refs/notes/用于注释,refs/stash用于stash)。[编辑,2022年7月:refs/namespaces/现在也被保留,refs/replace/git replace使用。refs/bisect/refs/rewritten/refs/worktree/被保留;如果您将使用git filter-branch,则保留refs/original/。如果您使用Gerrit,则有更多保留名称。列表似乎永远不会停止增长,因此请在此处小心使用。]

4
我明白了,这是一个所谓的 Git 管道命令,它允许你基本上任意地创建(更新)引用。headstagsremotesnotesstash 实际上只是 Git 中具有标准公认含义的引用的名称空间。对吗? - synaptik
3
好的,这个命令足够吗? git update-ref refs/archive/run/diss-001 origin/run/diss-001 - synaptik
10
只需创建指向所需提交的分支。请记住,在这种“归档”之前或之后,任何普通的分支名称都只是指向某个特定提交ID,我们称其为“分支尖端”。由于像refs/archive/foo这样的引用也指向某个特定的提交ID,因此您可以简单地使用git checkout -b restored refs/archive/foo创建一个新的分支restoredrefs/heads/restored),该分支指向该提交。它的名称在refs/heads/中使其成为一个分支。一旦它是当前分支,Git将自动更新它。 - torek
5
如果你的“存档分支”都列在refs/archive/下,请使用 git for-each-ref refs/archive 来显示它们(请注意,git for-each-ref有很多参数,包括一个格式化指令来控制其输出)。如果你选择了其他命名空间,你需要做些略微不同的事情。我不确定这里的答案是否需要进一步解释;人们也可以阅读注释。 :-) - torek
2
@Dave:是的,前提是接收Git允许它。每个Git实现都可以对非标准命名空间设置自己的限制。例如GitHub不允许您创建refs/pull/名称:它们将这些名称保留给自己使用。Gerrit服务器保留refs/for/:它们允许您在那里推送,但这些名称是“魔法”名称,并会导致特殊操作,然后消失。 - torek
显示剩余14条评论

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