如何将新文件夹推送到 GitHub 并在必要时自动变基?

How to push a new folder to GitHub and rebase automatically if necessary?

场景

所以在我的例子中,我有一个 GitHub 操作工作流,运行 对每个分支的每个推送分别进行一些测试。这些测试会生成一份 HTML 报告,可以将其部署为静态网站。我想使用 GitHub 页面来部署这些报告,这样我的团队总能在工作流 运行 完成后立即查看它们。

由于 GitHub 页面由常规 git 存储库支持,因此我总是需要在我的工作流定义中提交新报告并将其推送到该存储库。我还计划有一个单独的文件夹,其中包含每个工作流 运行 的 HTML 报告,以使新推送的报告文件夹彼此完全独立。

问题

由于多个管道可能会同时 运行,因此多个 branches/workflow 运行 可能会尝试同时在同一存储库上发布他们的报告。 这可能会导致竞争条件,即两个不同的工作流试图同时推送,而一个将失败,因为它不再是最新的。 实际上,这些推送的报告彼此完全独立,因为它们会推送完全没有关联的新文件夹。

问题

是否可以将一个全新的文件夹推送到 GitHub 存储库(或一般的任何 git 存储库),因此它总是会成功,因为永远不会发生冲突?是否有一些专用的 git 命令可以“无限地”变基直到它起作用或发生冲突?

我假设您的 github 操作是这样的:

# generate your html report here
exec ./bin/generate_report

# commit
git add .
git commit -m "auto generated at `date`"

git push origin master

现在您担心多个 github 操作可能会同时 运行,这可能会造成竞争条件,并且您的某些推送会因为没有相同的父提交而被拒绝。

为了解决这个问题,您可以使用 rebase 并循环它直到它成功推送,如下所示:

# create branch name with unix timestamp
BRANCH_NAME="report-`date +%s`"

git branch $BRANCH_NAME
git checkout $BRANCH_NAME

# generate your html report here
exec ./bin/generate_report

# commit
git add .
git commit -m "auto generated $BRANCH_NAME"

# push to branch as backup
git push -u origin $BRANCH_NAME

# 'infinitely' pull,rebase,push until push is successful
PUSH_SUCCESS=0
while [ $PUSH_SUCCESS -eq 0 ]; do
    git checkout master
    git pull origin master
    git checkout $BRANCH_NAME
    git rebase master
    git checkout master
    git merge --ff-only $BRANCH_NAME
    git push origin master
    if [ $? -eq 0 ]; then
        PUSH_SUCCESS=1
    fi
done

有了这个,如果在 pull 和 rebase 之间的时间里,远程的 master 分支已经改变了(例如:通过其他异步操作),你将重试(pull-rebase-push)直到成功。

你也可以通过rebase失败退出来进行改进,这样就不会因为某些不可预见的情况rebase失败时无限循环。