From e24474abd1e1ce9999173ca29505d0b1fe7e8efe Mon Sep 17 00:00:00 2001 From: liyepan Date: Thu, 22 Oct 2026 18:23:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20v0.9.1=20=E2=80=94=E2=80=94=20=E5=8F=B3?= =?UTF-8?q?=E9=94=AE=E8=8F=9C=E5=8D=95=E6=8B=86=E6=88=90=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20/=20=E5=BF=BD=E7=95=A5=20/=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E8=BF=9C=E7=AB=AF=20=E4=B8=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加:git add -- ,只暂存这个文件 - 忽略:把路径写进 .gitignore,不碰索引也不碰远端 - 删除远端:git rm --cached + 提交 + 推送,确认后执行;本地文件保留 - 原来的「忽略(并从远端删除)」合并项去掉 - 新增 13 条中英文翻译,清理 5 条过期条目 - README 同步,版本 0.9.1 --- README.md | 12 ++-- VoiletMark.pro | 2 +- src/MainWindow.cpp | 85 ++++++++++++++----------- src/MainWindow.h | 1 + translations/voiletmark_en.qm | Bin 9579 -> 10355 bytes translations/voiletmark_en.ts | 115 +++++++++++++++++++++------------- 6 files changed, 129 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index b82c0b4..838ebf1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 一个轻量的跨平台 Markdown 编辑器,基于 **Qt 5 / C++17** 构建。 -当前版本 **0.9.0**。 +当前版本 **0.9.1**。 ## 界面 @@ -57,12 +57,12 @@ | 暂存 | `git add -A` | | 提交 | 填说明后 `git commit -m` | -右键侧栏里的文件还有两项: +右键侧栏里的文件有三项: -- **添加到提交** → `git add -- ` -- **忽略(并从远端删除)** → 写进 `.gitignore` + `git rm --cached` + 提交 + 推送。 - **远端会真的删掉这个文件**,所以点之前会弹确认框,把要执行的命令逐条列出来; - 本地文件保留。 +- **添加** → `git add -- `,只暂存这一个文件 +- **忽略** → 把路径写进 `.gitignore`(不改已跟踪的文件,也不碰远端) +- **删除远端** → `git rm --cached` + 提交 + 推送。**远端会真的删掉这个文件**, + 本地文件保留;执行前弹确认框。 所有命令都是异步跑的,不会卡界面;失败时弹窗显示 git 的原始输出。 diff --git a/VoiletMark.pro b/VoiletMark.pro index 825279a..8bf0a7f 100644 --- a/VoiletMark.pro +++ b/VoiletMark.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = VoiletMark -VERSION = 0.9.0 +VERSION = 0.9.1 QT += core gui widgets printsupport diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 0242e0a..e8b4bac 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -1276,59 +1276,65 @@ void MainWindow::gitIgnoreFile(const QString &path) return; const QString relative = QDir(m_gitRoot).relativeFilePath(path); - - QMessageBox box(QMessageBox::Warning, tr("忽略文件"), - tr("忽略「%1」?\n\n" - "会依次执行:\n" - "1. 把路径写进 .gitignore\n" - "2. git rm --cached(从仓库移除,本地文件保留)\n" - "3. 提交并推送到远端——远端也会删掉这个文件\n\n" - "其他人 pull 之后,本地的那份也会被删掉。") - .arg(relative), - QMessageBox::NoButton, this); - QPushButton *confirm = box.addButton(tr("忽略并删除远端"), QMessageBox::AcceptRole); - box.addButton(tr("取消"), QMessageBox::RejectRole); - box.exec(); - if (box.clickedButton() != confirm) - return; - const QString ignorePath = QDir(m_gitRoot).filePath(QStringLiteral(".gitignore")); + QStringList lines; QFile ignoreFile(ignorePath); if (ignoreFile.open(QIODevice::ReadOnly | QIODevice::Text)) lines = QString::fromUtf8(ignoreFile.readAll()).split(QLatin1Char('\n')); ignoreFile.close(); - bool listed = false; for (const QString &line : lines) { if (line.trimmed() == relative) { - listed = true; - break; - } - } - if (!listed) { - if (ignoreFile.open(QIODevice::Append | QIODevice::Text)) { - QTextStream stream(&ignoreFile); - stream << relative << "\n"; - ignoreFile.close(); + statusBar()->showMessage(tr("「%1」已经在 .gitignore 里了").arg(relative), 4000); + return; } } - bool tracked = false; + if (!ignoreFile.open(QIODevice::Append | QIODevice::Text)) { + QMessageBox::warning(this, tr("忽略文件"), + tr("打不开 .gitignore:%1").arg(ignoreFile.errorString())); + return; + } + QTextStream stream(&ignoreFile); + stream << relative << "\n"; + ignoreFile.close(); + + statusBar()->showMessage(tr("已把 %1 写进 .gitignore").arg(relative), 4000); +} + +void MainWindow::gitRemoveRemote(const QString &path) +{ + if (m_gitRoot.isEmpty()) + return; + + const QString relative = QDir(m_gitRoot).relativeFilePath(path); + QProcess check; check.setWorkingDirectory(m_gitRoot); check.start(QStringLiteral("git"), {QStringLiteral("ls-files"), QStringLiteral("--error-unmatch"), QStringLiteral("--"), relative}); - if (check.waitForFinished(5000)) - tracked = (check.exitCode() == 0); + if (!(check.waitForFinished(5000) && check.exitCode() == 0)) { + QMessageBox::information(this, tr("删除远端"), + tr("「%1」没有被 git 跟踪,远端本来就没有它。").arg(relative)); + return; + } - if (tracked) - enqueueGit({QStringLiteral("rm"), QStringLiteral("--cached"), QStringLiteral("--"), relative}, - tr("从仓库移除")); - enqueueGit({QStringLiteral("add"), QStringLiteral("--"), QStringLiteral(".gitignore")}, - tr("更新忽略列表")); + QMessageBox box(QMessageBox::Warning, tr("删除远端"), + tr("从仓库删除「%1」并推送到远端?\n\n" + "本地文件会保留,远端和别人 pull 下来的仓库里会删掉它。") + .arg(relative), + QMessageBox::NoButton, this); + QPushButton *confirm = box.addButton(tr("删除并推送"), QMessageBox::AcceptRole); + box.addButton(tr("取消"), QMessageBox::RejectRole); + box.exec(); + if (box.clickedButton() != confirm) + return; + + enqueueGit({QStringLiteral("rm"), QStringLiteral("--cached"), QStringLiteral("--"), relative}, + tr("从仓库移除")); enqueueGit({QStringLiteral("commit"), QStringLiteral("-m"), - tr("chore: 忽略 %1").arg(relative)}, + tr("chore: 从仓库删除 %1").arg(relative)}, tr("提交")); enqueueGit({QStringLiteral("push")}, tr("推送")); } @@ -1347,8 +1353,13 @@ void MainWindow::showFileContextMenu(const QPoint &pos) if (!m_gitRoot.isEmpty()) { menu.addSeparator(); - menu.addAction(tr("添加到提交"), this, [this, path] { gitAddFile(path); }); - menu.addAction(tr("忽略(并从远端删除)"), this, [this, path] { gitIgnoreFile(path); }); + QAction *addAction = menu.addAction(tr("添加"), this, [this, path] { gitAddFile(path); }); + addAction->setToolTip(tr("git add 这个文件")); + QAction *ignoreAction = menu.addAction(tr("忽略"), this, [this, path] { gitIgnoreFile(path); }); + ignoreAction->setToolTip(tr("把路径写进 .gitignore(不改仓库里已跟踪的文件)")); + QAction *removeAction = + menu.addAction(tr("删除远端"), this, [this, path] { gitRemoveRemote(path); }); + removeAction->setToolTip(tr("git rm --cached 后提交并推送:远端删除,本地保留")); } menu.exec(m_fileList->viewport()->mapToGlobal(pos)); diff --git a/src/MainWindow.h b/src/MainWindow.h index 19a69bb..fc2b939 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -66,6 +66,7 @@ private: void showFileContextMenu(const QPoint &pos); void gitAddFile(const QString &path); void gitIgnoreFile(const QString &path); + void gitRemoveRemote(const QString &path); void gitCommit(); void gitPull(); void gitFetch(); diff --git a/translations/voiletmark_en.qm b/translations/voiletmark_en.qm index 2c66465b7bed19e7a2ad429fadf9478439222b61..d3eab113d6db0b34b3f434680294cbc47227ac82 100644 GIT binary patch delta 2346 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 - + 推送 Push @@ -207,7 +207,7 @@ - + 提交 Commit @@ -484,69 +484,100 @@ - 添加到提交 Add to commit - + + 「%1」已经在 .gitignore 里了 + "%1" is already in .gitignore + + + 忽略文件 Ignore File - - 忽略「%1」? - -会依次执行: -1. 把路径写进 .gitignore -2. git rm --cached(从仓库移除,本地文件保留) -3. 提交并推送到远端——远端也会删掉这个文件 - -其他人 pull 之后,本地的那份也会被删掉。 - Ignore "%1"? - -This will: -1. Add the path to .gitignore -2. Run git rm --cached (removes it from the repo, keeps your local file) -3. Commit and push - the file is deleted on the remote too - -Anyone who pulls afterwards will lose their local copy. + + 打不开 .gitignore:%1 + Cannot open .gitignore: %1 - - 忽略并删除远端 - Ignore and delete remote + + 已把 %1 写进 .gitignore + Added %1 to .gitignore - + + + + 删除远端 + Delete from remote + + + + 「%1」没有被 git 跟踪,远端本来就没有它。 + "%1" is not tracked by git, so the remote never had it. + + + + 从仓库删除「%1」并推送到远端? + +本地文件会保留,远端和别人 pull 下来的仓库里会删掉它。 + Remove "%1" from the repository and push? + +Your local file is kept, but the remote copy and everyone else's will be deleted. + + + + 删除并推送 + Delete and push + + + + chore: 从仓库删除 %1 + chore: remove %1 from repository + + + + 添加 + Add + + + + git add 这个文件 + git add this file + + + + 忽略 + Ignore + + + + 把路径写进 .gitignore(不改仓库里已跟踪的文件) + Add the path to .gitignore (does not untrack files already in the repo) + + + + git rm --cached 后提交并推送:远端删除,本地保留 + git rm --cached, then commit and push: gone from the remote, kept locally + + + 取消 Cancel - + 从仓库移除 Remove from repository - - 更新忽略列表 - Update ignore list - - - - chore: 忽略 %1 - chore: ignore %1 - - - + 打开 Open - - - 忽略(并从远端删除) - Ignore (and delete from remote) - MarkdownEditor