【发布时间】:2021-05-17 19:18:54
【问题描述】:
我已经开始使用 gitHub 来管理每天在我的工作站上运行的生产脚本的开发过程(通过 cron)。
确保最新有效生产版本运行的一种方法是在运行目标脚本之前在生产目录中运行git checkout。我想知道它是否可以在生产脚本中完成(即检查这是不是最新版本,如果不是,git checkout,如果是,什么都不做并运行)
【问题讨论】:
标签: python git github integration
我已经开始使用 gitHub 来管理每天在我的工作站上运行的生产脚本的开发过程(通过 cron)。
确保最新有效生产版本运行的一种方法是在运行目标脚本之前在生产目录中运行git checkout。我想知道它是否可以在生产脚本中完成(即检查这是不是最新版本,如果不是,git checkout,如果是,什么都不做并运行)
【问题讨论】:
标签: python git github integration
是当然可能这样做,例如(未经测试):
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>
此脚本可以存在于同一个存储库中。它是一个单独的脚本,它的工作是就地更新——如果没有什么可做的,它就是一个无操作(它说“已经是最新的。”然后退出 0 = 成功)——然后运行另一个脚本,不管它是否更新。这提供了明确的目的分离:一个脚本更新;一个脚本运行;没有自我更新和糟糕的组合,现在我不得不退出,因为可能我的代码不同。
请注意,将--quiet 添加到git merge --ff-only 会取消显示“已经是最新的”。消息,如果您的 cron 版本在有输出时通过电子邮件将输出发送给您,这可能会有所帮助。 (如果您的 cron 版本 不 这样做,它可能应该升级到这样做的版本。)所以你可能真的想要:
git fetch && git merge --ff-only --quiet && exec <path-to-script>
fetch 和 merge 是 git pull 默认执行的操作,但 git pull 是一个旨在由人类运行的程序。 Git 将其各种程序分为所谓的 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()
【讨论】: