说我有这个:
latest_commit=`git rev-parse HEAD`
git checkout -b "foo_$latest_commit"
git reset --soft "origin/dev"
我正在做的是跟踪第二个分支与第一个分支之间的差异。但是,除了将提交ID放在第二个分支的名称中,还有一种方法可以将元数据存储在第二个分支的某处,这样我就不必在分支的名称中放置一个长的提交ID?
最终,我要做什么?在使用git reset --soft
压缩提交之后,我将把foo_ $ latest_commit合并到Integration分支中。后来,我希望能够安全地删除第一个和第二个分支。如果第一个分支的尖端与第二个分支的名称中的提交ID匹配,我可以安全地删除第一个分支。
答案 0 :(得分:2)
...有一种方法可以将元数据存储在第二个分支的某处...
不直接,不。
请记住,每个分支 name 仅仅是指向提交的(可移动的)指针,具有特殊的属性,即如果您使用git checkout
来“进入”分支,{{1 }} 自动移动指针。其他各种命令也愿意以各种方式移动它:例如,git commit
将以快进的方式移动当前分支名称,而git merge --ff-only
将任意地移动它。
所以:您可以在哪里 存储元数据?这有点棘手。
Git由两个主要数据库组成:存储库本身是一个键值存储,以哈希ID作为键,存储库对象(blob,树,提交和带注释的标记)作为值。同时,引用(在git reset
中的分支名称,在refs/heads/*
中的标签名称,在refs/tags/*
中的存储区,等等)是一个键值存储,对键有一些奇怪的约束(大多数情况下,请参见refs/stash
),其值为哈希ID。
因为您的目标是(我认为)将分支名称与两个不同哈希ID相关联,所以一种显而易见的方法是在{{1} }。假设我们选择了git check-ref-format
。对于名称为B(例如全名refs
)的分支,您只需要创建一个refs/bases/
。您可以存储在refs/heads/B
中的唯一东西是哈希ID,但这正是您要存储的,因此就可以了。
您是否希望存储一个简单的哈希ID以外的内容,例如,如果要存储另一个名称,则需要某种数据对象。您可以选择四种对象类型中的任何一种,但是其中两种类型受到严格限制:树或提交必须正确设置格式。其中一个是弱约束的:一个带注释的标签对象必须包含另一个对象(带注释的标签的目标)的哈希ID,然后可以包含任意文本。最后一个
要创建带注释的标记对象,请使用refs/bases/B
。有关必需的标记格式,请参见其文档。
要创建Blob,请使用refs/bases/B
,可能使用git mktag
;请参阅其文档。
两者都输出一个哈希ID,然后您可以将其设置为哈希ID,以存储在git hash-object -w
或--stdin
或您选择的任何名称空间下。
对于大多数Git用法,工作方式不是存储基本分支名称,也不存储基本提交哈希ID。而是使用 set减法来请求 reachable 提交,格式为:
这正是refs/bases/B
对您传递的参数所做的事情,例如:当您运行refs/xyz-meta/B
时,Git枚举所有可从 到达的提交{{1} },减可从git rebase
获得的所有提交。这在Git中非常常见,以至于它具有git checkout feature; git rebase develop
语法:feature
意味着develop
,这意味着“从git rev-list
可以到达的提交,不包括从develop..feature
可以到达的提交”
(元数据技巧可以使您自动记住适当的名称,但事实证明,实际上,大多数人似乎不需要此名称。对于您的特定用法,这可能是一个好习惯我放这部分是因为我相信将来,其他人会找到您的问题和答案,并认为这是记住每个派生分支的“基础分支”的聪明方法。那不是一件聪明的事情。)