如果我有以下git shell命令:
for branch in `git branch -a | grep remotes | grep -v master | sed 's/^.*old\/\(.*\)/\1/g'`; do git branch --track $branch remotes/old/$branch; done
这会检出old
遥控器上存在的每个远程分支,并使用与该遥控器上相同的名称跟踪它们。但是,如果我想稍微更改本地分支的名称,该怎么办?
如果我有以下远程分支怎么办:
release/1.2.1.0
release/1.2.1.1
我想在相同的父文件夹release
下查看它们,但我只想要版本号中的最后3位数字。所以我希望我的本地分支是:
release/2.1.0
release/2.1.1
我有一个简单的javascript正则表达式,匹配版本字符串的最后3位数字:(?:\d\.)(\d.*)
这使用不匹配的组来丢弃第一个数字,然后是句点。问题是,如何将该正则表达式应用于上面的git shell bash脚本中的$branch
变量?
答案 0 :(得分:2)
首先,避免git branch
这样的循环。这里的正确工具是git for-each-ref
,它旨在使用脚本语言(git branch
针对用户,输出格式将来可能会发生变化,例如)。
要遍历所有远程跟踪分支,只需告诉for-each-ref
扫描远程跟踪分支命名空间。由于您需要(更具体地说)名为old
的远程,您可以通过添加/old
来轻松完成此操作:
git for-each-ref refs/remotes/old
此处的输出默认为objectname objecttype refname
的三倍。我们只关心 refname
部分(如果我们愿意的话,我们也可以使用:short
修饰符删除refs/remotes/
,尽管我们仍然需要删除old/
我也可以在没有修饰符的情况下逃脱。因此,我们希望包含--format=%(refname:short)
。
继续bash,bash具有内置的正则表达式支持。但它的RE语法并不完全相同,所以你现有的RE必须改变。这是一个可能适合您的需求:
bash$ x=1.2.3.4
bash$ [[ $x =~ ([0-9]\.)([0-9.]+) ]] && echo ${BASH_REMATCH[2]}
2.3.4
(这里有一点微妙之处:使用$x
改变=~
匹配的方式,在我们的例子中可能是好的。作为一个老派的Unix人我通常更喜欢使用{{ 1}}我自己,但在这种情况下,我可能会在Python中执行此操作,它具有Perl样式的RE,并且Javascript / ECMAscript RE在Perl上建模。但所有这些或多或少都无关紧要。最重要的是这个RE与版本号匹配器稍微相当。例如,它匹配“1.3..6”之类的字符串。我们很安全,因为它们是无效的分支名称 - 双点是禁止的,因为它们会与set减法冲突gitrevisions
中的语法 - 但它通常有点草率;通过一些工作,我们可以提出更严格的表达。它也失败以匹配从两个或更多数字开始的修订,但是你的原始RE也是如此,所以我故意将其留下。)
在shell中循环读取,使用expr
通常是明智的(参见Etan Reisner's comment),尽管在这种情况下我们可以安全地省略它,因为git控制分支名称。我将在示例中使用它只是为了表单。
将这些全部放在一起:
-r
(这整件事完全没有经过考验)。