Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°

πŸš€ Obsidian синхронизация бСсплатно: ПолноС руководство ΠΏΠΎ настройкС автоматичСской синхронизации Ρ‡Π΅Ρ€Π΅Π· GitHub

πŸš€ Obsidian синхронизация бСсплатно: ПолноС руководство ΠΏΠΎ настройкС автоматичСской синхронизации Ρ‡Π΅Ρ€Π΅Π· GitHub

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅ для LINUX. Windows 11 Π½ΠΈΠΆΠ΅.

Obsidian синхронизация бСсплатно β€” это Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ! Π’ этом ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠΌ руководствС ΠΌΡ‹ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ, ΠΊΠ°ΠΊ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½ΡƒΡŽ систСму автоматичСской синхронизации Π·Π°ΠΌΠ΅Ρ‚ΠΎΠΊ Obsidian ΠΌΠ΅ΠΆΠ΄Ρƒ устройствами Π±Π΅Π· ΠΏΠ»Π°Ρ‚Π½ΠΎΠΉ подписки Obsidian Sync. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ GitHub ΠΈ простыС скрипты, Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ½ΡƒΡŽ Π±Π΅ΡΠΏΠ»Π°Ρ‚Π½ΡƒΡŽ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ Obsidian с автоматичСскими Ρ€Π΅Π·Π΅Ρ€Π²Π½Ρ‹ΠΌΠΈ копиями.

Π§Ρ‚ΠΎ Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅:

- βœ… **АвтоматичСская синхронизация** ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 15 ΠΌΠΈΠ½ΡƒΡ‚

- βœ… **ГрафичСскоС мСню управлСния** с увСдомлСниями

- βœ… **ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅** всСх ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ

- βœ… **Π Π΅Π·Π΅Ρ€Π²Π½ΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅** Π² ΠΎΠ±Π»Π°ΠΊΠ΅ GitHub

- βœ… **ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ статуса** ΠΈ статистика

- βœ… **ΠŸΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ синхронизация** ΠΏΡ€ΠΈ нСобходимости

ВрСбования ΠΊ систСмС

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ систСма

- Linux (Ubuntu, Debian, Zorin OS, Linux Mint)

- macOS (с нСбольшими модификациями)

- Windows (Ρ‡Π΅Ρ€Π΅Π· WSL)

НСобходимыС ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹

# ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ для синхронизации
sudo apt update
sudo apt install -y git curl wget nano cron

# ΠŸΠ°ΠΊΠ΅Ρ‚Ρ‹ для графичСского интСрфСйса
sudo apt install -y zenity notify-send libnotify-bin

# Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹
sudo apt install -y tree htop

ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° GitHub рСпозитория

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ рСпозитория

- **Π’ΠΎΠΉΠ΄ΠΈΡ‚Π΅ Π² GitHub** ΠΈ создайтС Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹ΠΉ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ

- **НазваниС**: `obsidian-notes` (ΠΈΠ»ΠΈ любоС Π΄Ρ€ΡƒΠ³ΠΎΠ΅)

- **ОписаниС**: "Π›ΠΈΡ‡Π½Ρ‹Π΅ Π·Π°ΠΌΠ΅Ρ‚ΠΊΠΈ Obsidian"

- **ΠŸΡ€ΠΈΠ²Π°Ρ‚Π½ΠΎΡΡ‚ΡŒ**: Private (для ΠΊΠΎΠ½Ρ„ΠΈΠ΄Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ)

Настройка SSH ΠΊΠ»ΡŽΡ‡Π΅ΠΉ

# Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ SSH ΠΊΠ»ΡŽΡ‡ для GitHub
ssh-keygen -t ed25519 -C "your-email@example.com" -f ~/.ssh/github_obsidian

# ДобавляСм ΠΊΠ»ΡŽΡ‡ Π² SSH Π°Π³Π΅Π½Ρ‚
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/github_obsidian

# Π’Ρ‹Π²ΠΎΠ΄ΠΈΠΌ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ для добавлСния Π² GitHub
cat ~/.ssh/github_obsidian.pub

Π‘ΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ Π²Ρ‹Π²ΠΎΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΈ Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ SSH ΠΊΠ»ΡŽΡ‡ Π² GitHub:

- ΠŸΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ Π² Settings β†’ SSH and GPG keys β†’ New SSH key

- Π’ΡΡ‚Π°Π²ΡŒΡ‚Π΅ скопированный ΠΊΠ»ΡŽΡ‡

