git自动同步obsidian

背景

入坑obsidian做笔记有一年多了,obsidian哪里都好,就是同步稍显麻烦,图片开了个阿里的oss,搭建了图床,算初步解决。数据同步方案折腾了一大堆,最后还是回到了git。平平淡淡才是真啊。但是每天手动提交,还得写上对笔记来说没那么重要的commit message,多少有点浪费时间。一时半会还行,时间久了还真是有些烦人。

解决方案

python + git + 批处理

GitPython

GitPython允许我们使用git命令来操作git仓库

安装

bash 复制代码
pip install gitpython

封装一个GitSync

python 复制代码
import git

class GitSync():
    def __init__(self, rep_path):
        log.info("rep_path:%s" % rep_path)
        # 判断rep_path是否为Path对象
        if not isinstance(rep_path, Path):
            log.error("rep_path is not Path object")
            raise Exception("rep_path is not Path object")
        # 判断rep_path是否为git仓库
        if not Path(rep_path).joinpath(".git").exists():
            log.error("not git repository")
            raise Exception("not git repository")
        self.rep_path = str(rep_path)
        self.repo = git.Repo(rep_path)

    def check_status(self):
        status = self.repo.git.status()
        if "nothing to commit, working tree clean" in status:
            return True
        else:
            return False

    def auto_commit(self):
        self.repo.git.add(".")
        # 获取当前时间
        now = datetime.now()
        # 格式化时间
        now = now.strftime("%Y-%m-%d %H:%M:%S")
        self.repo.git.commit("-m", "auto commit at %s" % now)
        self.repo.git.push()
        log.info("auto commit success")

    def pull(self):
        # 判断拉取是否存在冲突
        try:
            self.repo.git.pull()
            log.info("pull success")
            return True
        except git.exc.GitCommandError as e:
            log.error(e)
            log.error("pull error")
            return False

    def push(self):
        self.repo.git.push()
        log.info("push success")

为了扩展和方便使用,我们引入命令行,没有传入则使用当前路径作为git仓库

python 复制代码
import argparse

if __name__ == '__main__':
    # 创建一个ArgumentParser对象
    parser = argparse.ArgumentParser(description="git auto commit tool")
    parser.add_argument("--rep", type=str, default="", help="path of repository")
    # 解析命令行参数
    args = parser.parse_args()
    if args.rep:
        rep_path = Path(args.rep)
    else:
        rep_path = Path(__file__).parent.absolute()

搭配批处理

bat 复制代码
D:\dev\Anaconda\pythonw.exe D:\code\gitee\obsidian\git自动提交.py
pause

这里介绍一下pythonw

pythonw 是 Python 安装过程中在 Windows 系统上安装的一个可执行文件,它的作用与 python 类似,但有一些关键的区别:

  1. 无控制台窗口 :当你运行 pythonw.exe 时,它不会创建一个新的控制台窗口来显示输出或错误信息。这对于 GUI 应用程序或那些你不希望用户看到控制台窗口的脚本非常有用。
  2. 图形界面应用程序pythonw 通常用于运行没有控制台窗口的 Python GUI 应用程序。例如,使用 Tkinter 或 PyQt 等库创建的应用程序。
  3. 后台运行 :由于没有控制台窗口,使用 pythonw 运行的脚本适合作为后台进程运行,不会干扰用户的其他操作。
  4. 脚本运行 :如果你有一个 Python 脚本,你希望它在没有控制台窗口的情况下运行,你可以双击该脚本文件,或者在开始菜单中选择它,Python 会使用 pythonw 来运行它。
  5. 环境变量 :在 Windows 上,可以通过设置环境变量 PYTHONW_DEFAULT 来让双击 .py 文件时默认使用 pythonw.exe 运行。

这样我们可以将脚本放置在仓库根目录,并发送到桌面快捷方式,双击则可以自动同步并提交。如果有多台电脑,同步起来也异常方便。

完整代码

python 复制代码
import argparse
import git
import logging as log
from pathlib import Path
from datetime import datetime

log.basicConfig(level=log.INFO, format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')


class GitSync():
    def __init__(self, rep_path):
        log.info("rep_path:%s" % rep_path)
        # 判断rep_path是否为Path对象
        if not isinstance(rep_path, Path):
            log.error("rep_path is not Path object")
            raise Exception("rep_path is not Path object")
        # 判断rep_path是否为git仓库
        if not Path(rep_path).joinpath(".git").exists():
            log.error("not git repository")
            raise Exception("not git repository")
        self.rep_path = str(rep_path)
        self.repo = git.Repo(rep_path)

    def check_status(self):
        status = self.repo.git.status()
        if "nothing to commit, working tree clean" in status:
            return True
        else:
            return False

    def auto_commit(self):
        self.repo.git.add(".")
        # 获取当前时间
        now = datetime.now()
        # 格式化时间
        now = now.strftime("%Y-%m-%d %H:%M:%S")
        self.repo.git.commit("-m", "auto commit at %s" % now)
        self.repo.git.push()
        log.info("auto commit success")

    def pull(self):
        # 判断拉取是否存在冲突
        try:
            self.repo.git.pull()
            log.info("pull success")
            return True
        except git.exc.GitCommandError as e:
            log.error(e)
            log.error("pull error")
            return False

    def push(self):
        self.repo.git.push()
        log.info("push success")


if __name__ == '__main__':
    # 创建一个ArgumentParser对象
    parser = argparse.ArgumentParser(description="git auto commit tool")
    parser.add_argument("--rep", type=str, default="", help="path of repository")
    # 解析命令行参数
    args = parser.parse_args()
    if args.rep:
        rep_path = Path(args.rep)
    else:
        rep_path = Path(__file__).parent.absolute()
    sync = GitSync(rep_path)
    nothing_status = sync.check_status()
    if nothing_status:
        log.info("nothing to commit, working tree clean")
    else:
        res = sync.pull()
        if not res:
            log.error("pull error")
            raise Exception("pull error")
        sync.auto_commit()
相关推荐
蜡笔小新星20 分钟前
Python Kivy库学习路线
开发语言·网络·经验分享·python·学习
篝火悟者34 分钟前
问题-python-运行报错-SyntaxError: Non-UTF-8 code starting with ‘\xd5‘ in file 汉字编码问题
开发语言·python
hakesashou1 小时前
python如何比较字符串
linux·开发语言·python
_.Switch2 小时前
Python机器学习模型的部署与维护:版本管理、监控与更新策略
开发语言·人工智能·python·算法·机器学习
int WINGsssss2 小时前
Git使用
git
Hoper.J2 小时前
PyTorch 模型保存与加载的三种常用方式
人工智能·pytorch·python
弱冠少年2 小时前
websockets库使用(基于Python)
开发语言·python·numpy
技术无疆3 小时前
【Python】Streamlit:为数据科学与机器学习打造的简易应用框架
开发语言·人工智能·python·深度学习·神经网络·机器学习·数据挖掘
羊小猪~~3 小时前
机器学习/数据分析--用通俗语言讲解时间序列自回归(AR)模型,并用其预测天气,拟合度98%+
人工智能·python·机器学习·数据挖掘·数据分析·回归·时序数据库
用户0760530354383 小时前
Git Revert:安全移除错误提交的方式
git