python脚本:git运行前检出



我已经开始使用gitHub来管理每天在我的工作站上运行的生产脚本的开发过程(通过cron)。

确保最新有效的生产版本运行的一种方法是在运行目标脚本之前,在生产目录中运行git checkout。我想知道它是否可以从生产脚本内完成(即检查这是最新版本,如果不是,git checkout,如果是,什么都不做,运行)

如果当然可能这样做,例如(未经测试):

git fetch &&
ahead=$(git rev-list --count master..origin/master) &&
case "$ahead" in
0)  ;; # run normally
*)  echo "I seem to be out of date"
git merge --ff-only || { echo "update failed, quitting"; exit 1; }
exec <path-to-script>;;
esac
# ... normal part of script here

但这几乎肯定是错误的方法。而不是这样做,安排一个作业——一个脚本——它包括:

git fetch && git merge --ff-only && exec <path-to-script>

这个脚本可以保存在同一个存储库中。它是一个单独的脚本,它的工作是就地更新——如果没有什么可做的,它是无操作的(它说&;Already up to date.&;然后退出(0 = success),然后运行另一个脚本,不管它是否更新。这提供了一个清晰的目的分离:一个脚本更新;一个脚本运行;没有自我更新和哎呀,现在我必须退出,因为我的代码可能是不同的奇怪组合。

请注意,将--quiet添加到git merge --ff-only中会抑制"已更新"。消息,如果您的cron版本在有输出时通过电子邮件将输出发送给您,这可能会有所帮助。(如果您的cron版本不能执行此操作,则可能应该将其升级到具有此功能的版本。)所以你可能想要:

git fetch && git merge --ff-only --quiet && exec <path-to-script>

取后合并是git pull默认做的,但git pull是一个由人运行的程序。Git将它的各种程序分为所谓的porcelainplumbing,其中porcelain命令是用于人类的命令,而plumbing命令是用于编写脚本的命令。Git在这里的划分非常不完善:有些命令同时是管道瓷器,并且有一些品种缺失(例如,git log是瓷器,但它所做的一些事情没有管道命令)-但在某种程度上,坚持这种模式通常是明智的。

如果它可能有用,这里是我现在使用的python脚本。我在commit之后立即从vim调用它。

#!/bin/python3
"""
This script syncs development -> production branches
Both directories are connected to the same repository
Assume projectP (for production) and projectD (for development)
"""
####################################################
# Modules
####################################################
import git
####################################################
# Globals
####################################################
theProjectD = "path_to_projectD"
theProjectP = "path_to_projectP"
####################################################
# Code
####################################################
# push & merge develop to main from the develop directory
repo = git.Repo(theProjectD)
repo.remotes.origin.push()
repo.git.checkout('main')
repo.git.merge('develop')
repo.remotes.origin.push()
repo.git.checkout('develop')
# fetch latest version of main in the production directory
repo = git.Repo(theProjectP)
repo.remotes.origin.fetch()
repo.remotes.origin.pull()

最新更新