Настройка SSH ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ SSH
nano ~/.ssh/config

Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΠΌΠΎΠ΅ Ρ„Π°ΠΉΠ»Π°:

Host github-obsidian
    HostName github.com
    User git
    IdentityFile ~/.ssh/github_obsidian
    IdentitiesOnly yes

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Obsidian Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°

ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° ΠΏΠ°ΠΏΠΊΠΈ с Π·Π°ΠΌΠ΅Ρ‚ΠΊΠ°ΠΌΠΈ

# ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² ΠΏΠ°ΠΏΠΊΡƒ с Π·Π°ΠΌΠ΅Ρ‚ΠΊΠ°ΠΌΠΈ Obsidian
cd "$HOME/Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹/Obsidian Vault"

# Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Git Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ
git init

# НастраиваСм Git ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ
git config user.name "Π’Π°ΡˆΠ΅ Имя"
git config user.email "your-email@example.com"

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ .gitignore для ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ слуТСбных Ρ„Π°ΠΉΠ»ΠΎΠ²
nano .gitignore

Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΠΌΠΎΠ΅ .gitignore:

# Obsidian слуТСбныС Ρ„Π°ΠΉΠ»Ρ‹
.obsidian/workspace*
.obsidian/hotkeys.json
.obsidian/appearance.json
.obsidian/graph.json

# БистСмныС Ρ„Π°ΠΉΠ»Ρ‹
.DS_Store
Thumbs.db
*.tmp
*.temp

# ΠšΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹
*conflict*

ΠŸΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½Π°Ρ настройка рСпозитория

# ДобавляСм ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ
git remote add origin git@github-obsidian:ваш-username/obsidian-notes.git

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠΈΡ‚
git add .
git commit -m "Initial commit: Obsidian vault setup"

# ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ Π² GitHub
git branch -M main
git push -u origin main

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ систСмы автоматичСской синхронизации

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ°ΠΏΠΊΡƒ для скриптов
mkdir -p ~/scripts/obsidian-sync
cd ~/scripts/obsidian-sync

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ структуру Ρ„Π°ΠΉΠ»ΠΎΠ²
touch obsidian-sync.sh
touch force-sync.sh
touch status.sh
touch quick-menu.sh
touch advanced-menu.sh
touch sync.log

Основной скрипт синхронизации

nano ~/scripts/obsidian-sync/obsidian-sync.sh

ΠŸΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ скрипта:

#!/bin/bash

# Obsidian Auto-Sync Script
# АвтоматичСская синхронизация Π·Π°ΠΌΠ΅Ρ‚ΠΎΠΊ с GitHub

# ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ
OBSIDIAN_PATH="$HOME/Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹/Obsidian Vault"
LOG_FILE="$HOME/scripts/obsidian-sync/sync.log"
HOSTNAME=$(hostname)

# Ѐункция логирования
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# Ѐункция ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ
notify() {
    local message="$1"
    local icon="$2"

    # Desktop ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅
    if command -v notify-send >/dev/null 2>&1; then
        notify-send "Obsidian Sync" "$message" --icon="$icon" --expire-time=5000
    fi

    # Π›ΠΎΠ³ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅
    log "NOTIFICATION: $message"
}

# ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° сущСствования ΠΏΠ°ΠΏΠΊΠΈ
if [ ! -d "$OBSIDIAN_PATH" ]; then
    log "ERROR: Папка Obsidian нС найдСна: $OBSIDIAN_PATH"
    exit 1
fi

cd "$OBSIDIAN_PATH"

log "=== Начало синхронизации ==="

# ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ статус Git
if [ ! -d ".git" ]; then
    log "ERROR: Git Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ Π½Π΅ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½"
    exit 1
fi

# ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ измСнСния с сСрвСра
log "ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ измСнСния с GitHub..."
git fetch origin main 2>&1 | tee -a "$LOG_FILE"

# ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Ρ‹
REMOTE_CHANGES=$(git rev-list HEAD..origin/main --count 2>/dev/null || echo "0")
LOCAL_CHANGES=$(git status --porcelain | wc -l)

log "Π£Π΄Π°Π»Π΅Π½Π½Ρ‹Ρ… ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ: $REMOTE_CHANGES, Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ…: $LOCAL_CHANGES"

# Если Π΅ΡΡ‚ΡŒ ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Π΅ измСнСния, сливаСм ΠΈΡ…
if [ "$REMOTE_CHANGES" -gt 0 ]; then
    log "ΠŸΡ€ΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Π΅ измСнСния..."
    git pull origin main 2>&1 | tee -a "$LOG_FILE"

    if [ $? -eq 0 ]; then
        notify "πŸ“₯ ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ $REMOTE_CHANGES ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ с сСрвСра" "dialog-information"
    else
        log "ERROR: Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ"
        notify "❌ Ошибка синхронизации" "dialog-error"
        exit 1
    fi
fi

# Если Π΅ΡΡ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ измСнСния, отправляСм ΠΈΡ…
if [ "$LOCAL_CHANGES" -gt 0 ]; then
    log "БохраняСм Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ измСнСния..."

    # ДобавляСм всС измСнСния
    git add . 2>&1 | tee -a "$LOG_FILE"

    # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΊΠΎΠΌΠΌΠΈΡ‚ с автоматичСским сообщСниСм
    COMMIT_MSG="Auto-sync from $HOSTNAME: $(date '+%Y-%m-%d %H:%M:%S')"
    git commit -m "$COMMIT_MSG" 2>&1 | tee -a "$LOG_FILE"

    # ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ Π½Π° сСрвСр
    log "ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ измСнСния Π½Π° сСрвСр..."
    git push origin main 2>&1 | tee -a "$LOG_FILE"

    if [ $? -eq 0 ]; then
        notify "πŸ“€ Obsidian Sync - ΠžΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ $LOCAL_CHANGES ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ" "dialog-information"
    else
        log "ERROR: Ошибка ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ"
        notify "❌ Ошибка ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Π½Π° сСрвСр" "dialog-error"
        exit 1
    fi
fi

# Если Π½Π΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
if [ "$REMOTE_CHANGES" -eq 0 ] && [ "$LOCAL_CHANGES" -eq 0 ]; then
    log "ИзмСнСний Π½Π΅Ρ‚, синхронизация Π½Π΅ трСбуСтся"
fi

log "=== Бинхронизация Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° ==="

Π‘ΠΊΡ€ΠΈΠΏΡ‚ ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ синхронизации

nano ~/scripts/obsidian-sync/force-sync.sh

Код скрипта:

#!/bin/bash

# Force Sync Script - ΠŸΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ синхронизация
# Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΡ€ΠΈ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Π°Ρ… ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°Ρ…

OBSIDIAN_PATH="$HOME/Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹/Obsidian Vault"
LOG_FILE="$HOME/scripts/obsidian-sync/sync.log"
BACKUP_DIR="$HOME/scripts/obsidian-sync/backups"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] FORCE: $1" | tee -a "$LOG_FILE"
}

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ°ΠΏΠΊΡƒ для Ρ€Π΅Π·Π΅Ρ€Π²Π½Ρ‹Ρ… ΠΊΠΎΠΏΠΈΠΉ
mkdir -p "$BACKUP_DIR"

cd "$OBSIDIAN_PATH"

log "=== Начало ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ синхронизации ==="

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ€Π΅Π·Π΅Ρ€Π²Π½ΡƒΡŽ копию Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
BACKUP_NAME="backup-$(date +%Y%m%d-%H%M%S).tar.gz"
tar -czf "$BACKUP_DIR/$BACKUP_NAME" . 2>/dev/null
log "Π‘ΠΎΠ·Π΄Π°Π½Π° рСзСрвная копия: $BACKUP_NAME"

# БбрасываСм Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ измСнСния
git fetch origin main
git reset --hard origin/main
git clean -fd

log "Π›ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ измСнСния ΡΠ±Ρ€ΠΎΡˆΠ΅Π½Ρ‹ Π΄ΠΎ состояния сСрвСра"

# ЗапускаСм ΠΎΠ±Ρ‹Ρ‡Π½ΡƒΡŽ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ
~/scripts/obsidian-sync/obsidian-sync.sh

log "=== ΠŸΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ синхронизация Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° ==="

Π‘ΠΊΡ€ΠΈΠΏΡ‚ ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π° статуса

nano ~/scripts/obsidian-sync/status.sh

Код скрипта:

#!/bin/bash

# Status Monitor Script - ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ состояния систСмы

OBSIDIAN_PATH="$HOME/Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹/Obsidian Vault"
LOG_FILE="$HOME/scripts/obsidian-sync/sync.log"

cd "$OBSIDIAN_PATH"

echo "πŸ” БВАВУБ OBSIDIAN SYNC"
echo "========================"
echo "πŸ“… ВрСмя: $(date '+%Y-%m-%d %H:%M:%S')"
echo ""

