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()
相关推荐
IT北辰2 分钟前
python+MySQL+HTML实现产品管理系统
python·mysql·html
拉姆哥的小屋18 分钟前
超精密工件小孔几何尺寸测量:自动化解决方案
运维·人工智能·python·自动化
花千树-01026 分钟前
LangChain教程 - Agent -之 REACT_DOCSTORE
python·机器学习·langchain·pdf·prompt·aigc·embedding
pk_xz12345632 分钟前
使用 Flask 进行简单服务器改造的详细步骤和代码
服务器·python·flask
Nelson_hehe42 分钟前
五子棋小游戏-简单开发版
python·小游戏·pygame·五子棋
go54631584651 小时前
多时间尺度的配电网深度强化学习无功优化策略的Python示例代码框架
python·深度学习·ui
互联网搬砖老肖2 小时前
Python开发合并多个PDF文件
java·python·pdf
Tz一号2 小时前
前端 git规范-不同软件(GitHub、Sourcetree、WebStorm)、命令行合并方式下增加 --no-ff的方法
前端·git·github
啥都鼓捣的小yao3 小时前
Python手写机器学习的“线性回归”算法
python·算法·机器学习
agctXY3 小时前
错误记录: git 无法连接到github
git·github