Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
2d72022
feat(source-control): add push-selection and operation-state foundation
ClaudiaFang Aug 21, 2026
4b09425
fix(source-control): key selection and operation state by ChangeId
ClaudiaFang Aug 22, 2026
5d5645e
docs: add source control refactor roadmap
ClaudiaFang Aug 22, 2026
76db082
feat(source-control): add ViewModel foundation layer
ClaudiaFang Aug 22, 2026
7cec661
feat(source-control): add Phase 3 source control UI
ClaudiaFang Aug 22, 2026
70f6c9e
feat(source-control): add Phase 2 action service
ClaudiaFang Aug 22, 2026
ec44025
chore: add deploy script to sync build output to local Obsidian vault
ClaudiaFang Aug 22, 2026
4e647fb
feat(source-control): wire Source Control view as the entry and remov…
ClaudiaFang Aug 22, 2026
0bcc800
fix(source-control): correct status grouping and filter semantics
ClaudiaFang Aug 22, 2026
8f130b3
test: add source control filter coverage
ClaudiaFang Aug 22, 2026
8ed5df9
test: extract reusable source control E2E fixtures
ClaudiaFang Aug 22, 2026
df9dea9
test: cover complex rename and move workflows
ClaudiaFang Aug 22, 2026
726c54a
test: expand conflict state transition coverage
ClaudiaFang Aug 22, 2026
e4a3ff0
test: cover conflict resolution workflows
ClaudiaFang Aug 22, 2026
b8f50b2
test: cover mixed batch operations
ClaudiaFang Aug 22, 2026
2e293f3
test: cover source control selection workflows
ClaudiaFang Aug 22, 2026
119ba03
test: cover divergence and idempotency flows
ClaudiaFang Aug 22, 2026
f036888
test: add path and batch-scale regression cases
ClaudiaFang Aug 22, 2026
e9f0d28
fix(ci): run E2E suites through shared runner
ClaudiaFang Aug 22, 2026
220f2d5
test(ci): guard E2E suite registration
ClaudiaFang Aug 22, 2026
c2bfeb0
fix(ci): fold E2E suite registration check into run-e2e.sh
ClaudiaFang Aug 22, 2026
54e3fb7
fix(test): show per-test progress in real-provider E2E CI logs
ClaudiaFang Aug 22, 2026
039588f
fix(test): capture post-push head before asserting no-op repeat push
ClaudiaFang Aug 22, 2026
d6cdc36
fix(settings): keep release history accessible after dismiss
ClaudiaFang Aug 22, 2026
b9a90b2
perf(test): memoize remote reads in source-control-flows scenarios
ClaudiaFang Aug 22, 2026
c37e37c
fix(settings): keep release history accessible after dismiss
ClaudiaFang Aug 22, 2026
8228a04
test(settings): keep release history accessible after dismiss
ClaudiaFang Aug 22, 2026
de55653
fix(i18n): remove duplicate releaseHistory keys from concurrent fixes
ClaudiaFang Aug 22, 2026
b1d2208
perf(ci): gate and tier real-provider E2E
ClaudiaFang Aug 22, 2026
a8a704b
Merge pull request #133 from firstsun-dev/test/source-control-e2e-cov…
ClaudiaFang Aug 22, 2026
9333b77
Merge pull request #132 from firstsun-dev/fix/source-control-status-m…
ClaudiaFang Aug 22, 2026
f449125
feat(source-control): full-width diff tab and mobile view-title dedup
ClaudiaFang Aug 22, 2026
8c69cc8
refactor(sync-status): integrate source control view model
ClaudiaFang Aug 22, 2026
625fad2
feat(sync-status): add selection workflow and sync action UI
ClaudiaFang Aug 22, 2026
759b717
feat(sync-status): add refresh and operation feedback
ClaudiaFang Aug 22, 2026
dd8ddd5
feat(source-control): presentation adapter, diff stat, responsive mobile
ClaudiaFang Aug 22, 2026
8aa8fdf
docs: record sync-status-workflow-ui completion in progress + handoff
ClaudiaFang Aug 22, 2026
853793c
feat(source-control): selected-section rows, drop show-synced toggle,…
ClaudiaFang Aug 22, 2026
a9d3e98
fix(source-control): make whole view scroll, add clear-selection, cli…
ClaudiaFang Aug 22, 2026
7538e0a
refactor(source-control): Selected section becomes a read-only action…
ClaudiaFang Aug 22, 2026
639840a
refactor(source-control): converge UI to sync-intent workflow
ClaudiaFang Aug 22, 2026
395b87e
ci: parallelize validation jobs behind a single required-checks gate
ClaudiaFang Aug 22, 2026
60790a3
refactor(source-control): staged/Changes split with collapsible sections
ClaudiaFang Aug 22, 2026
d7606ff
fix(source-control): pin Checked Changes, independent scroll for Chan…
ClaudiaFang Aug 22, 2026
069653f
test(ci): align ci-workflow contract with parallel DAG + required-che…
ClaudiaFang Aug 22, 2026
9fd1789
feat(source-control): split sync queue/repository regions and extract…
ClaudiaFang Aug 22, 2026
f9eb81b
feat(source-control): add remote-only download action and queue uploa…
ClaudiaFang Aug 22, 2026
4009f1d
feat(sync): auto-refresh status on local vault changes and distinguis…
ClaudiaFang Aug 23, 2026
a4ccf9f
docs(claude): remove session-handoff references from agent workflow
ClaudiaFang Aug 23, 2026
66d7b8a
Merge pull request #135 from firstsun-dev/feat/sync-status-workflow-ui
ClaudiaFang Aug 24, 2026
b5eb1ae
fix(sync): report added/updated counts in push/pull toasts, i18n them
ClaudiaFang Aug 24, 2026
10e344f
fix(source-control): preserve Changes tree scroll position on rerender
ClaudiaFang Aug 24, 2026
b059ae2
Merge pull request #138 from firstsun-dev/claude/sync-plan-workflow-r…
ClaudiaFang Aug 25, 2026
ebd8cb6
fix(source-control): route local-deleted to delete-remote, not pull-r…
ClaudiaFang Aug 25, 2026
2dfe78b
fix(source-control): make sync actions actually sequential and clean …
ClaudiaFang Aug 27, 2026
264ae4b
refactor(source-control): unify Sync into one plan, one commit
ClaudiaFang Aug 27, 2026
257b2a4
fix(e2e): invalidate SourceControlScenario's remote cache on commitRe…
ClaudiaFang Aug 27, 2026
920adee
test(e2e): run Gitea safely across local and CI
ClaudiaFang Aug 27, 2026
18de6e0
fix(ci): continue after intentionally skipped E2E jobs
ClaudiaFang Aug 27, 2026
b5884fc
fix(ci): isolate manual E2E concurrency
ClaudiaFang Aug 27, 2026
bf33cd2
docs: record Gitea E2E CI verification
ClaudiaFang Aug 27, 2026
2fc6997
Merge remote-tracking branch 'origin/claude/source-control-foundation…
ClaudiaFang Aug 27, 2026
641a58b
Merge pull request #140 from firstsun-dev/codex/test-gitea-e2e-ci
ClaudiaFang Aug 27, 2026
17b361f
fix(source-control): unify sync completion notification
ClaudiaFang Aug 28, 2026
25dfbc8
docs: record unified sync notification verification
ClaudiaFang Aug 28, 2026
5dcd87e
fix(e2e): constrain generated runtime imports
ClaudiaFang Aug 28, 2026
d4ce756
docs: align guides with source control workflow
ClaudiaFang Aug 28, 2026
daf7c81
docs: restore README demo media
ClaudiaFang Aug 28, 2026
3e9f709
fix(e2e): replace unsafe dynamic imports and align Obsidian lint
ClaudiaFang Aug 28, 2026
88e08dd
feat(whats-new): add onboarding layout for the Source Control workflow
ClaudiaFang Aug 28, 2026
2bbd042
fix(source-control): prevent duplicate sync status views
ClaudiaFang Aug 29, 2026
259fed6
chore(deps): update dev dependencies and fix audit vulnerabilities
ClaudiaFang Aug 29, 2026
49033a8
chore(lint): fix test warnings and scope remaining rule exemptions
ClaudiaFang Aug 29, 2026
2d6cf91
fix(source-control): repair diff stat cache lifecycle
ClaudiaFang Aug 29, 2026
709905a
fix(source-control): preserve mobile list position after diff
ClaudiaFang Aug 29, 2026
05f6628
fix(source-control): harden scroll, diff-stat and create lifecycles
ClaudiaFang Aug 29, 2026
af376f2
chore(source-control): finish legacy sync-status presentation cleanup
ClaudiaFang Aug 29, 2026
9eb3713
docs: record lifecycle hardening round in session handoff and progress
ClaudiaFang Aug 29, 2026
acd2046
fix(ci): serialize branch validation workflows
ClaudiaFang Aug 29, 2026
78a78e8
fix(source-control): track diff stat requests by generation token
ClaudiaFang Aug 29, 2026
49f3033
fix(sync-status): preserve refreshed state across live modifications
ClaudiaFang Aug 29, 2026
fbe0787
fix(source-control): correct one-sided diff stat direction
ClaudiaFang Aug 29, 2026
17d241c
docs: record final-fix round in session handoff and progress
ClaudiaFang Aug 29, 2026
8c07011
docs: record CI green evidence for the whole-run concurrency
ClaudiaFang Aug 29, 2026
b3720f7
fix(source-control): correct mobile queue and diff presentation
ClaudiaFang Aug 30, 2026
44c17ba
fix(deps): bump undici and ip-address overrides to patched versions
ClaudiaFang Aug 30, 2026
c73c9cc
fix(source-control): make keep-remote resolution authoritative
ClaudiaFang Aug 30, 2026
cd8c31c
test(source-control): cover keep-remote end-to-end semantics
ClaudiaFang Aug 30, 2026
2591e05
fix(source-control): apply keep-remote-only batch plans and harden re…
ClaudiaFang Aug 30, 2026
10f9ead
fix(source-control): refresh the open diff tab when its backing statu…
ClaudiaFang Aug 30, 2026
8100e45
style(source-control): replace raw rgba diff colors with semantic --s…
ClaudiaFang Aug 30, 2026
ac2bd2a
fix(conflict-modal): apply modal sizing CSS and add filename-first ro…
ClaudiaFang Aug 30, 2026
769f82d
refactor(diff): extract shared DiffViewer, gfs-conflict-modal shell, …
ClaudiaFang Aug 30, 2026
246a59f
feat(conflict-modal): wire SyncDiffService.getConflictStat as the bat…
ClaudiaFang Aug 30, 2026
a7dcda7
refactor(sync): compact batch-conflict header and drop totalFiles fro…
ClaudiaFang Aug 30, 2026
94196ab
test(i18n): cover inline plural forms; docs: record refactor round
ClaudiaFang Aug 30, 2026
a07a895
docs(imgs): add sync-status screenshot
ClaudiaFang Aug 30, 2026
ec9d356
feat(conflict-modal): wire View Diff data through SyncDiffService
ClaudiaFang Aug 31, 2026
2825641
test(e2e): add two-client sync convergence suite
ClaudiaFang Aug 31, 2026
02bd3e3
fix(sync): stop remote-op failures from masking each other's outcome
ClaudiaFang Aug 31, 2026
38a5d9e
fix(e2e): resolve SonarCloud quality gate findings on new code
ClaudiaFang Aug 31, 2026
376901f
refactor(test): move real-provider E2E to e2e-tests/provider/, commit…
ClaudiaFang Aug 31, 2026
7d7db23
Merge pull request #144 from firstsun-dev/refactor/e2e-tests-scanner-…
ClaudiaFang Aug 31, 2026
264cb47
fix(sync): classify remote-only changes as remote-modified, not local…
ClaudiaFang Aug 31, 2026
b186d35
Merge pull request #145 from firstsun-dev/fix/remote-modified-classif…
ClaudiaFang Aug 31, 2026
2c7a473
fix(e2e): scope two-client convergence checks to the run's own namespace
ClaudiaFang Aug 31, 2026
120dfe5
fix(e2e): share the manager's SyncStatusService in the two-client fix…
ClaudiaFang Aug 31, 2026
8d09aad
fix(e2e): bound the requestUrl shim to a 30s timeout
ClaudiaFang Aug 31, 2026
9528528
docs(progress): record CI run 33358507732 triage
ClaudiaFang Aug 31, 2026
2c33b1f
test(e2e): isolate two-client sync scope
ClaudiaFang Aug 31, 2026
5422666
test(e2e): streamline two-client sync scenarios
ClaudiaFang Aug 31, 2026
ac7b466
test(e2e): bound git transport operations and reset retry state
ClaudiaFang Aug 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
438 changes: 294 additions & 144 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Agent Workflow

