如何编写可移植的Git库脚本?
我通过在/usr/local/libexec/git
编写脚本并创建别名来调用它们来创建自定义Git命令。 例如:
git config --global alias.graph '!/usr/local/libexec/git/git-graph'
棘手的部分是我希望我的脚本是“可移植的”,因为任何安装了Git的人都应该能够像我一样安装和运行我的脚本,而不会遇到缺少的依赖关系。
重要编辑:在@ Schwern的回应之后,我意识到我必须添加更多信息。 “任何已经安装Git的人”替换为“任何通过官方Git源代码提供的git-core
脚本与Git交互的人”。 例如,调用git rebase
执行.../git-core/git-rebase.sh
。 (你可以点击最后一个单词;它是一个超链接,但它不会在所有浏览器中出现)。我认为这是大多数Git用户的情况,因为这是Git项目本身提供的默认值。
从我多年编写可移植shell脚本的经验来看,我知道在任何一个曾经存在的类Unix操作系统上运行即使是中等复杂度的shell脚本也是徒劳的。 然而,我认为在Git工作站之间存在一个共同的工具基础是合理的,至少足以避免在编写脚本在这些工作站上运行时不停地跳过篮圈并在蛋壳上行走。
以下是我对Git工作站的假设:
git-core
目录中的所有脚本(例如/usr/libexec/git-core
)都没有被Git安装放置在那里。 git-core
所有脚本按预期运行(即与Git维护人员的工作站或具有“正常”设置的任何人一样)。 我如何确定可用于在这些Git工作站上编写可移植脚本的公用工具?
编辑:我基本上在寻找主要Git发行版中提供的git-core
脚本的依赖列表。 这将给我寻找的共同基地。
实际上,所有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-core
目录本身的确切位置是在构建Git时设置的。 您可以通过运行以查看它:
git --exec-path
请注意,尽管git foo
会尝试运行$(git --exec-path)/git-foo
,如果在那里没有git-foo
,并且将git-foo
放在您自己的脚本目录中(即在$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
(qv)的文件。 这包含一些便利功能和一些针对构建Git的系统上已知问题的解决方法。 因此,“核心”Git脚本应始终以. git-sh-setup
. git-sh-setup
。 (这是可行的,因为$PATH
在前面有git-core目录。)显式运行一些“非核心”contrib脚本. $(git --exec-path)/git-sh-setup
. $(git --exec-path)/git-sh-setup
。
在脚本中,除了需要解决某些错误(例如,FreeBSD / bin / sh在某些版本中return
错误句柄)之外,您可以依赖任何POSIX shell内置函数。 对于额外的命令的支持基本上是基于“通过测试找到”的基础上,据我所知:如果您查看git源代码中的git-sh-setup.sh
和其他.sh
文件的历史记录,您将看到各种随着时间的变化来处理这些事情。
除了“SVN工作站”或者甚至是“Ruby工作站”之外,再没有“Git工作站”这样的东西了。 这只是一些安装了Git的机器,并且正在用于处理或获取某些使用Git的项目。 如果他们在Windows环境中,它将是Windows。 如果它们位于过时的Solaris计算机上,则它将成为Solaris环境。 由于Git现在标配OS X,所以每台OS X机器都是“Git工作站”。
由于“Git工作站”包含Windows,并且Windows不附带任何常规shell实用程序,因此根本无法使用shell。 充其量,你可以依靠Git Bash提供的最小集合,但是有很多不使用Git Bash的Windows / Git安装。 相反,很多IDE都捆绑了Git。
这些都不会改变编写可移植shell脚本的兼容性挑战。 BSD vs Gnu vs一些商业怪物,所有的问题都是关于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
的二进制文件。