使用git推送和拉我的conda环境

oku*_*oub 4 git environment version-control github conda

我的项目有一个git repo。我conda经常更改环境,因此我希望我的仓库可以跟踪环境的变化,并能够推送最新的更新并将其拉入另一台计算机。可能吗?我搜索并找到了几种解决方案(例如https://tdhopper.com/blog/my-python-environment-workflow-with-conda/),但是没有一个提供自动的变更跟踪。

意思是,我想将我在环境中所做的任何更改都包含在项目的存储库中。就像添加新软件包等。这样,当我在另一台计算机上git pull它时,新软件包也将被提取并添加到环境中。

Mar*_*awk 5

在 Conda 中,您可以从文件创建虚拟环境并将环境导出到文件,该文件可以包含在您的 git 存储库中。如果您在另一台机器上拉下您的存储库或删除您的环境,您可以运行:

conda env create -f=env.yml
Run Code Online (Sandbox Code Playgroud)

当您对环境进行更改时,请在添加/提交之前运行导出:

conda env export > env.yml
Run Code Online (Sandbox Code Playgroud)


kho*_*hin 5

我使用git hooks使conda环境自动更新。您可以在此处获得有关git hooks的更多信息。

这里的想法是有两个git钩子:

  • 一个用来检测本地conda环境是否发生了更改,如果是,请使用更新的env.yml文件创建一个新提交(我为此选择了一个预推钩子)。
  • 一个在拉动后检测到env.yml文件中的更改的文件(即,远程env.yml与本地文件不同并被合并,我为此选择了一个合并后钩子)

如文档中所述,当启动git存储库时,将创建一个文件夹.git / hooks并用示例脚本填充。要使用其中之一,您只需编辑文件,将其重命名以删除其扩展名(.sample),并确保其可执行。

注意:我使用zsh作为shell,但是bash中的脚本应该是相同的(如果没有,请注释),您只需要更改shebang行即可。


预推钩

  • 重写.git / hooks中已经存在的pre-push.sample文件(替换为conda环境的名称):<ENV_NAME>
#!/usr/bin/env zsh

echo "\n==================== pre-push hook ===================="

# Export conda environment to yaml file
conda env export -n <ENV_NAME> env.yml

# Check if new environment file is different from original 
git diff --exit-code --quiet env.yml 

# If new environment file is different, commit it
if [[ $? -eq 0 ]]; then
    echo "Conda environment not changed. No additional commit."
else
    echo "Conda environment changed. Commiting new env.yml"
    git add env.yml
    git commit -m "Updating conda environment"
    echo 'You need to push again to push additional "Updating conda environment" commit.'
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)
  • 删除其扩展名.sample,并在必要时使其可执行(chmod u+x pre-push

合并后挂钩

#!/usr/bin/env zsh

echo "\n==================== post-merge hook ===================="

changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"

check_run() {
    echo "$changed_files" | grep --quiet "$1" && eval "$2"
}

echo "Have to update the conda environment"
check_run env.yml "conda env update --file env.yml"
Run Code Online (Sandbox Code Playgroud)
  • 并使其可执行(chmod u+x post-merge

现在会发生什么?

  • 推送时,如果conda环境已更改,将显示一条消息,指示您必须再次推送以使用更新的env.yml推送提交
  • 拉动时,如果拉出的env.yml与本地env.yml不同,则conda将使用新拉出的env.yml更新本地环境。

局限性

  • 如果环境在本地更改,则可以看到更新的env.yml不会自动推送到远程。我从git commit的pre-push hook中接受了建议。
  • 当前,拉动后conda环境的更新使用的是合并后钩子。例如,我不知道如何处理rebase
  • 这里没有git专家,也许有更适合这些任务的钩子。
  • 我注意到env.yml中的prefix节提供了本地计算机上环境文件夹的路径。经过一些测试,一切似乎都运行良好,但是我不知道在各种机器上进行开发时是否可能以某种方式造成冲突。

因此,非常欢迎评论,更正和改进意见!