# Git статус
echo "πŸ“Š Git статус:"
git status --short

echo ""
echo "πŸ“ˆ Бтатистика Ρ„Π°ΠΉΠ»ΠΎΠ²:"
echo "   ВсСго .md Ρ„Π°ΠΉΠ»ΠΎΠ²: $(find . -name "*.md" | wc -l)"
echo "   ВсСго ΠΏΠ°ΠΏΠΎΠΊ: $(find . -type d | wc -l)"
echo "   Π Π°Π·ΠΌΠ΅Ρ€ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°: $(du -sh . | cut -f1)"
echo "   ПослСдний ΠΊΠΎΠΌΠΌΠΈΡ‚: $(git log -1 --format='%h - %s (%cr)' 2>/dev/null || echo 'НСт ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΎΠ²')"

echo ""
echo "πŸ”„ Π£Π΄Π°Π»Π΅Π½Π½Ρ‹Π΅ измСнСния:"
git fetch origin >/dev/null 2>&1
REMOTE_CHANGES=$(git rev-list HEAD..origin/main --count 2>/dev/null || echo "0")
LOCAL_CHANGES=$(git status --porcelain | wc -l)

if [ "$REMOTE_CHANGES" -gt 0 ]; then
    echo "   ⚠️  Π•ΡΡ‚ΡŒ $REMOTE_CHANGES ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π½Π° сСрвСрС"
elif [ "$LOCAL_CHANGES" -gt 0 ]; then
    echo "   πŸ“ Π•ΡΡ‚ΡŒ $LOCAL_CHANGES Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ"
else
    echo "   βœ… ΠŸΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ синхронизировано"
fi

echo ""
echo "πŸ“ ПослСдниС записи Π»ΠΎΠ³Π°:"
if [ -f "$LOG_FILE" ]; then
    tail -5 "$LOG_FILE" | sed 's/^/   /'
else
    echo "   Π›ΠΎΠ³ Ρ„Π°ΠΉΠ» Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½"
fi

echo ""
echo "βš™οΈ  Автосинхронизация:"
if crontab -l 2>/dev/null | grep -q "obsidian-sync"; then
    echo "   βœ… НастроСна ΠΈ Π°ΠΊΡ‚ΠΈΠ²Π½Π°"
    echo "   πŸ“… РасписаниС: $(crontab -l | grep obsidian-sync | cut -d' ' -f1-5)"
else
    echo "   ❌ НС настроСна"
fi

ГрафичСский интСрфСйс управлСния

ΠŸΡ€ΠΎΡΡ‚ΠΎΠ΅ мСню управлСния

nano ~/scripts/obsidian-sync/quick-menu.sh

Код мСню:

#!/bin/bash

# Quick Menu - ΠŸΡ€ΠΎΡΡ‚ΠΎΠ΅ графичСскоС мСню

choice=$(zenity --list \
    --title="Obsidian Sync - БыстрыС дСйствия" \
    --text="Π’Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ дСйствиС:" \
    --column="ДСйствиС" \
    --column="ОписаниС" \
    "sync" "πŸ”„ Π‘ΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ сСйчас" \
    "status" "πŸ“Š ΠŸΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ статус" \
    "force" "⚑ ΠŸΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ синхронизация" \
    "log" "πŸ“ ΠŸΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ Π»ΠΎΠ³" \
    "open" "πŸ“‚ ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΏΠ°ΠΏΠΊΡƒ Obsidian" \
    --width=400 --height=300)

case $choice in
    "sync")
        ~/scripts/obsidian-sync/obsidian-sync.sh
        zenity --info --text="Бинхронизация Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π°!" --title="Obsidian Sync"
        ;;
    "status")
        ~/scripts/obsidian-sync/status.sh | zenity --text-info \
            --title="Бтатус Obsidian Sync" \
            --width=600 --height=400 \
            --font="monospace 10"
        ;;
    "force")
        if zenity --question --text="⚠️ Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ?\n\nΠ­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ измСнСния."; then
            ~/scripts/obsidian-sync/force-sync.sh
            zenity --info --text="ΠŸΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ синхронизация Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π°!" --title="Obsidian Sync"
        fi
        ;;
    "log")
        if [ -f "$HOME/scripts/obsidian-sync/sync.log" ]; then
            cat "$HOME/scripts/obsidian-sync/sync.log" | zenity --text-info \
                --title="Π›ΠΎΠ³ Obsidian Sync" \
                --width=600 --height=400 \
                --font="monospace 10"
        else
            zenity --info --text="Π›ΠΎΠ³ Ρ„Π°ΠΉΠ» Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½." --title="ΠžΠ±Ρ‰Π°Ρ информация"
        fi
        ;;
    "open")
        xdg-open "$HOME/Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹/Obsidian Vault"
        ;;
