2017-02-15 117 views
1

背景:我们目前有一个项目,它需要将多个git存储库克隆到一个父文件夹中。我试图写一个脚本,这样我可以运行git操作,所有子目录,使其更易于管理(如./gitall.sh status/add/reset/commit -m "Foobar"/push /等Shell脚本>双引号参数,只有它存在

脚本运作良好所有操作,直到我试图执行一个./gitall.sh push

我收到错误fatal: remote part of refspec is not a valid name in为每个目录,因为有效的命令是git -C somedir push "" "" "" ""git borks在后双引号)。NB的参数需要用双引号,以便捕获参数rs与空格。

gitall.sh

find ./repo-* -type d -depth 0 -exec bash -c "git -C {} \"$1\" \"$2\" \"$3\" \"$4\" \"$5\"" \; 

反正是有双引号的参数,只有当它的存在? (或者无论如何告诉git忽略尾部双引号?)

+1

如果你有这么多的git仓库需要自动与它们进行交互,你可能想重新考虑你的仓库结构。 [考虑子模块](https://git-scm.com/book/en/v2/Git-Tools-Submodules)。 – Schwern

+0

如果您发现自己需要同时提交*多个存储库*,那么您使用的是Git错误。如果您在多个存储库中有更改,并且它们在语义上属于一起以便您想将它们提交到一起,那么它们不应该放在不同的存储库中。如果你有独立的存储库,那些应该独立工作*,而不需要另一个存储库来了解它的历史。 – poke

+0

谢谢大家!这是我最终使用的。 https://gist.github.com/nickgrealy/3ad1d08a5efc4696a29c658f1842d89a#file-git-sh –

回答

2

问题是你正在向git push传递额外的参数。每个""由shell传递到git,然后它认为它获得7个参数,但最后4个是空字符串。

你在找什么是"[email protected]""[email protected]"相当于"$1" "$2" ...

有没有必要所有的额外报价,也没有bash -c。将在shell脚本中展开"[email protected]"

另请注意,调用find将不能用于GNU查找,因此请使用BSD查找的完整路径。

#/bin/sh 

/usr/bin/find ./repo-* -type d -depth 0 -exec git -C {} "[email protected]" \; 
+0

[永远不要解析ls的输出](http://mywiki.wooledge.org/ParsingLs)。它会例如目录名称包含空格时会失火。 –

+0

@SirAthos对,谢谢。必须有一种更简单的方法来遍历shell中的目录。 – Schwern

1

"[email protected]"后,并有更好的方法可以做到你在做什么:

find -name .git -prune -execdir git "[email protected]" \; 

,你可以添加-maxdepth 1或任何限制find命令的进一步洞穴探险。

3

在bash中传递未知数量参数的正确方法是使用"[email protected]"。此外,您不需要明确呼叫bash,因为这会使您需要引用参数的方式复杂化。

这将自动引用所有参数:

#!/bin/bash 
find ./repo-* -type d -depth 0 -exec git -C {} "[email protected]" ';' 

往前多走一步,就没有必要调用find如果你想要的是在目前的水平目录条目。该/在匹配模式的结尾将只选择目录:

#!/bin/bash 
for d in repo-*/; do 
    [ -d "$d" ] && git -C "$d" "[email protected]" 
done 

(请注意,如果你没有匹配模式的任何目录,循环将使用该文本参数repo-*/执行一次;在这种情况下,[ -d "$d" ]将防止git被调用)。

最后,您可能要考虑使用Google's repo tool而不是您自己的解决方案来管理多个git回购。它功能强大且易于使用。

+0

如果没有匹配'repo - * /'它将运行'git -C repo - * /'。也许存在检查? – Schwern

+1

@Schwern确实会;为了完成,我添加了一个'-d'的警戒,并澄清了这个注释。 –