Git: кэш+пагинация истории, diff в потоке, точечный коммит, честное удаление
- История: кэш по vault|rel|headOid, fileHistory(vault,file,limit), в диалоге Показать ещё по 60 с сохранением выбора - Diff считается в QtConcurrent-пуле (parseBlocksWithDiffAsync+blocksReady, stale-guard), спиннер busy; MarkdownView.diffApplied - commitFile точечно вместо всего хранилища (общий commitFromIndex), autoCommit честный; fileExistedAt + willDelete в подтверждении - DocumentManager.readTextFile общий (GitManager.workdirContent через него); fileGitStatus через relativePath - Тесты: пагинация/кэш, existed, commitFile не трогает B, async==sync
This commit is contained in:
@@ -154,6 +154,62 @@ int main(int argc, char *argv[])
|
||||
bool autoAgain = git.autoCommit(vault, file);
|
||||
if(!autoAgain) return fail("auto again should be true even if no changes");
|
||||
|
||||
// Пагинация: limit режет сверху, порядок новые сверху, кэш консистентен
|
||||
{
|
||||
QVariantList full = git.fileHistory(vault, file);
|
||||
QVariantList part = git.fileHistory(vault, file, 2);
|
||||
if(part.size()!=2) return fail("paged size", QString::number(part.size()));
|
||||
if(part.first().toMap().value("hash") != full.first().toMap().value("hash"))
|
||||
return fail("paged order");
|
||||
// повторный запрос с тем же лимитом — из кэша, тот же результат
|
||||
QVariantList part2 = git.fileHistory(vault, file, 2);
|
||||
if(part2.size()!=2 || part2.first().toMap().value("hash") != part.first().toMap().value("hash"))
|
||||
return fail("paged cache");
|
||||
// limit<=0 — как раньше (всё)
|
||||
if(git.fileHistory(vault, file, 0).size() != full.size()) return fail("limit 0");
|
||||
}
|
||||
|
||||
// fileExistedAt: отличает «пустой файл» от «файла не было»
|
||||
// (коммит удаления в историю файла не попадает — файла нет в дереве,
|
||||
// поэтому false проверяем коммитом, предшествующим созданию файла)
|
||||
{
|
||||
if(!git.fileExistedAt(vault, file, hash1)) return fail("existed v1");
|
||||
const QString late = vault+"/late.md";
|
||||
QFile lf(late);
|
||||
if(!lf.open(QIODevice::WriteOnly)) return fail("late create");
|
||||
lf.write("late\n");
|
||||
lf.close();
|
||||
if(!git.commitAll(vault, "late file")) return fail("commit late", git.lastError());
|
||||
QString lateHash = git.fileHistory(vault, late).first().toMap().value("hash").toString();
|
||||
if(!git.fileExistedAt(vault, late, lateHash)) return fail("late existed");
|
||||
if(git.fileExistedAt(vault, late, hash1)) return fail("late should not exist at v1");
|
||||
if(git.fileExistedAt(vault, late, "0000000000000000000000000000000000000000"))
|
||||
return fail("bad hash existed");
|
||||
}
|
||||
|
||||
// commitFile: точечный коммит одного файла (второй файл не трогаем)
|
||||
{
|
||||
QFile re(file);
|
||||
if(!re.open(QIODevice::WriteOnly)) return fail("recreate");
|
||||
re.write("v-final\n");
|
||||
re.close();
|
||||
if(!git.commitFile(vault, file, "final A")) return fail("commitFile A", git.lastError());
|
||||
const int histA = git.fileHistory(vault, file).size();
|
||||
// правим оба файла
|
||||
QFile fa(file);
|
||||
fa.open(QIODevice::WriteOnly | QIODevice::Append); fa.write("more A\n"); fa.close();
|
||||
QFile fb(vault+"/other.md");
|
||||
fb.open(QIODevice::WriteOnly | QIODevice::Append); fb.write("more B\n"); fb.close();
|
||||
const int histBBefore = git.fileHistory(vault, vault+"/other.md").size();
|
||||
if(!git.commitFile(vault, file, "final B")) return fail("commitFile B", git.lastError());
|
||||
if(git.fileHistory(vault, file).size() != histA + 1) return fail("commitFile history A");
|
||||
if(git.fileHistory(vault, vault+"/other.md").size() != histBBefore) return fail("commitFile затронул B");
|
||||
if(!git.fileHistory(vault, file).first().toMap().value("message").toString().contains("final B"))
|
||||
return fail("commitFile message");
|
||||
// commitFile без изменений — false с понятной ошибкой, как commitAll
|
||||
if(git.commitFile(vault, file, "noop")) return fail("commitFile noop should fail");
|
||||
}
|
||||
|
||||
std::printf("GIT HISTORY TEST OK (forward/backward, diff, restore, time)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user