git别名不仅仅记录我想要的分支

问题描述 投票:0回答:1

我已经创建了一个测试别名,在这个别名中,我希望能够只记录我正在使用的当前分支(请记住这是日志的简化版本,最后一个有更多细节,颜色和等等)。

我的别名看起来像这样:

test = "!git log \"$(git rev-parse --abbrev-ref HEAD)\""

但是当我输入git test时,我得到了分支上的2个提交以及来自不同分支的所有先前提交(我不想要)。

任何的想法?谢谢

git github git-alias
1个回答
1
投票

你在这里显示的别名没有错,你的期望(你对Git在“分支上”的意思)的想法是错误的:也就是说,你在“分支上”是什么意思,而Git的意思是“在一个分支上”分支“,根本不同意。

基本问题是Git分支并不意味着人们期望它们的含义。 (有人可能会认为这意味着Git是错误的。其他一些VCS如Mercurial定义了你希望Git定义它们的方式。)在Git中,一个分支名称只指向一个提交,Git称之为提交提交那个分支。

但是,每次提交都会指回先前或父提交的某个数字(通常是一个)。 Git使用它将提交串起来用于多种目的,包括用git log显示它们。我们可以通过纸上或白板或StackOverflow答案绘制这个,用一个箭头绘制分支名称,指向分支中包含的最后一个提交,然后进行该提交 - 其“真名” “是那些丑陋的提交哈希ID之一,但我们将在这里使用单个字母 - 从中​​有一个箭头,指向其父级,依此类推:

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

git log所做的是从分支名称指向的提交开始,并显示它。然后它移动到提交的父级,并显示。然后它进一步向后移动(向左)并显示提交,依此类推

所有Git内部链接总是向后,所以只要我们将更新的提交放在右边,我们就不需要绘制内部箭头了。我们只知道他们倒退了。那么让我们绘制一个更复杂的设置:

...--F--G--H   <-- master
            \
             I--J   <-- feature

名称feature指向提交J,因此提交J在功能分支上。承诺J回到I,指向回到HG,依此类推。所以每次提交都在分支feature上,即使提交H也是分支master的提示。通过H提交的所有内容都在master上,所以通过H的提交都在两个分支上。

你想在这里做什么,而不是记录当前分支中包含的所有提交 - 简单的git log就足够了 - 是要求Git记录当前分支中包含但未包含在其他分支中的提交(es )。棘手的部分在于弄清楚如何排除这些提交。

一种方法是列出每个分支名称,然后去掉当前分支名称,然后告诉git log:列出当前分支中包含的每个提交,从HEAD开始,但在到达任何其他分支中包含的任何提交时停止列表。要做到这一点,你可以得到当前的分支名称(正如你现在所做的那样,或以其他方式),并从所有分支的列表中排除(你会得到某种方式):

git log HEAD --not br1 br2 br3 br4

(如果其他四个分支通过br1命名为br4)。

但这通常不是必需的。通常,每当您在某个分支上工作时,您将指定一些其他名称 - 有时是另一个分支名称,有时候像origin/master这样的远程跟踪名称 - 作为当前分支的上游。每个分支只能有一个上游设置(或根本没有设置),一旦你有一个上游设置,你可以使用符号表示法@{upstream}或短版本@{u}来引用它:

git log HEAD --not @{u}

这有一个较短的语法,因为它经常有用:为一个提交说明符添加一个帽子^字符意味着“不”,所以你可以写:

git log HEAD ^@{u}

然后有一个更短的语法,因为这是如此常见:

git log @{u}..HEAD

字面意思是指从当前HEAD提交可到达的所有提交,除了从当前分支的上游可到达的所有提交。

所以你可能想要的只是@{u}..HEAD符号。这与明确排除所有其他分支不同。例如,假设我们有一个图形看起来像这样:

       M   <-- origin/br2
      /
...--H   <-- origin/master, origin/br1
      \
       I--J   <-- br1
           \
            K--L   <-- br2 (HEAD)

进一步假设br2的上游是origin/br2。要求origin/br2..br2(即@{u}..HEAD)中的提交意味着你将选择提交LKJI。要求br2中包含的提交但没有其他分支(即,不是br1)将只获得LK。如果只得到LK - 就是你想要的,那么你实际上需要枚举所有的分支。

(枚举所有分支的技巧是使用git for-each-refrefs/heads/前缀。你应该考虑使用git symbolic-ref来读取当前的分支名称,如果你要编写很多脚本或花哨的别名。这些命令,git for-each-ref和Gazxswpoi一样,是Git所说的管道命令,用于编写脚本和复杂的别名。它们的行为更加严格,针对计算机使用,而不是像git symbolic-refgit log这样的“面向用户”的命令。 “面向用户”有点可笑,但他们显然更加注重用户,例如,git diff。)


1这简化了一下。在查看多个分支名称或遵循多个父项的合并提交的情况下,git diff-tree必须以某种方式线性化图形拓扑。它通过优先级队列执行此操作,显示“最高优先级”提交,并将该提交的父项添加到队列中。然而,对于简单的线性链,Git在历史中向后移动的想法就足够了。

© www.soinside.com 2019 - 2024. All rights reserved.