如何编写可移植的Git库脚本?

时间:2016-12-12 19:49:17

标签: git portability

我通过在/usr/local/libexec/git中编写脚本并创建别名来调用它们来创建自定义Git命令。例如:

git config --global alias.graph '!/usr/local/libexec/git/git-graph'

棘手的部分是我希望我的脚本能够随身携带并且#34;从某种意义上说,任何安装了Git的人都应该能够像我一样安装和运行我的脚本,而不会遇到缺少的依赖项。

重要编辑:按照@ Schwern的回复,我意识到我必须添加更多信息。替换"任何安装了Git"与#34;任何通过官方Git来源提供的git-core脚本与Git交互的人#34;例如,调用git rebase执行.../git-core/git-rebase.sh。 (你可以点击最后一个单词;它是一个超链接,但它并没有在所有浏览器中以这种方式出现。)我认为这是大多数Git用户的情况,因为这是Git提供的默认值项目本身。

从我多年编写portable shell scripts的经验来看,我知道在每个类似Unix的操作系统上都可以运行即使是中等复杂度的shell脚本也是徒劳的。但是,我认为在Git工作站之间存在一个共同的实用工具基础是合理的,至少足以避免在编写脚本在这些工作站上运行时不断跳过箍和走蛋壳。

以下是我对Git工作站的假设:

  • git-core目录中的所有脚本(例如/usr/libexec/git-core)由于被Git安装放置在那里而没有被更改。
  • git-core中的所有脚本都按预期运行(即与Git维护者'工作站上的相同,或者具有"正常"设置的任何人)。
  • 已安装的Git版本符合我决定使用我的脚本支持的一些任意最低要求。 编辑:通过"任意",我的意思是"方便"。 @Schwern精确地说明了我在这里想说的话。

如何确定可用于在这些Git工作站上编写可移植脚本的实用程序的通用基础?

编辑:我基本上是在寻找主Git发行版中提供的git-core脚本的依赖项列表。这将提供我正在寻找的共同基础。

2 个答案:

答案 0 :(得分:2)

事实上,Git的所有内置脚本(有很多,sh和一些perl)都存在于git-core目录中。在设置各种环境变量之后,运行git xxx会尝试执行程序git-xxx,通常在git-core目录之外。例如,git --git-dir=/path/to/some/dir导出GIT_DIR=/path/to/some/dir设置。

构建Git时会设置git-core目录本身的精确位置。您可以通过运行来查看它:

git --exec-path

请注意,虽然git foo会尝试运行$(git --exec-path)/git-foo,但如果中没有git-foo,则会将git-foo放入< em>拥有脚本编目目录(位于$PATH上的某个位置),git foo将最终运行 。机制很简单:git前端将git-core路径插入$PATH的前面:

$ cat << 'end' > $HOME/scripts/git-statusy
? #! /bin/sh
? echo statusy: \$PATH is $PATH
? git status
? 'end'
$ chmod +x $HOME/scripts/git-statusy
$ git statusy
statusy: $PATH is /usr/local/libexec/git-core:[...snipped]
On branch master
... [snipped]

git-core目录中,有一个名为git-sh-setup(q.v.)的文件。这包含一些便利功能和一些解决方案,用于构建Git的系统上的已知问题。因此,“核心”Git脚本应始终以. git-sh-setup开头。 (这是有效的,因为$PATH前面有git-core目录。)但是,一些“非核心”的贡献脚本显式地运行. $(git --exec-path)/git-sh-setup

在您的脚本中,您可以依赖任何POSIX shell内置函数,除非您需要解决某些错误(例如,某些版本中的FreeBSD / bin / sh错误句柄return)。据我所知,支持其他命令基本上是“通过测试找到的”基础:如果你查看Git源中git-sh-setup.sh和其他.sh文件的历史记录,你会看到随着时间的推移做出各种变化来处理这些事情。

答案 1 :(得分:0)

除了“SVN工作站”甚至是“Ruby工作站”之外,没有“Git工作站”这样的东西了。它只是一些安装了Git的机器,用于处理或获取一些使用Git的项目。如果他们在Windows环境中,它将是Windows。如果它们位于过时的Solaris计算机上,则它将是Solaris环境。由于Git现在标配OS X,因此每台OS X机器都是“Git工作站”。

因为“Git工作站”包含Windows,而Windows没有任何普通的shell实用程序,所以根本不能使用shell。充其量你可以依赖Git Bash附带的最小集合,但有很多Windows / Git安装不使用Git Bash。相反,许多IDE都捆绑了Git。

这些都不会改变编写可移植shell脚本的兼容性挑战。 BSD与Gnu对比一些商业怪物,以及所有关于Windows的问题,这些都将存在。

对于安装第三方扩展,这一切都没有改变。他们没有进入/usr,这是系统的东西,应该保持不变。它们的内容类似/usr/local甚至~/bin。如果Git脚本位于用户的PATH

中,它们将起作用

至于你对Git的一些假设......

  

git-core目录中的所有脚本(例如/ usr / libexec / git-core)都没有被更改,因为它被Git安装放置在那里。

这是一个公平的假设......如果存在的话。在OS X上没有/usr/libexec/git-core,我找不到任何等价物。我怀疑他们都被编译成二进制文件。 您不能假设Git是一堆脚本 ,甚至还有像MacPorts这样的兼容性硬链接。

  

git-core中的所有脚本都按预期运行(即与Git维护者工作站上的相同,或任何具有“正常”设置的人)。

同样,这是一个很好的假设 ,如果它们存在 ,他们没有。

  

已安装的Git版本符合我决定支持我的脚本的任意最低要求。

选择支持脚本所需功能的最低版本,而不是任意的,这对您来说并不是太不方便。请务必使用git --version

进行检查

考虑到所有这些,便携式......

  • 直接使用git,而不是通过脚本。
  • 不要 假设“git”不是名为git的二进制文件。
  • 让安装程序询问用户的git二进制文件的位置。
  • 不要 将您自己的扩展名转储到/ usr / libexec中,将它们放在用户路径中的某个位置。
  • 不要 硬编码安装扩展程序的任何路径。
  • 不要 在shell中或使用Unix实用程序编写任何内容。
  • 使用编译语言并提供二进制文件或常用的脚本语言,如Perl或Python或Ruby,并提供二进制包。