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 2c66465..d3eab11 100644 Binary files a/translations/voiletmark_en.qm and b/translations/voiletmark_en.qm differ diff --git a/translations/voiletmark_en.ts b/translations/voiletmark_en.ts index d95d236..169deb3 100644 --- a/translations/voiletmark_en.ts +++ b/translations/voiletmark_en.ts @@ -182,7 +182,7 @@ - + 推送 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