ΠΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π΄Π»Ρ 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"