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()
相关推荐
2601_962293791 小时前
OCRmyPDF批处理脚本:使用Python自动化复杂OCR任务
python·自动化·批处理脚本·ocrmypdf·ocr任务
Java后端的Ai之路2 小时前
20、Python - 备忘录模式
开发语言·人工智能·python·外观模式·备忘录模式
2601_962077713 小时前
基于Python与NLP的新闻事件信息抽取实战:从NER到时空标准化
python·nlp·transformers·spacy·新闻事件抽取
JavaPub-rodert3 小时前
LangChain 从入门到 Agent 实战:用 Python 搭建一个真正能调用工具和知识库的 AI 助手
人工智能·python·langchain
郝学胜-神的一滴4 小时前
Qt 高级编程 045:坐标体系深度实战
开发语言·c++·windows·python·qt·程序人生
m0_380743875 小时前
给 OpenAI API 调用加上模型切换:GPT-5.1 和 Codex 的配置实践
人工智能·python·gpt
2601_962297485 小时前
在python3中、下列输出变量a的正确写法是_2020超星大数据Python免费答案
数据结构·python·算法·编程·字符串操作
“AI国潮设计-小江”5 小时前
Python实战 | SDXL精准控制“普宁英歌舞×星空蛋糕”IP落地,附核心Prompt与商用授权思路
开发语言·人工智能·python·prompt·aigc
公爵爱学习5 小时前
无人机视觉识别前序-Linux-YOLO安装
python·yolo·计算机视觉·conda·无人机
2601_962295335 小时前
使用python实现一个浏览器自动化的脚本
python·脚本·rpa·浏览器自动化·操作