- **Startup**: read `feature_list.json` (active/next-up work; GitHub Issues on `firstsun-dev/git-files-sync`, Project #6, is the actual source of truth — re-sync before trusting stale entries) and `progress.md` (what's open right now), then `session-handoff.md` for the previous session's exact stopping point.
- **Startup**: read `feature_list.json` (active/next-up work; GitHub Issues on `firstsun-dev/git-files-sync`, Project #6, is the actual source of truth — re-sync before trusting stale entries) and `progress.md` (what's open right now).
- **Before editing**: run `./init.sh` (installs deps, then lint + test + build) to confirm you're starting from a green baseline.
- **Definition of done**: `npx eslint .` has 0 errors, `npm run build` passes (includes the Obsidian 1.11.0 compat typecheck), and `npx vitest run` passes, *and* evidence of that run is recorded (one line: command + result) in `progress.md` or the PR description — not just claimed.
- **Scope**: work one `feature_list.json` entry at a time; don't start the next until the current one's evidence is recorded.
- **End of session**: overwrite `session-handoff.md` with the new stopping point, move finished items from `progress.md` into `archive/YYYY-MM.md` (current month).
- **End of session**: move finished items from `progress.md` into `archive/YYYY-MM.md` (current month).
- Issue/PR conventions (Conventional Commits titles, Project #6 fields, English-only for this public plugin repo) are defined in the `firstsun-pm` skill, not duplicated here.

## Development Commands
Expand Down
198 changes: 116 additions & 82 deletions README.md

Large diffs are not rendered by default.

186 changes: 118 additions & 68 deletions USAGE_zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,107 +7,157 @@

**[English](README.md)** · **[繁體中文](USAGE_zh.md)** · **[更新日志](CHANGELOG.md)**

<video src="https://blog-assets.firstsun.org/obsidian/plugins/git-file-sync/git-file-sync-zh.webm" width="100%" controls autoplay loop muted playsinline></video>
Git File Sync 让你通过 GitHub、GitLab 或自建 Gitea,在桌面端与移动端 Obsidian 中**选择性同步文件**,不需要把整个 vault 都交给同一套同步服务。

本指南介绍如何使用 Git File Sync 插件,在移动设备与桌面端之间,通过 GitLab、GitHub 或自建 Gitea 选择性同步笔记。
你可以先检查变更、选择这次真正要同步的项目,再从“同步队列”一次确认并应用。插件直接通过 Git 服务 API 操作,不需要安装 Git CLI,也不需要在 vault 中创建本地 `.git` 仓库。

Git File Sync 不会同步整个 vault;您可以只选择要分享、发布或备份的笔记,同时将私人笔记保留在本地。它直接连接 Git 服务的 API,不需要安装 Git、使用命令行,或在 vault 中创建本地 `.git` 仓库。
## 新版操作模型

---
Git File Sync 的版本控制流程可以记成:

## 支持的 Git 服务
**检查变更 → 加入同步队列 → 同步**

| 服务 | 适用场景 | 最低版本 |
| :--- | :--- | :--- |
| **GitHub** | 公开/私有仓库 | — |
| **GitLab** | gitlab.com 或自建实例 | GitLab 13.0+ |
| **Gitea** | 自建 Git 服务器 | Gitea 1.12+ |
1. **检查“仓库变更”** — 在同一个界面查看本地变更、远程变更、重命名、删除和冲突。
2. **建立“同步队列”** — 勾选这次真正要处理的项目。
3. **检查并同步** — 在应用前先查看完整同步计划,再执行上传、下载和删除。

---
被选中的项目会从“仓库变更”移动到“同步队列”,同一条变更不会同时出现在两个区域。

## 1. 初始设置
## 主要功能

在开始同步前,请完成以下设置:
- **只同步你选择的文件** — 私人笔记或无关文件可以留在本地。
- **统一的版本控制界面** — 集中查看本地、远程、移动、删除与冲突状态。
- **一个同步队列** — 同一次操作可以包含上传、下载和远程删除。
- **应用前先检查** — 新增、修改、移动、下载和删除都会先出现在同步计划中。
- **内置差异对比** — 支持单栏与并排 Diff,对比本地与远程版本。
- **明确处理冲突** — 由你决定保留本地或远程,不会静默覆盖。
- **多平台与多服务** — 支持 GitHub、GitLab、Gitea,以及桌面端和移动端 Obsidian。
- **三种界面语言** — English、繁體中文、简体中文。

![Plugin Settings](imgs/plugin-settings.png)
*在设置面板选择 Git 服务,并填写对应的凭据和路径。*
## 快速开始

1. **选择服务**:在 `设置` > `Git File Sync` 中选择 GitLab、GitHub 或 Gitea。
2. **填写凭据**:
1. 从 Obsidian 社区插件安装 Git File Sync。
2. 在 **设置 → Git File Sync** 中配置 GitHub、GitLab 或 Gitea。
3. 从侧边功能栏或命令面板打开 **版本控制(Source Control)**。
4. 检查 **仓库变更**。
5. 勾选要同步的项目,项目会移动到 **同步队列**。
6. 点击 **同步**,检查同步计划后选择 **应用**。

> **安全提示:** 请把每个令牌的权限范围缩到最小:只允许需要同步的仓库、只授予必要权限,并设置较短的有效期。令牌只应保存在本插件的设置中,不要粘贴到会被同步的笔记里。如果令牌可能泄露,请立即撤销并重新创建;不再使用的令牌也应直接撤销。
## 版本控制界面

- **GitHub**:建议创建 [fine-grained personal access token](https://github.com/settings/personal-access-tokens/new),而不是 classic token。在 **Repository access** 中选择 *Only select repositories*,只指定要同步的仓库;设置 **Expiration**(建议不超过 90 天),并只授予 **Contents: Read and write**。如果必须使用 classic token,则使用 `repo` scope,并为该用途设置到期时间。
- **GitLab**:建议优先使用 [project access token](https://docs.gitlab.com/user/project/settings/project_access_tokens/)(`Project` > `Settings` > `Access tokens`),而不是个人访问令牌,使权限限制在单个项目内,也可以独立撤销。插件只会调用 repository tree、blob、commit 和 branch 相关 API,因此只需要 `read_repository` 和 `write_repository`,**不需要** `api`。如需推送到非 protected branch,最低角色为 **Developer**。请设置到期时间;服务器网址默认为 `https://gitlab.com`,自建环境请改为您的实例网址。
- **Gitea**:在 `用户设置` > `应用程序` > `访问令牌` 中创建令牌。插件只会操作仓库内容、分支和 Git data;Gitea 1.19+ 支持 scoped token,请只选择 **`write:repository`**(已包含读取权限),不要选择全部权限。较旧版本(最低支持到 1.12)没有 scoped token,令牌默认是账号级别;这种情况下建议使用只拥有目标仓库权限的专用 bot / service account,而不是个人账号。若实例支持到期时间也请设置,并将服务器网址指向您的 Gitea 实例(例如 `https://gitea.example.com`)。
### 仓库变更

三种服务都可以从各自的设置页面立即撤销令牌。如果令牌可能泄露,请先撤销,再签发新的令牌。
3. **仓库路径**:如需把笔记存放在仓库中的特定目录(例如 `notes/`),请设置 `Root Path`。
4. **语言和自动刷新**:可以选择跟随系统、English、繁體中文或简体中文。“Obsidian 启动时自动刷新同步状态”默认开启,也可在设置中关闭。
显示当前需要处理、但尚未加入下一次同步的项目。可以使用搜索、筛选器与树状/列表视图快速缩小范围。

---
### 同步队列

## 2. 核心操作流程
显示下一次“同步”会实际处理的项目。每一项都会标示预计执行的动作:

### 💡 检查同步状态
- **上传** — 将本地版本应用到远程仓库。
- **下载** — 将远程版本带回当前 vault。
- **删除** — 将本地已删除的跟踪文件同步删除远程版本。

每次开始工作或切换设备时,建议先查看状态:
点击 **同步** 后会先生成一份合并的同步计划。远程的新增、修改、移动和删除会一起提交;下载则在确认后应用到本地。

1. 点击侧边栏的**列表图标**,或打开命令面板 (`Ctrl/Cmd + P`) 并运行 `Open sync status view`。
2. 同步状态会在 Obsidian 启动后自动刷新;需要时仍可点击 **Refresh status**。
3. 使用状态标签、路径搜索或可选的树状视图浏览文件。树状视图支持展开文件夹和三态复选框,可一次选中整个文件夹。
4. 文件会显示为:
- **Synced**:已同步(与远程一致)。
- **Modified**:本地已修改(需要 Push)。
- **Remote only**:远程有新文件(需要 Pull)。
- **Moved**:文件或文件夹已重命名/移动,尚待同步;可以 Push 或撤销移动。
### 文件状态

![sync-status](imgs/sync-status.png)
*同步状态面板让您一目了然地确认哪些文件已经修改,并进行上传或下载。*
| 状态 | 含义 |
|---|---|
| `A` | 本地新增 |
| `M` | 本地已修改 |
| `D` | 本地已删除 |
| `R` | 已重命名或移动 |
| `↓` | 远程可下载 |
| `↕` | 远程已修改 |
| `!` | 冲突 |
| `S` | 已同步 |

### ⬆️ 如何上传(Push)
> **本地已删除:** 将 `D` 项目加入同步队列后,默认会同步删除远程的跟踪文件。如果是误删,请改用 **下载**,把远程版本恢复到本地。

写完笔记后,您可以:
## 常见操作

- **单个文件**:点击左侧功能栏的云上传图标,或在文件列表中右键选择 `Push to GitLab/GitHub/Gitea`。
- **批量上传**:在同步面板勾选多个文件,然后点击 **Push selected**。
- **确认计划**:每次 Push 前都会列出新增、修改、移动和删除项目;确认后点击 **Apply**。文件重命名或文件夹移动会作为真正的移动提交,不会在远程留下重复文件。
| 情况 | 操作结果 |
|---|---|
| 本地新增文件 | `A` → 同步队列 → **上传** |
| 本地修改文件 | `M` → 同步队列 → **上传** |
| 文件只存在远程 | `↓` → 同步队列 → **下载** |
| 远程版本已修改 | `↕` → 同步队列 → **下载** |
| 本地删除跟踪文件 | `D` → 同步队列 → **删除**远程 |
| 本地误删 | `D` → **下载** → 恢复本地 |
| 重命名/移动 | `R` → 同步队列 → 以移动方式**上传** |
| 本地与远程都修改 | `!` → 检查冲突 → **保留本地**或**采用远程** |

### ⬇️ 如何下载(Pull)
## 差异对比与冲突

1. 打开同步面板并点击 **Refresh status**。
2. 找到标记为 **Remote only** 或 **Modified**(远程版本较新)的文件。
3. 勾选后点击 **Pull selected**。
4. 查看即将应用的同步计划,然后点击 **Apply**。
5. **注意**:Pull 会覆盖本地内容。如果两端都有修改,会自动打开冲突解决窗口。
选择有变更的文件后,可以在同步前查看本地与远程内容差异。Diff 支持单栏与并排布局,并在可用时显示新增/删除行数。

---
![conflict](imgs/git-diff.png)
*同步前先检查本地与远程的差异,再决定保留哪一侧。*

## 3. 冲突解决(Conflict Resolution)
如果本地与远程都修改过同一个文件,Git File Sync 会保留明确的冲突状态:

当同一文件在本地和远程都被修改时,会显示冲突窗口:
- **Keep Local/保留本地** — 使用本地内容覆盖远程。
- **Keep Remote/采用远程** — 接受远程版本并覆盖本地。

1. 左侧是**本地版本**,右侧是**远程版本**。
2. 查看两侧的差异。
3. 选择 **Keep Local**(保留本地版本)或 **Keep Remote**(采用远程版本)。
4. 选择后,插件会更新文件。
## 支持的 Git 服务

![conflict](imgs/git-diff.png)
*内置差异查看器可在同步前并排对比本地与远程的修改。*
| 服务 | 适用场景 | 最低版本 |
|---|---|---|
| **GitHub** | github.com/GitHub Enterprise | — |
| **GitLab** | gitlab.com/自建 | GitLab 13.0+ |
| **Gitea** | 自建 Git 服务器 | Gitea 1.12+ |

## 初始设置

![Plugin Settings](imgs/plugin-settings.png)
*在设置面板选择 Git 服务并配置仓库。*

| 服务 | 必要信息 | 建议权限 |
|---|---|---|
| **GitHub** | Token、owner、repository | Fine-grained token:**Contents: Read and write** |
| **GitLab** | Token、project ID、base URL | `read_repository`、`write_repository` |
| **Gitea** | Token、owner、repository、base URL | Gitea 1.19+:`write:repository` |

其他设置包括语言、同步分支、仓库 Root Path、vault folder 范围、启动时刷新、忽略规则,以及 symbolic link 处理方式。Symbolic link 详细行为请参考 [Symbolic link handling](docs/symlink-handling.md)。

> **安全建议:** 令牌只授予必要仓库和最低权限,能设置到期时间就设置;不要把令牌写进可能被同步的笔记。如果怀疑泄露,请立即撤销并重新签发。

## 移动端

移动端使用相同的版本控制模型。同步队列默认保持紧凑,避免把“仓库变更”推离屏幕;选择文件后会进入适合手机操作的详情/Diff 界面。

跨设备工作时,建议先刷新远程状态再开始修改;完成后只把真正要同步的项目加入同步队列。

## 安装

### 从社区插件安装(推荐)

1. 打开 **设置 → 社区插件**,必要时关闭限制模式。
2. 点击 **浏览**,搜索 **Git File Sync**。
3. 点击 **安装**,完成后 **启用**。

### 手动安装

在桌面端,点击 **Diff** 会在专用窗格打开对比;移动端仍在面板内显示。可以点击文件路径打开本地笔记,或在支持的服务上打开远程文件页面。
1. 从 [最新 Release](https://github.com/firstsun-dev/git-files-sync/releases/latest) 下载 `main.js`、`manifest.json`、`styles.css`。
2. 创建 `<vault>/.obsidian/plugins/git-file-sync/`。
3. 将三个文件放入该目录。
4. 重新加载 Obsidian,并在 **设置 → 社区插件** 中启用 Git File Sync。

---
## 隐私与安全

## 4. 移动设备使用技巧
- **Token 仅保存在本地** — 访问令牌保存在 vault 内的插件数据中,只会发送给你配置的 Git 服务。
- **无遥测** — 插件不收集使用分析或个人数据。
- **选择性同步** — 未选入同步流程的文件不会因为新版版本控制流程而自动上传。

- **打开面板**:从屏幕左侧向右滑动,展开功能栏后即可看到同步图标。
- **工作前先 Pull**:每次开始编辑前,先刷新状态以确认已获取最新版本。
- **完成后及时 Push**:编辑完成后及时 Push,确保变更已保存到远程。
## 系统要求

---
- Obsidian **1.11.0** 或更新版本
- 支持桌面端与移动端

## 🔒 隐私与安全
## 更多文档

- 个人访问令牌只保存在本地 vault 的插件数据目录中,只会发送到您配置的 Git 服务。
- 插件不收集使用数据或分析信息。
- [English README](README.md)
- [繁體中文使用指南](USAGE_zh.md)
- [Symbolic link handling](docs/symlink-handling.md)
- [完整更新日志](CHANGELOG.md)
- [Releases](https://github.com/firstsun-dev/git-files-sync/releases)
Loading
Loading