在查找已合并到当前分支的分支时,如何排除没有提交的新git分支?

时间:2019-12-05 23:15:55

标签: git

扩展到this question。我的目标是通过删除已经合并到当前分支的分支来进行一些清理。

所以我开始

git branch --merged

但是,这也会拾取从当前分支创建但没有提交的分支。有没有一种方法可以将结果限制为其中至少包含一个提交的分支?

示例:

git checkout develop
git checkout -b newFeature
touch a
git add . && git commit -a -m "sample"
git checkout develop
git merge newFeature
git branch branchIwantToKeepForFuture
git branch --merged  --> this shows both newFeature and branchIwantToKeepForFuture

我需要找到一种仅显示newFeature但不显示branchIwantToKeepForFuture的方法,以便我可以使用这些args运行delete命令

1 个答案:

答案 0 :(得分:0)

我在评论中添加了简短答案(只需再次创建分支,或稍后再创建),但问题中存在一个基本错误:

  

...这还将拾取从当前分支创建但没有提交的分支。

那些分支 do 包含提交。它们只包含与您当前分支相同的 提交。

请记住,分支名称只是一个名称-无论您喜欢什么字符串,都有一些较小的限制,例如“无连续点”和“无符号”等等。请参阅the git check-ref-format documentation)-包含一个哈希ID。一个哈希ID是作为分支尖端的提交。这是Git中分支名称的定义:是

  • 一个名字
  • 包含哈希ID
  • 提交

该提交(由于具有标识该提交的名称)是该分支的提示。

如果个以上名称持有相同哈希ID,则一次提交是多个分支的提示

同时,每个提交都包含一个哈希ID列表(通常只有一个条目),这些哈希ID是该提交的 parent 提交。这些哈希ID是提交本身的一部分。从某种意义上说,哈希ID是每次提交的“真实名称”。如果我们绘制提交,用单个大写字母替换实际的哈希ID,则会得到如下图所示:

... <-F <-G <-H   <--master

名称 master保存提交H的哈希ID。提交H保留先前提交G的哈希ID。 G保留先前提交的F的哈希ID,该哈希ID保留另一个哈希ID,依此类推。因此,名称master 指向 HH指向G,后者指向F,依此类推。

如果我们有多个名称指向H,则所有提交-从H-都位于这些分支的 all 上:

...--F--G--H   <-- master, develop
            \
             I--J   <-- feature/short

同时分支名称feature/short指向提交J,指向I,指向H,指向G,依此类推。上。因此,通过H的提交位于所有三个分支上,而IJ的提交目前仅在{{1 }}。

Git将移动一个分支名称。如果我们将新名称feature/short指向temp,我们将得到:

H

如果我们现在...--F--G--H <-- master, develop, temp \ I--J <-- feature/short 然后进行新的提交,则新的提交将获得一个新的哈希ID-但在这里我们将其称为git checkout temp-名称K < em>移动以指向新提交:

temp

要创建分支,我们选择任何现有的提交,并命名一个指向该现有提交的新名称。要删除分支,我们只需删除名称。让我们删除 K <-- temp / ...--F--G--H <-- master, develop \ I--J <-- feature/short (我们必须首先temp一些其他东西):

git checkout

提交 K / ...--F--G--H <-- master, develop \ I--J <-- feature/short 仍然存在。您现在无法找到。一旦确实找不到它,Git最终将收回它,但是Git通常会坚持一些隐藏的方法来找到K,以防万一您想找回它,通常至少一个月左右。只要这些隐藏的方法可以找到K,提交K就会留下来。但是由于找不到明显的方法,我们将停止完全绘制它。

现在让我们将名称K移到指向提交develop的位置,也许可以这样做:

J

图片现在看起来像这样:

git checkout develop && git merge --ff-only feature/short

...--F--G--H <-- master \ I--J <-- feature/short, develop (HEAD) 注释只是为了记住我们现在已签出的分支。

(HEAD)的作用是查找以下位置的名称:

  • 给定的分支名称指向一个提交(始终),
  • 该名称所指向的提交可从您当前的git branch --merged
  • 到达

因此,如果您在HEAD上,并且提交develop不存在,则指向可以从K开始并向后工作的提交的名称是:

  • J,因为master可以通过从H开始并返回两步来访问,并且
  • J,因为feature/short可以通过从J开始而不进行任何操作来访问。

J应该这样向前迈一步:

feature/short

然后...--F--G--H <-- master \ I--J <-- develop (HEAD) \ L <-- feature/short 将停止列出git branch --merged,因为我们无法通过从feature/short开始并向后工作来达到提交L。但是向J添加另一个提交对develop的输出没有影响:

git branch --merged

我们可以从...--F--G--H <-- master \ I--J--M <-- develop (HEAD) \ L <-- feature/short 开始,倒退三步,依次到MJ,然后到I,我们已经完成了{{ 1}}点,因此H仍列出master

如果愿意,可以在以下位置获取分支机构列表:

  • 该名称指向可从git branch --merged
  • 访问的提交
  • 名称指向的提交不是master所标识的提交

但这将采取多个步骤:首先,通过HEAD获取可达列表,然后比较以下结果:

HEAD

(这是当前提交的实际哈希ID)对每个分支名称(这是每个分支的尖端提交)上git branch --merged的结果。

当心在git rev-parse HEAD 之类的远程跟踪名称上使用它

请注意,所有这些结果仅对您的姓名有效。如果将它们应用于远程跟踪名称,它们会告诉您有关这些远程跟踪名称的信息,因为它们现在存在于存储库中。如果某些 other Git中的分支名称非常活跃,则需要先运行git rev-parse来更新远程跟踪名称。这样,您的origin/mastergit fetch等将与另一个Git保持同步。

但是,如果其他Git处于极端状态,则在您花费时间运行origin/master并进行更多检查时,您自己的远程跟踪名称可能已过时。您需要再次运行origin/feature来更新它们,然后重试。到您得到结果时,它们可能已经过时了,依此类推。除非您控制另一个存储库,并且可以使人们停止对其进行更新,否则您将与他们竞争以获取准确的图片。这通常是不明智的。