esac

РасписаниС автоматичСской синхронизации

# ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ crontab для рСдактирования
crontab -e

Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ строку для автоматичСской синхронизации ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 15 ΠΌΠΈΠ½ΡƒΡ‚:

*/15 * * * * ~/scripts/obsidian-sync/obsidian-sync.sh

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

 Π’Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ вас Π΅ΡΡ‚ΡŒ полноцСнная систСма автоматичСской синхронизации Π·Π°ΠΌΠ΅Ρ‚ΠΎΠΊ Obsidian с использованиСм GitHub. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π»Π΅Π³ΠΊΠΎ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ синхронизациСй Ρ‡Π΅Ρ€Π΅Π· графичСский интСрфСйс, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ увСдомлСния ΠΎ статусС. НС Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Π»ΠΎΠ³ΠΈ для отслСТивания всСх ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ.

Obsidian синхронизация бСсплатно Π½Π° Windows 11: ПолноС руководство ΠΏΠΎ настройкС автоматичСской синхронизации Ρ‡Π΅Ρ€Π΅Π· GitHub

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅

Obsidian синхронизация бСсплатно Π½Π° Windows 11 β€” это доступная Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π° ΠΏΠ»Π°Ρ‚Π½ΠΎΠΉ подпискС Obsidian Sync! Π’ этом ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠΌ руководствС ΠΌΡ‹ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ, ΠΊΠ°ΠΊ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½ΡƒΡŽ систСму автоматичСской синхронизации Π·Π°ΠΌΠ΅Ρ‚ΠΎΠΊ Obsidian ΠΌΠ΅ΠΆΠ΄Ρƒ устройствами Π½Π° Windows 11 Π±Π΅Π· Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π·Π°Ρ‚Ρ€Π°Ρ‚. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ GitHub, PowerShell ΠΈ ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊ Π·Π°Π΄Π°Ρ‡ Windows, Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ½ΡƒΡŽ Π±Π΅ΡΠΏΠ»Π°Ρ‚Π½ΡƒΡŽ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ Obsidian с автоматичСскими Ρ€Π΅Π·Π΅Ρ€Π²Π½Ρ‹ΠΌΠΈ копиями.

Π§Ρ‚ΠΎ Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅:

- βœ… **АвтоматичСская синхронизация** ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 15 ΠΌΠΈΠ½ΡƒΡ‚

- βœ… **ГрафичСскиС увСдомлСния Windows** ΠΎ статусС синхронизации

- βœ… **PowerShell скрипты** для управлСния

- βœ… **ΠŸΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊ Π·Π°Π΄Π°Ρ‡ Windows** для Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ

- βœ… **Π Π΅Π·Π΅Ρ€Π²Π½ΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅** Π² ΠΎΠ±Π»Π°ΠΊΠ΅ GitHub

- βœ… **ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ статуса** ΠΈ подробная статистика

- βœ… **ГрафичСскоС мСню управлСния** Ρ‡Π΅Ρ€Π΅Π· Windows Forms

ВрСбования ΠΊ систСмС

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ систСма

- Windows 11 (любая рСдакция)

- Windows 10 (с обновлСниями)

НСобходимоС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ΅ обСспСчСниС

1. Git для Windows

# Π‘ΠΊΠ°Ρ‡Π°ΠΉΡ‚Π΅ Git с ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ сайта
# https://git-scm.com/download/win
# Или установитС Ρ‡Π΅Ρ€Π΅Π· winget
winget install Git.Git

2. PowerShell 7 (рСкомСндуСтся)

# Установка Ρ‡Π΅Ρ€Π΅Π· winget
winget install Microsoft.PowerShell

# Или скачайтС с GitHub
# https://github.com/PowerShell/PowerShell/releases

3. Windows Terminal (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ)

# Установка Ρ‡Π΅Ρ€Π΅Π· Microsoft Store ΠΈΠ»ΠΈ winget
winget install Microsoft.WindowsTerminal

ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° Ρ€Π°Π±ΠΎΡ‡Π΅ΠΉ срСды

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ структуры ΠΏΠ°ΠΏΠΎΠΊ

# ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ PowerShell ΠΎΡ‚ ΠΈΠΌΠ΅Π½ΠΈ администратора
# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ°ΠΏΠΊΡƒ для скриптов
New-Item -ItemType Directory -Path "$env:USERPROFILE\Scripts\ObsidianSync" -Force

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ°ΠΏΠΊΡƒ для Π»ΠΎΠ³ΠΎΠ²
New-Item -ItemType Directory -Path "$env:USERPROFILE\Scripts\ObsidianSync\Logs" -Force

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ°ΠΏΠΊΡƒ для Ρ€Π΅Π·Π΅Ρ€Π²Π½Ρ‹Ρ… ΠΊΠΎΠΏΠΈΠΉ
New-Item -ItemType Directory -Path "$env:USERPROFILE\Scripts\ObsidianSync\Backups" -Force

# ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² Ρ€Π°Π±ΠΎΡ‡ΡƒΡŽ ΠΏΠ°ΠΏΠΊΡƒ
Set-Location "$env:USERPROFILE\Scripts\ObsidianSync"

Настройка ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊΠΈ выполнСния PowerShell

# Π Π°Π·Ρ€Π΅ΡˆΠ°Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… скриптов
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

# ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊΡƒ
Get-ExecutionPolicy -List

ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° GitHub рСпозитория

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ рСпозитория

- **Π’ΠΎΠΉΠ΄ΠΈΡ‚Π΅ Π² GitHub** ΠΈ создайтС Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹ΠΉ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ

- **НазваниС**: `obsidian-notes-windows`

- **ОписаниС**: "Π›ΠΈΡ‡Π½Ρ‹Π΅ Π·Π°ΠΌΠ΅Ρ‚ΠΊΠΈ Obsidian - Windows 11"

- **ΠŸΡ€ΠΈΠ²Π°Ρ‚Π½ΠΎΡΡ‚ΡŒ**: Private (для ΠΊΠΎΠ½Ρ„ΠΈΠ΄Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ)

Настройка SSH ΠΊΠ»ΡŽΡ‡Π΅ΠΉ Π² Windows

# ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ OpenSSH
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'

# УстанавливаСм OpenSSH Client Ссли Π½ΡƒΠΆΠ½ΠΎ
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ°ΠΏΠΊΡƒ .ssh Ссли Π΅Ρ‘ Π½Π΅Ρ‚
if (!(Test-Path "$env:USERPROFILE\.ssh")) {
    New-Item -ItemType Directory -Path "$env:USERPROFILE\.ssh"
}

# Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ SSH ΠΊΠ»ΡŽΡ‡
ssh-keygen -t ed25519 -C "your-email@example.com" -f "$env:USERPROFILE\.ssh\github_obsidian"

# ЗапускаСм SSH Agent
Start-Service ssh-agent
Set-Service -Name ssh-agent -StartupType Manual

# ДобавляСм ΠΊΠ»ΡŽΡ‡ Π² SSH Agent
ssh-add "$env:USERPROFILE\.ssh\github_obsidian"

# Π’Ρ‹Π²ΠΎΠ΄ΠΈΠΌ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ для GitHub
Get-Content "$env:USERPROFILE\.ssh\github_obsidian.pub"

Настройка SSH ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ SSH config Ρ„Π°ΠΉΠ»
@"
Host github-obsidian
    HostName github.com
    User git
    IdentityFile ~/.ssh/github_obsidian
    IdentitiesOnly yes
"@ | Out-File -FilePath "$env:USERPROFILE\.ssh\config" -Encoding UTF8

Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ SSH ΠΊΠ»ΡŽΡ‡ Π² GitHub:

- ΠŸΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ Π² Settings β†’ SSH and GPG keys β†’ New SSH key

- Π’ΡΡ‚Π°Π²ΡŒΡ‚Π΅ содСрТимоС Ρ„Π°ΠΉΠ»Π° `github_obsidian.pub`

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Obsidian Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°

ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° ΠΏΠ°ΠΏΠΊΠΈ с Π·Π°ΠΌΠ΅Ρ‚ΠΊΠ°ΠΌΠΈ

# ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² ΠΏΠ°ΠΏΠΊΡƒ Obsidian (стандартный ΠΏΡƒΡ‚ΡŒ)
$ObsidianPath = "$env:USERPROFILE\Documents\Obsidian Vault"
Set-Location $ObsidianPath

# Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Git Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ
git init

# НастраиваСм Git ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ
git config user.name "Π’Π°ΡˆΠ΅ Имя"
git config user.email "your-email@example.com"

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ .gitignore
@"
# Obsidian слуТСбныС Ρ„Π°ΠΉΠ»Ρ‹
.obsidian/workspace*
.obsidian/hotkeys.json
.obsidian/appearance.json
.obsidian/graph.json
.obsidian/plugins/*/data.json

# Windows систСмныС Ρ„Π°ΠΉΠ»Ρ‹
Thumbs.db
Desktop.ini
*.tmp
*.temp
~$*

# ΠšΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹
*conflict*
*.orig
"@ | Out-File -FilePath ".gitignore" -Encoding UTF8

# ДобавляСм ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ
git remote add origin git@github-obsidian:ваш-username/obsidian-notes-windows.git

# ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠΈΡ‚
git add .
git commit -m "Initial commit: Obsidian vault setup on Windows 11"

# ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ Π² GitHub
git branch -M main
git push -u origin main

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ PowerShell скриптов синхронизации

Основной скрипт синхронизации

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ основной скрипт синхронизации
@'
# ObsidianSync.ps1 - Основной скрипт синхронизации
param(
    [switch]$Force,
    [switch]$Quiet
)

# ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ
$ObsidianPath = "$env:USERPROFILE\Documents\Obsidian Vault"
$LogPath = "$env:USERPROFILE\Scripts\ObsidianSync\Logs"
$LogFile = "$LogPath\sync-$(Get-Date -Format 'yyyy-MM').log"
$ComputerName = $env:COMPUTERNAME

# Ѐункция логирования
function Write-Log {
    param([string]$Message, [string]$Level = "INFO")
    $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $LogEntry = "[$Timestamp] [$Level] $Message"

    # ЗаписываСм Π² Π»ΠΎΠ³ Ρ„Π°ΠΉΠ»
    $LogEntry | Out-File -FilePath $LogFile -Append -Encoding UTF8

    # Π’Ρ‹Π²ΠΎΠ΄ΠΈΠΌ Π² консоль Ссли Π½Π΅ Ρ‚ΠΈΡ…ΠΈΠΉ Ρ€Π΅ΠΆΠΈΠΌ
    if (-not $Quiet) {
        Write-Host $LogEntry
    }
}

# Ѐункция Windows ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ
function Show-Notification {
    param(
        [string]$Title = "Obsidian Sync",
        [string]$Message,
        [string]$Icon = "Info"
    )

    # Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Windows Toast увСдомлСния
    Add-Type -AssemblyName System.Windows.Forms
    $notification = New-Object System.Windows.Forms.NotifyIcon
    $notification.Icon = [System.Drawing.SystemIcons]::Information
    $notification.BalloonTipIcon = $Icon
    $notification.BalloonTipText = $Message
    $notification.BalloonTipTitle = $Title
    $notification.Visible = $True
    $notification.ShowBalloonTip(5000)

    # Π›ΠΎΠ³ΠΈΡ€ΡƒΠ΅ΠΌ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅
    Write-Log "NOTIFICATION: $Title - $Message"

    # ΠžΡ‡ΠΈΡ‰Π°Π΅ΠΌ рСсурсы
    Start-Sleep -Seconds 1
    $notification.Dispose()
}

# ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° сущСствования ΠΏΠ°ΠΏΠΊΠΈ Obsidian
if (-not (Test-Path $ObsidianPath)) {
    Write-Log "ERROR: Папка Obsidian нС найдСна: $ObsidianPath" "ERROR"
    Show-Notification -Message "Папка Obsidian нС найдСна!" -Icon "Error"
    exit 1
}

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ°ΠΏΠΊΡƒ Π»ΠΎΠ³ΠΎΠ² Ссли Π΅Ρ‘ Π½Π΅Ρ‚
if (-not (Test-Path $LogPath)) {
    New-Item -ItemType Directory -Path $LogPath -Force | Out-Null
}

Set-Location $ObsidianPath

Write-Log "=== Начало синхронизации ==="

# ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ Git Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ
if (-not (Test-Path ".git")) {
    Write-Log "ERROR: Git Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ Π½Π΅ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½" "ERROR"
    Show-Notification -Message "Git Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½!" -Icon "Error"
    exit 1
}

try {
    # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ измСнСния с сСрвСра
    Write-Log "ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ измСнСния с GitHub..."
    git fetch origin main 2>&1 | Out-File -FilePath $LogFile -Append -Encoding UTF8

    # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ количСство ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
    $RemoteChanges = (git rev-list HEAD..origin/main --count 2>$null)
    if (-not $RemoteChanges) { $RemoteChanges = 0 }

    $LocalChanges = (git status --porcelain | Measure-Object).Count

    Write-Log "Π£Π΄Π°Π»Π΅Π½Π½Ρ‹Ρ… ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ: $RemoteChanges, Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ…: $LocalChanges"

    # ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Π΅ измСнСния
    if ([int]$RemoteChanges -gt 0) {
        Write-Log "ΠŸΡ€ΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Π΅ измСнСния..."
        $pullResult = git pull origin main 2>&1

        if ($LASTEXITCODE -eq 0) {
            Write-Log "УспСшно ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ $RemoteChanges ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ"
            Show-Notification -Message "πŸ“₯ ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ $RemoteChanges ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ с сСрвСра"
        } else {
            Write-Log "ERROR: Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ: $pullResult" "ERROR"
            Show-Notification -Message "❌ Ошибка синхронизации" -Icon "Error"
            exit 1
        }
    }

    # ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ измСнСния
    if ($LocalChanges -gt 0) {
        Write-Log "БохраняСм Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ измСнСния..."

        # ДобавляСм всС измСнСния
        git add . 2>&1 | Out-File -FilePath $LogFile -Append -Encoding UTF8

        # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΊΠΎΠΌΠΌΠΈΡ‚
        $CommitMessage = "Auto-sync from $ComputerName`: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
        git commit -m $CommitMessage 2>&1 | Out-File -FilePath $LogFile -Append -Encoding UTF8

        # ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ Π½Π° сСрвСр
        Write-Log "ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ измСнСния Π½Π° сСрвСр..."
        $pushResult = git push origin main 2>&1

        if ($LASTEXITCODE -eq 0) {
            Write-Log "УспСшно ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ $LocalChanges ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ"
            Show-Notification -Message "πŸ“€ ΠžΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ΠΎ $LocalChanges ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π½Π° сСрвСр"
        } else {
            Write-Log "ERROR: Ошибка ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅: $pushResult" "ERROR"
            Show-Notification -Message "❌ Ошибка ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Π½Π° сСрвСр" -Icon "Error"
            exit 1
        }
    }

    # Если Π½Π΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
    if ([int]$RemoteChanges -eq 0 -and $LocalChanges -eq 0) {
        Write-Log "ИзмСнСний Π½Π΅Ρ‚, синхронизация Π½Π΅ трСбуСтся"
        if (-not $Quiet) {
            Show-Notification -Message "βœ… ВсС синхронизировано"
        }
    }

} catch {
    Write-Log "ERROR: ΠšΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΠ°Ρ ошибка: $($_.Exception.Message)" "ERROR"
    Show-Notification -Message "❌ ΠšΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΠ°Ρ ошибка синхронизации" -Icon "Error"
    exit 1
}

Write-Log "=== Бинхронизация Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° ==="
'@ | Out-File -FilePath "$env:USERPROFILE\Scripts\ObsidianSync\ObsidianSync.ps1" -Encoding UTF8

Π‘ΠΊΡ€ΠΈΠΏΡ‚ ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ синхронизации

 ```powershell @'

ForceSync.ps1 - ΠŸΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ синхронизация

 param([switch]$Confirm)


 $ObsidianPath = "$env:USERPROFILE\Documents\Obsidian Vault" $BackupPath = "$env:USERPROFILE\Scripts\ObsidianSync\Backups" $LogFile = "$env:USERPROFILE\Scripts\ObsidianSync\Logs\force-sync-$(Get-Date -Format 'yyyy-MM-dd').log"


 function Write-Log { param([string]$Message) $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" "[$Timestamp] FORCE: $Message" | Out-File -FilePath $LogFile -Append -Encoding UTF8 Write-Host "[$Timestamp] FORCE: $Message" }


 if (-not $Confirm) { $response = Read-Host "⚠️ Π’ΠΠ˜ΠœΠΠΠ˜Π•: ΠŸΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ синхронизация сбросит Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ измСнСния!`nΠŸΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ? (y/N)" if ($response -ne 'y' -and $response -ne 'Y') { Write-Host "ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π°." exit 0 } }


 Set-Location $ObsidianPath Write-Log "=== Начало ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ синхронизации ==="

Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ€Π΅Π·Π΅Ρ€Π²Π½ΡƒΡŽ копию

 $BackupName = "backup-$(Get-Date -Format 'yyyyMMdd-HHmmss').zip" $BackupFullPath = "$BackupPath\$BackupName"