mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-07-02 04:47:01 +08:00
Upgrade to latest dart-git
Most of dart-git's operations are synchronous by default now. The async functions run on another isolate.
This commit is contained in:
@ -4,15 +4,20 @@
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
import 'package:dart_git/blob_ctime_builder.dart';
|
import 'package:dart_git/blob_ctime_builder.dart';
|
||||||
import 'package:dart_git/dart_git.dart';
|
import 'package:dart_git/dart_git.dart';
|
||||||
|
import 'package:dart_git/exceptions.dart';
|
||||||
import 'package:dart_git/file_mtime_builder.dart';
|
import 'package:dart_git/file_mtime_builder.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
import 'package:universal_io/io.dart' as io;
|
import 'package:universal_io/io.dart' as io;
|
||||||
|
|
||||||
|
import 'package:gitjournal/error_reporting.dart';
|
||||||
import 'package:gitjournal/logger/logger.dart';
|
import 'package:gitjournal/logger/logger.dart';
|
||||||
import 'file.dart';
|
import 'file.dart';
|
||||||
|
|
||||||
@ -25,21 +30,7 @@ class FileStorage with ChangeNotifier {
|
|||||||
var _dateTime = DateTime.now();
|
var _dateTime = DateTime.now();
|
||||||
DateTime get dateTime => _dateTime;
|
DateTime get dateTime => _dateTime;
|
||||||
|
|
||||||
TreeEntryVisitor get visitor {
|
var head = GitHash.zero();
|
||||||
return MultiTreeEntryVisitor(
|
|
||||||
[
|
|
||||||
blobCTimeBuilder,
|
|
||||||
fileMTimeBuilder,
|
|
||||||
],
|
|
||||||
afterCommitCallback: (commit) {
|
|
||||||
var commitDt = commit.author.date;
|
|
||||||
if (commitDt.isBefore(_dateTime)) {
|
|
||||||
_dateTime = commitDt;
|
|
||||||
}
|
|
||||||
notifyListeners();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileStorage({
|
FileStorage({
|
||||||
required String repoPath,
|
required String repoPath,
|
||||||
@ -96,20 +87,50 @@ class FileStorage with ChangeNotifier {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> fill() async {
|
||||||
|
var rp = ReceivePort();
|
||||||
|
rp.listen((d) {
|
||||||
|
if (d is DateTime) {
|
||||||
|
_dateTime = d;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var resp = await compute(
|
||||||
|
_fillFileStorage,
|
||||||
|
_FillFileStorageParams(
|
||||||
|
rp.sendPort,
|
||||||
|
repoPath,
|
||||||
|
blobCTimeBuilder,
|
||||||
|
fileMTimeBuilder,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
rp.close();
|
||||||
|
|
||||||
|
// FIXME: Handle this case of having an error!
|
||||||
|
assert(resp != null);
|
||||||
|
if (resp == null) return;
|
||||||
|
|
||||||
|
blobCTimeBuilder.update(resp.item1);
|
||||||
|
fileMTimeBuilder.update(resp.item2);
|
||||||
|
head = resp.item3;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
static Future<FileStorage> fake(String rootFolder) async {
|
static Future<FileStorage> fake(String rootFolder) async {
|
||||||
assert(rootFolder.startsWith(p.separator));
|
assert(rootFolder.startsWith(p.separator));
|
||||||
|
|
||||||
await GitRepository.init(rootFolder).throwOnError();
|
GitRepository.init(rootFolder).throwOnError();
|
||||||
|
|
||||||
var blobVisitor = BlobCTimeBuilder();
|
var blobVisitor = BlobCTimeBuilder();
|
||||||
var mTimeBuilder = FileMTimeBuilder();
|
var mTimeBuilder = FileMTimeBuilder();
|
||||||
|
|
||||||
var repo = await GitRepository.load(rootFolder).getOrThrow();
|
var repo = GitRepository.load(rootFolder).getOrThrow();
|
||||||
var result = await repo.headHash();
|
var result = repo.headHash();
|
||||||
if (result.isSuccess) {
|
if (result.isSuccess) {
|
||||||
var multi = MultiTreeEntryVisitor([blobVisitor, mTimeBuilder]);
|
var multi = MultiTreeEntryVisitor([blobVisitor, mTimeBuilder]);
|
||||||
await repo
|
repo
|
||||||
.visitTree(fromCommitHash: result.getOrThrow(), visitor: multi)
|
.visitTree(fromCommitHash: result.getOrThrow(), visitor: multi)
|
||||||
.throwOnError();
|
.throwOnError();
|
||||||
}
|
}
|
||||||
@ -128,17 +149,7 @@ class FileStorage with ChangeNotifier {
|
|||||||
|
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
Future<Result<void>> reload() async {
|
Future<Result<void>> reload() async {
|
||||||
var gitRepo = await GitRepository.load(repoPath).getOrThrow();
|
await fill();
|
||||||
var result = await gitRepo.headHash();
|
|
||||||
if (result.isFailure) {
|
|
||||||
return fail(result);
|
|
||||||
}
|
|
||||||
var headHash = result.getOrThrow();
|
|
||||||
|
|
||||||
var multi = MultiTreeEntryVisitor([blobCTimeBuilder, fileMTimeBuilder]);
|
|
||||||
await gitRepo
|
|
||||||
.visitTree(fromCommitHash: headHash, visitor: multi)
|
|
||||||
.throwOnError();
|
|
||||||
return Result(null);
|
return Result(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,3 +158,53 @@ class FileStorageCacheIncomplete implements Exception {
|
|||||||
final String path;
|
final String path;
|
||||||
FileStorageCacheIncomplete(this.path);
|
FileStorageCacheIncomplete(this.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef _FillFileStorageParams
|
||||||
|
= Tuple4<SendPort, String, BlobCTimeBuilder, FileMTimeBuilder>;
|
||||||
|
|
||||||
|
typedef _FillFileStorageOutput
|
||||||
|
= Tuple3<BlobCTimeBuilder, FileMTimeBuilder, GitHash>;
|
||||||
|
|
||||||
|
_FillFileStorageOutput? _fillFileStorage(_FillFileStorageParams params) {
|
||||||
|
var sendPort = params.item1;
|
||||||
|
var repoPath = params.item2;
|
||||||
|
var blobCTimeBuilder = params.item3;
|
||||||
|
var fileMTimeBuilder = params.item4;
|
||||||
|
|
||||||
|
var dateTime = DateTime.now();
|
||||||
|
var visitor = MultiTreeEntryVisitor(
|
||||||
|
[blobCTimeBuilder, fileMTimeBuilder],
|
||||||
|
afterCommitCallback: (commit) {
|
||||||
|
var commitDt = commit.author.date;
|
||||||
|
if (commitDt.isBefore(dateTime)) {
|
||||||
|
dateTime = commitDt;
|
||||||
|
sendPort.send(dateTime);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
var gitRepo = GitRepository.load(repoPath).getOrThrow();
|
||||||
|
var headR = gitRepo.headHash();
|
||||||
|
if (headR.isFailure) {
|
||||||
|
if (headR.error is GitRefNotFound) {
|
||||||
|
// No commits
|
||||||
|
// fileStorageCacheReady = true;
|
||||||
|
// notifyListeners();
|
||||||
|
// FIXME: Send a signal saying its done
|
||||||
|
return _FillFileStorageOutput(
|
||||||
|
blobCTimeBuilder, fileMTimeBuilder, GitHash.zero());
|
||||||
|
}
|
||||||
|
Log.e("Failed to fetch HEAD", result: headR);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var head = headR.getOrThrow();
|
||||||
|
Log.d("Got HEAD: $head");
|
||||||
|
|
||||||
|
var result = gitRepo.visitTree(fromCommitHash: head, visitor: visitor);
|
||||||
|
if (result.isFailure) {
|
||||||
|
Log.e("Failed to build FileStorage cache", result: result);
|
||||||
|
logException(result.exception!, result.stackTrace!);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _FillFileStorageOutput(blobCTimeBuilder, fileMTimeBuilder, head);
|
||||||
|
}
|
||||||
|
@ -66,9 +66,7 @@ class FileStorageCache {
|
|||||||
|
|
||||||
Future<Result<void>> save(FileStorage fileStorage) async {
|
Future<Result<void>> save(FileStorage fileStorage) async {
|
||||||
return catchAll(() async {
|
return catchAll(() async {
|
||||||
var repo = await GitRepository.load(fileStorage.repoPath).getOrThrow();
|
lastProcessedHead = fileStorage.head;
|
||||||
var headR = await repo.headHash();
|
|
||||||
lastProcessedHead = headR.isFailure ? GitHash.zero() : headR.getOrThrow();
|
|
||||||
|
|
||||||
var blobCTimeBuilder = fileStorage.blobCTimeBuilder;
|
var blobCTimeBuilder = fileStorage.blobCTimeBuilder;
|
||||||
var fileMTimeBUilder = fileStorage.fileMTimeBuilder;
|
var fileMTimeBUilder = fileStorage.fileMTimeBuilder;
|
||||||
@ -83,7 +81,7 @@ class FileStorageCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String get _cTimeFilePath => p.join(cacheFolderPath, 'blob_ctime_v1');
|
String get _cTimeFilePath => p.join(cacheFolderPath, 'blob_ctime_v1');
|
||||||
String get _mTimeFilePath => p.join(cacheFolderPath, 'file_mtime_v1');
|
String get _mTimeFilePath => p.join(cacheFolderPath, 'file_mtime_v2');
|
||||||
|
|
||||||
Future<Tuple2<BlobCTimeBuilder, GitHash>> _buildCTimeBuilder() async {
|
Future<Tuple2<BlobCTimeBuilder, GitHash>> _buildCTimeBuilder() async {
|
||||||
var file = io.File(_cTimeFilePath);
|
var file = io.File(_cTimeFilePath);
|
||||||
|
@ -24,6 +24,9 @@ import 'package:gitjournal/utils/git_desktop.dart';
|
|||||||
|
|
||||||
bool useDartGit = false;
|
bool useDartGit = false;
|
||||||
|
|
||||||
|
// FIXME: Remember to close all the opened repos!!
|
||||||
|
// FIXME: Micro optimization? Avoid re-creating the GitAsyncRepository!
|
||||||
|
|
||||||
class GitNoteRepository {
|
class GitNoteRepository {
|
||||||
final String gitRepoPath;
|
final String gitRepoPath;
|
||||||
final gb.GitRepo _gitRepo;
|
final gb.GitRepo _gitRepo;
|
||||||
@ -43,7 +46,7 @@ class GitNoteRepository {
|
|||||||
|
|
||||||
Future<Result<void>> _add(String pathSpec) async {
|
Future<Result<void>> _add(String pathSpec) async {
|
||||||
if (useDartGit || AppConfig.instance.experimentalGitOps) {
|
if (useDartGit || AppConfig.instance.experimentalGitOps) {
|
||||||
var repo = await GitRepository.load(gitRepoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(gitRepoPath).getOrThrow();
|
||||||
await repo.add(pathSpec).throwOnError();
|
await repo.add(pathSpec).throwOnError();
|
||||||
return Result(null);
|
return Result(null);
|
||||||
} else {
|
} else {
|
||||||
@ -59,7 +62,7 @@ class GitNoteRepository {
|
|||||||
|
|
||||||
Future<Result<void>> _rm(String pathSpec) async {
|
Future<Result<void>> _rm(String pathSpec) async {
|
||||||
if (useDartGit || AppConfig.instance.experimentalGitOps) {
|
if (useDartGit || AppConfig.instance.experimentalGitOps) {
|
||||||
var repo = await GitRepository.load(gitRepoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(gitRepoPath).getOrThrow();
|
||||||
return await repo.rm(pathSpec);
|
return await repo.rm(pathSpec);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@ -78,7 +81,7 @@ class GitNoteRepository {
|
|||||||
required String authorName,
|
required String authorName,
|
||||||
}) async {
|
}) async {
|
||||||
if (useDartGit || AppConfig.instance.experimentalGitOps) {
|
if (useDartGit || AppConfig.instance.experimentalGitOps) {
|
||||||
var repo = await GitRepository.load(gitRepoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(gitRepoPath).getOrThrow();
|
||||||
var author = GitAuthor(name: authorName, email: authorEmail);
|
var author = GitAuthor(name: authorName, email: authorEmail);
|
||||||
var r = await repo.commit(message: message, author: author);
|
var r = await repo.commit(message: message, author: author);
|
||||||
if (r.isFailure) {
|
if (r.isFailure) {
|
||||||
@ -209,7 +212,7 @@ class GitNoteRepository {
|
|||||||
|
|
||||||
Future<Result<void>> resetLastCommit() async {
|
Future<Result<void>> resetLastCommit() async {
|
||||||
if (useDartGit || AppConfig.instance.experimentalGitOps) {
|
if (useDartGit || AppConfig.instance.experimentalGitOps) {
|
||||||
var repo = await GitRepository.load(gitRepoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(gitRepoPath).getOrThrow();
|
||||||
var headCommitR = await repo.headCommit();
|
var headCommitR = await repo.headCommit();
|
||||||
if (headCommitR.isFailure) {
|
if (headCommitR.isFailure) {
|
||||||
return fail(headCommitR);
|
return fail(headCommitR);
|
||||||
@ -268,7 +271,7 @@ class GitNoteRepository {
|
|||||||
Future<Result<void>> merge() => catchAll(_merge);
|
Future<Result<void>> merge() => catchAll(_merge);
|
||||||
|
|
||||||
Future<Result<void>> _merge() async {
|
Future<Result<void>> _merge() async {
|
||||||
var repo = await GitRepository.load(gitRepoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(gitRepoPath).getOrThrow();
|
||||||
var branch = await repo.currentBranch().getOrThrow();
|
var branch = await repo.currentBranch().getOrThrow();
|
||||||
|
|
||||||
var branchConfig = repo.config.branch(branch);
|
var branchConfig = repo.config.branch(branch);
|
||||||
@ -316,7 +319,7 @@ class GitNoteRepository {
|
|||||||
Future<Result<void>> push() async {
|
Future<Result<void>> push() async {
|
||||||
// Only push if we have something we need to push
|
// Only push if we have something we need to push
|
||||||
try {
|
try {
|
||||||
var repo = await GitRepository.load(gitRepoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(gitRepoPath).getOrThrow();
|
||||||
var canPush = await repo.canPush().getOrThrow();
|
var canPush = await repo.canPush().getOrThrow();
|
||||||
if (!canPush) {
|
if (!canPush) {
|
||||||
return Result(null);
|
return Result(null);
|
||||||
@ -365,7 +368,7 @@ class GitNoteRepository {
|
|||||||
|
|
||||||
Future<int?> numChanges() async {
|
Future<int?> numChanges() async {
|
||||||
try {
|
try {
|
||||||
var repo = await GitRepository.load(gitRepoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(gitRepoPath).getOrThrow();
|
||||||
var nResult = await repo.numChangesToPush();
|
var nResult = await repo.numChangesToPush();
|
||||||
if (nResult.isSuccess) {
|
if (nResult.isSuccess) {
|
||||||
return nResult.getOrThrow();
|
return nResult.getOrThrow();
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
|
|
||||||
import 'package:dart_git/dart_git.dart';
|
import 'package:dart_git/dart_git.dart';
|
||||||
import 'package:dart_git/diff_commit.dart';
|
import 'package:dart_git/diff_commit.dart';
|
||||||
@ -43,10 +44,10 @@ class _CommitDataWidgetState extends State<CommitDataWidget> {
|
|||||||
_initStateAsync();
|
_initStateAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _initStateAsync() async {
|
void _initStateAsync() {
|
||||||
// FIXME: Run all of this in another worker thread!
|
// FIXME: Run all of this in another worker thread!
|
||||||
|
|
||||||
var r = await diffCommits(
|
var r = diffCommits(
|
||||||
fromCommit: widget.parentCommit,
|
fromCommit: widget.parentCommit,
|
||||||
toCommit: widget.commit,
|
toCommit: widget.commit,
|
||||||
objStore: widget.gitRepo.objStorage,
|
objStore: widget.gitRepo.objStorage,
|
||||||
@ -54,7 +55,7 @@ class _CommitDataWidgetState extends State<CommitDataWidget> {
|
|||||||
if (r.isFailure) {
|
if (r.isFailure) {
|
||||||
Log.e("Got exception in diffCommits",
|
Log.e("Got exception in diffCommits",
|
||||||
ex: r.error, stacktrace: r.stackTrace);
|
ex: r.error, stacktrace: r.stackTrace);
|
||||||
return setState(() {
|
setState(() {
|
||||||
_exception = r.exception;
|
_exception = r.exception;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -131,11 +132,11 @@ class __BlobLoaderState extends State<_BlobLoader> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
_initStateAsync();
|
SchedulerBinding.instance!.addPostFrameCallback((_) => _initStateAsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _initStateAsync() async {
|
void _initStateAsync() {
|
||||||
var result = await widget.gitRepo.objStorage.readBlob(widget.blobHash);
|
var result = widget.gitRepo.objStorage.readBlob(widget.blobHash);
|
||||||
setState(() {
|
setState(() {
|
||||||
_exception = result.exception;
|
_exception = result.exception;
|
||||||
_blob = result.data;
|
_blob = result.data;
|
||||||
|
@ -8,7 +8,7 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:dart_git/git.dart';
|
import 'package:dart_git/dart_git.dart';
|
||||||
import 'package:dart_git/plumbing/commit_iterator.dart';
|
import 'package:dart_git/plumbing/commit_iterator.dart';
|
||||||
import 'package:dart_git/plumbing/objects/commit.dart';
|
import 'package:dart_git/plumbing/objects/commit.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
@ -59,7 +59,7 @@ class _HistoryWidgetState extends State<HistoryWidget> {
|
|||||||
List<Result<GitCommit>> commits = [];
|
List<Result<GitCommit>> commits = [];
|
||||||
List<dynamic> commitsAndSyncAttempts = [];
|
List<dynamic> commitsAndSyncAttempts = [];
|
||||||
|
|
||||||
Stream<Result<GitCommit>>? _stream;
|
Iterable<Result<GitCommit>>? _stream;
|
||||||
|
|
||||||
final _scrollController = ScrollController();
|
final _scrollController = ScrollController();
|
||||||
final _lock = Lock();
|
final _lock = Lock();
|
||||||
@ -109,7 +109,7 @@ class _HistoryWidgetState extends State<HistoryWidget> {
|
|||||||
var stream = _stream!;
|
var stream = _stream!;
|
||||||
|
|
||||||
var list = <Result<GitCommit>>[];
|
var list = <Result<GitCommit>>[];
|
||||||
await for (var commit in stream.take(20)) {
|
for (var commit in stream.take(20)) {
|
||||||
list.add(commit);
|
list.add(commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,20 +120,19 @@ class _HistoryWidgetState extends State<HistoryWidget> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Stream<Result<GitCommit>>> _initStream() async {
|
Future<Iterable<Result<GitCommit>>> _initStream() async {
|
||||||
try {
|
try {
|
||||||
_gitRepo = await GitRepository.load(widget.repoPath).getOrThrow();
|
_gitRepo = GitRepository.load(widget.repoPath).getOrThrow();
|
||||||
var head = await _gitRepo!.headHash().getOrThrow();
|
var head = _gitRepo!.headHash().getOrThrow();
|
||||||
return commitPreOrderIterator(
|
return commitPreOrderIterator(
|
||||||
objStorage: _gitRepo!.objStorage, from: head)
|
objStorage: _gitRepo!.objStorage, from: head);
|
||||||
.asBroadcastStream();
|
|
||||||
} on Exception catch (ex) {
|
} on Exception catch (ex) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_exception = ex;
|
_exception = ex;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return const Stream.empty();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
void _rebuildCombined() {
|
void _rebuildCombined() {
|
||||||
|
@ -135,7 +135,7 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
|
|
||||||
if (!repoDir.existsSync()) {
|
if (!repoDir.existsSync()) {
|
||||||
Log.i("Calling GitInit for ${storageConfig.folderName} at: $repoPath");
|
Log.i("Calling GitInit for ${storageConfig.folderName} at: $repoPath");
|
||||||
var r = await GitRepository.init(repoPath, defaultBranch: 'main');
|
var r = GitRepository.init(repoPath, defaultBranch: DEFAULT_BRANCH);
|
||||||
if (r.isFailure) {
|
if (r.isFailure) {
|
||||||
Log.e("GitInit Failed", result: r);
|
Log.e("GitInit Failed", result: r);
|
||||||
return fail(r);
|
return fail(r);
|
||||||
@ -144,7 +144,7 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
storageConfig.save();
|
storageConfig.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
var valid = await GitRepository.isValidRepo(repoPath);
|
var valid = GitRepository.isValidRepo(repoPath);
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
// What happened that the directory still exists but the .git folder
|
// What happened that the directory still exists but the .git folder
|
||||||
// has disappeared?
|
// has disappeared?
|
||||||
@ -154,7 +154,7 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
return Result.fail(ex);
|
return Result.fail(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
var repoR = await GitRepository.load(repoPath);
|
var repoR = await GitAsyncRepository.load(repoPath);
|
||||||
if (repoR.isFailure) {
|
if (repoR.isFailure) {
|
||||||
return fail(repoR);
|
return fail(repoR);
|
||||||
}
|
}
|
||||||
@ -164,6 +164,7 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
if (!storageConfig.storeInternally) {
|
if (!storageConfig.storeInternally) {
|
||||||
var r = await _commitUnTrackedChanges(repo, gitConfig);
|
var r = await _commitUnTrackedChanges(repo, gitConfig);
|
||||||
if (r.isFailure) {
|
if (r.isFailure) {
|
||||||
|
repo.close();
|
||||||
return fail(r);
|
return fail(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,6 +193,8 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
currentBranch: await repo.currentBranch().getOrThrow(),
|
currentBranch: await repo.currentBranch().getOrThrow(),
|
||||||
headHash: head,
|
headHash: head,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
repo.close();
|
||||||
return Result(gjRepo);
|
return Result(gjRepo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +271,7 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
var r = await rootFolder.loadRecursively();
|
var r = await rootFolder.loadRecursively();
|
||||||
if (r.isFailure) {
|
if (r.isFailure) {
|
||||||
if (r.error is FileStorageCacheIncomplete) {
|
if (r.error is FileStorageCacheIncomplete) {
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(repoPath).getOrThrow();
|
||||||
await _commitUnTrackedChanges(repo, gitConfig);
|
await _commitUnTrackedChanges(repo, gitConfig);
|
||||||
await _resetFileStorage();
|
await _resetFileStorage();
|
||||||
return;
|
return;
|
||||||
@ -287,33 +290,11 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> __fillFileStorageCache() async {
|
Future<void> __fillFileStorageCache() async {
|
||||||
var gitRepo = await GitRepository.load(repoPath).getOrThrow();
|
|
||||||
var headR = await gitRepo.headHash();
|
|
||||||
if (headR.isFailure) {
|
|
||||||
if (headR.error is GitRefNotFound) {
|
|
||||||
// No commits
|
|
||||||
fileStorageCacheReady = true;
|
|
||||||
notifyListeners();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Log.e("Failed to fetch HEAD", result: headR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var head = headR.getOrThrow();
|
|
||||||
Log.d("Got HEAD: $head");
|
|
||||||
|
|
||||||
var startTime = DateTime.now();
|
var startTime = DateTime.now();
|
||||||
var result = await gitRepo.visitTree(
|
await fileStorage.fill();
|
||||||
fromCommitHash: head,
|
|
||||||
visitor: fileStorage.visitor,
|
|
||||||
);
|
|
||||||
var endTime = DateTime.now().difference(startTime);
|
var endTime = DateTime.now().difference(startTime);
|
||||||
|
|
||||||
Log.i("Built Git Time Cache - $endTime");
|
Log.i("Built Git Time Cache - $endTime");
|
||||||
if (result.isFailure) {
|
|
||||||
Log.e("Failed to build FileStorage cache", result: result);
|
|
||||||
logException(result.exception!, result.stackTrace!);
|
|
||||||
}
|
|
||||||
|
|
||||||
var r = await fileStorageCache.save(fileStorage);
|
var r = await fileStorageCache.save(fileStorage);
|
||||||
if (r.isFailure) {
|
if (r.isFailure) {
|
||||||
@ -321,10 +302,7 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
logException(r.exception!, r.stackTrace!);
|
logException(r.exception!, r.stackTrace!);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileStorageCache.lastProcessedHead != head) {
|
assert(fileStorageCache.lastProcessedHead == fileStorage.head);
|
||||||
Log.e(
|
|
||||||
"FileStorageCache Head different ${fileStorageCache.lastProcessedHead}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify that the cache is ready
|
// Notify that the cache is ready
|
||||||
fileStorageCacheReady = true;
|
fileStorageCacheReady = true;
|
||||||
@ -342,7 +320,7 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
Future<void> syncNotes({bool doNotThrow = false}) async {
|
Future<void> syncNotes({bool doNotThrow = false}) async {
|
||||||
// This is extremely slow with dart-git, can take over a second!
|
// This is extremely slow with dart-git, can take over a second!
|
||||||
if (_shouldCheckForChanges()) {
|
if (_shouldCheckForChanges()) {
|
||||||
var repoR = await GitRepository.load(repoPath);
|
var repoR = await GitAsyncRepository.load(repoPath);
|
||||||
if (repoR.isFailure) {
|
if (repoR.isFailure) {
|
||||||
Log.e("SyncNotes Failed to Load Repo", result: repoR);
|
Log.e("SyncNotes Failed to Load Repo", result: repoR);
|
||||||
return;
|
return;
|
||||||
@ -747,7 +725,7 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
|
|
||||||
Future<void> discardChanges(Note note) async {
|
Future<void> discardChanges(Note note) async {
|
||||||
// FIXME: Add the checkout method to GJRepo
|
// FIXME: Add the checkout method to GJRepo
|
||||||
var gitRepo = await GitRepository.load(repoPath).getOrThrow();
|
var gitRepo = await GitAsyncRepository.load(repoPath).getOrThrow();
|
||||||
await gitRepo.checkout(note.filePath).throwOnError();
|
await gitRepo.checkout(note.filePath).throwOnError();
|
||||||
|
|
||||||
// FIXME: Instead of this just reload that specific file
|
// FIXME: Instead of this just reload that specific file
|
||||||
@ -756,12 +734,12 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<List<GitRemoteConfig>> remoteConfigs() async {
|
Future<List<GitRemoteConfig>> remoteConfigs() async {
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(repoPath).getOrThrow();
|
||||||
return repo.config.remotes;
|
return repo.config.remotes;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<String>> branches() async {
|
Future<List<String>> branches() async {
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(repoPath).getOrThrow();
|
||||||
var branches = Set<String>.from(await repo.branches().getOrThrow());
|
var branches = Set<String>.from(await repo.branches().getOrThrow());
|
||||||
if (repo.config.remotes.isNotEmpty) {
|
if (repo.config.remotes.isNotEmpty) {
|
||||||
var remoteName = repo.config.remotes.first.name;
|
var remoteName = repo.config.remotes.first.name;
|
||||||
@ -777,11 +755,12 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
|
|
||||||
Future<String> checkoutBranch(String branchName) async {
|
Future<String> checkoutBranch(String branchName) async {
|
||||||
Log.i("Changing branch to $branchName");
|
Log.i("Changing branch to $branchName");
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(repoPath).getOrThrow();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var created = await createBranchIfRequired(repo, branchName);
|
var created = await createBranchIfRequired(repo, branchName);
|
||||||
if (created.isEmpty) {
|
if (created.isEmpty) {
|
||||||
|
repo.close();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
} catch (ex, st) {
|
} catch (ex, st) {
|
||||||
@ -800,12 +779,15 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
} catch (e, st) {
|
} catch (e, st) {
|
||||||
Log.e("Checkout Branch Failed", ex: e, stacktrace: st);
|
Log.e("Checkout Branch Failed", ex: e, stacktrace: st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repo.close();
|
||||||
return branchName;
|
return branchName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Why does this need to return a string?
|
// FIXME: Why does this need to return a string?
|
||||||
/// throws exceptions
|
/// throws exceptions
|
||||||
Future<String> createBranchIfRequired(GitRepository repo, String name) async {
|
Future<String> createBranchIfRequired(
|
||||||
|
GitAsyncRepository repo, String name) async {
|
||||||
var localBranches = await repo.branches().getOrThrow();
|
var localBranches = await repo.branches().getOrThrow();
|
||||||
if (localBranches.contains(name)) {
|
if (localBranches.contains(name)) {
|
||||||
return name;
|
return name;
|
||||||
@ -824,8 +806,8 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
await repo.createBranch(name, hash: remoteBranchRef.hash).throwOnError();
|
repo.createBranch(name, hash: remoteBranchRef.hash).throwOnError();
|
||||||
await repo.setBranchUpstreamTo(name, remoteConfig, name).throwOnError();
|
repo.setBranchUpstreamTo(name, remoteConfig, name).throwOnError();
|
||||||
|
|
||||||
Log.i("Created branch $name");
|
Log.i("Created branch $name");
|
||||||
return name;
|
return name;
|
||||||
@ -840,7 +822,8 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
/// reset --hard the current branch to its remote branch
|
/// reset --hard the current branch to its remote branch
|
||||||
Future<Result<void>> resetHard() {
|
Future<Result<void>> resetHard() {
|
||||||
return catchAll(() async {
|
return catchAll(() async {
|
||||||
var repo = await GitRepository.load(_gitRepo.gitRepoPath).getOrThrow();
|
var repo =
|
||||||
|
await GitAsyncRepository.load(_gitRepo.gitRepoPath).getOrThrow();
|
||||||
var branchName = await repo.currentBranch().getOrThrow();
|
var branchName = await repo.currentBranch().getOrThrow();
|
||||||
var branchConfig = repo.config.branch(branchName);
|
var branchConfig = repo.config.branch(branchName);
|
||||||
if (branchConfig == null) {
|
if (branchConfig == null) {
|
||||||
@ -866,7 +849,8 @@ class GitJournalRepo with ChangeNotifier {
|
|||||||
|
|
||||||
Future<Result<bool>> canResetHard() {
|
Future<Result<bool>> canResetHard() {
|
||||||
return catchAll(() async {
|
return catchAll(() async {
|
||||||
var repo = await GitRepository.load(_gitRepo.gitRepoPath).getOrThrow();
|
var repo =
|
||||||
|
await GitAsyncRepository.load(_gitRepo.gitRepoPath).getOrThrow();
|
||||||
var branchName = await repo.currentBranch().getOrThrow();
|
var branchName = await repo.currentBranch().getOrThrow();
|
||||||
var branchConfig = repo.config.branch(branchName);
|
var branchConfig = repo.config.branch(branchName);
|
||||||
if (branchConfig == null) {
|
if (branchConfig == null) {
|
||||||
@ -930,7 +914,7 @@ Future<void> _ensureOneCommitInRepo({
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Result<void>> _commitUnTrackedChanges(
|
Future<Result<void>> _commitUnTrackedChanges(
|
||||||
GitRepository repo, GitConfig gitConfig) async {
|
GitAsyncRepository repo, GitConfig gitConfig) async {
|
||||||
var timer = Stopwatch()..start();
|
var timer = Stopwatch()..start();
|
||||||
//
|
//
|
||||||
// Check for un-committed files and save them
|
// Check for un-committed files and save them
|
||||||
|
@ -23,6 +23,8 @@ const SETTINGS_VERSION = 3;
|
|||||||
const DEFAULT_LIGHT_THEME_NAME = "LightDefault";
|
const DEFAULT_LIGHT_THEME_NAME = "LightDefault";
|
||||||
const DEFAULT_DARK_THEME_NAME = "DarkDefault";
|
const DEFAULT_DARK_THEME_NAME = "DarkDefault";
|
||||||
|
|
||||||
|
const DEFAULT_BRANCH = 'main';
|
||||||
|
|
||||||
class Settings extends ChangeNotifier with SettingsSharedPref {
|
class Settings extends ChangeNotifier with SettingsSharedPref {
|
||||||
Settings(this.id, this.pref);
|
Settings(this.id, this.pref);
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ class _GitRemoteSettingsScreenState extends State<GitRemoteSettingsScreen> {
|
|||||||
while (true) {
|
while (true) {
|
||||||
var repoFolderPath = p.join(gitDir, "$repoFolderName$num");
|
var repoFolderPath = p.join(gitDir, "$repoFolderName$num");
|
||||||
if (!Directory(repoFolderPath).existsSync()) {
|
if (!Directory(repoFolderPath).existsSync()) {
|
||||||
var r = await GitRepository.init(repoFolderPath, defaultBranch: 'main');
|
var r = GitRepository.init(repoFolderPath, defaultBranch: 'main');
|
||||||
showResultError(context, r);
|
showResultError(context, r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,10 @@ import 'package:path/path.dart' as p;
|
|||||||
import 'package:universal_io/io.dart' show Directory;
|
import 'package:universal_io/io.dart' show Directory;
|
||||||
|
|
||||||
import 'package:gitjournal/logger/logger.dart';
|
import 'package:gitjournal/logger/logger.dart';
|
||||||
|
import 'package:gitjournal/settings/settings.dart';
|
||||||
import 'git_transfer_progress.dart';
|
import 'git_transfer_progress.dart';
|
||||||
|
|
||||||
const DefaultBranchName = 'main';
|
const DefaultBranchName = DEFAULT_BRANCH;
|
||||||
|
|
||||||
typedef GitFetchFunction = Future<Result<void>> Function(
|
typedef GitFetchFunction = Future<Result<void>> Function(
|
||||||
String repoPath,
|
String repoPath,
|
||||||
@ -56,7 +57,7 @@ Future<Result<void>> cloneRemotePluggable({
|
|||||||
required GitDefaultBranchFunction defaultBranchFn,
|
required GitDefaultBranchFunction defaultBranchFn,
|
||||||
required GitMergeFn gitMergeFn,
|
required GitMergeFn gitMergeFn,
|
||||||
}) async {
|
}) async {
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = await GitAsyncRepository.load(repoPath).getOrThrow();
|
||||||
var remote = await repo.addOrUpdateRemote(remoteName, cloneUrl).getOrThrow();
|
var remote = await repo.addOrUpdateRemote(remoteName, cloneUrl).getOrThrow();
|
||||||
|
|
||||||
var statusFile = p.join(Directory.systemTemp.path, 'gj');
|
var statusFile = p.join(Directory.systemTemp.path, 'gj');
|
||||||
@ -73,12 +74,14 @@ Future<Result<void>> cloneRemotePluggable({
|
|||||||
timer.cancel();
|
timer.cancel();
|
||||||
if (fetchR.isFailure) {
|
if (fetchR.isFailure) {
|
||||||
// FIXME: Give a better error?
|
// FIXME: Give a better error?
|
||||||
|
repo.close();
|
||||||
return fail(fetchR);
|
return fail(fetchR);
|
||||||
}
|
}
|
||||||
|
|
||||||
var branchNameR = await defaultBranchFn(
|
var branchNameR = await defaultBranchFn(
|
||||||
repoPath, remoteName, sshPublicKey, sshPrivateKey, sshPassword);
|
repoPath, remoteName, sshPublicKey, sshPrivateKey, sshPassword);
|
||||||
if (branchNameR.isFailure) {
|
if (branchNameR.isFailure) {
|
||||||
|
repo.close();
|
||||||
return fail(branchNameR);
|
return fail(branchNameR);
|
||||||
}
|
}
|
||||||
var remoteBranchName = branchNameR.getOrThrow();
|
var remoteBranchName = branchNameR.getOrThrow();
|
||||||
@ -101,6 +104,7 @@ Future<Result<void>> cloneRemotePluggable({
|
|||||||
var remoteBranchR = await repo.remoteBranch(remoteName, remoteBranchName);
|
var remoteBranchR = await repo.remoteBranch(remoteName, remoteBranchName);
|
||||||
if (remoteBranchR.isFailure) {
|
if (remoteBranchR.isFailure) {
|
||||||
if (remoteBranchR.error is! GitNotFound) {
|
if (remoteBranchR.error is! GitNotFound) {
|
||||||
|
repo.close();
|
||||||
return fail(remoteBranchR);
|
return fail(remoteBranchR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +148,7 @@ Future<Result<void>> cloneRemotePluggable({
|
|||||||
var r = await gitMergeFn(
|
var r = await gitMergeFn(
|
||||||
repoPath, remoteName, remoteBranchName, authorName, authorEmail);
|
repoPath, remoteName, remoteBranchName, authorName, authorEmail);
|
||||||
if (r.isFailure) {
|
if (r.isFailure) {
|
||||||
|
repo.close();
|
||||||
return fail(r);
|
return fail(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,6 +164,7 @@ Future<Result<void>> cloneRemotePluggable({
|
|||||||
var r = await gitMergeFn(
|
var r = await gitMergeFn(
|
||||||
repoPath, remoteName, remoteBranchName, authorName, authorEmail);
|
repoPath, remoteName, remoteBranchName, authorName, authorEmail);
|
||||||
if (r.isFailure) {
|
if (r.isFailure) {
|
||||||
|
repo.close();
|
||||||
return fail(r);
|
return fail(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,10 +179,12 @@ Future<Result<void>> cloneRemotePluggable({
|
|||||||
if (!skipCheckout) {
|
if (!skipCheckout) {
|
||||||
var r = await repo.checkout(".");
|
var r = await repo.checkout(".");
|
||||||
if (r.isFailure) {
|
if (r.isFailure) {
|
||||||
|
repo.close();
|
||||||
return fail(r);
|
return fail(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repo.close();
|
||||||
return Result(null);
|
return Result(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,9 +81,9 @@ Future<Result<void>> _merge(
|
|||||||
String authorEmail,
|
String authorEmail,
|
||||||
) {
|
) {
|
||||||
return catchAll(() async {
|
return catchAll(() async {
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = GitRepository.load(repoPath).getOrThrow();
|
||||||
var author = GitAuthor(name: authorName, email: authorEmail);
|
var author = GitAuthor(name: authorName, email: authorEmail);
|
||||||
await repo.mergeCurrentTrackingBranch(author: author).throwOnError();
|
repo.mergeCurrentTrackingBranch(author: author).throwOnError();
|
||||||
return Result(null);
|
return Result(null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,8 @@ Future<Result<String>> _defaultBranch(
|
|||||||
Log.w("Could not fetch git Default Branch", ex: ex);
|
Log.w("Could not fetch git Default Branch", ex: ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = GitRepository.load(repoPath).getOrThrow();
|
||||||
var remoteBranch = await repo.guessRemoteHead(remoteName);
|
var remoteBranch = repo.guessRemoteHead(remoteName);
|
||||||
if (remoteBranch == null) {
|
if (remoteBranch == null) {
|
||||||
return Result(null);
|
return Result(null);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'package:dart_git/git.dart';
|
import 'package:dart_git/dart_git.dart';
|
||||||
import 'package:dots_indicator/dots_indicator.dart';
|
import 'package:dots_indicator/dots_indicator.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:function_types/function_types.dart';
|
import 'package:function_types/function_types.dart';
|
||||||
@ -426,20 +426,20 @@ class GitHostSetupScreenState extends State<GitHostSetupScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _removeRemote() async {
|
void _removeRemote() {
|
||||||
var repo = context.read<GitJournalRepo>();
|
var repo = context.read<GitJournalRepo>();
|
||||||
var basePath = repo.gitBaseDirectory;
|
var basePath = repo.gitBaseDirectory;
|
||||||
|
|
||||||
var repoPath = p.join(basePath, widget.repoFolderName);
|
var repoPath = p.join(basePath, widget.repoFolderName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!await GitRepository.isValidRepo(repoPath)) {
|
if (!GitRepository.isValidRepo(repoPath)) {
|
||||||
var r = await GitRepository.init(repoPath, defaultBranch: 'main');
|
var r = GitRepository.init(repoPath, defaultBranch: 'main');
|
||||||
showResultError(context, r);
|
showResultError(context, r);
|
||||||
}
|
}
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = GitRepository.load(repoPath).getOrThrow();
|
||||||
if (repo.config.remote(widget.remoteName) != null) {
|
if (repo.config.remote(widget.remoteName) != null) {
|
||||||
await repo.removeRemote(widget.remoteName).throwOnError();
|
repo.removeRemote(widget.remoteName).throwOnError();
|
||||||
}
|
}
|
||||||
} catch (e, stacktrace) {
|
} catch (e, stacktrace) {
|
||||||
Log.e("Failed to remove remote", ex: e, stacktrace: stacktrace);
|
Log.e("Failed to remove remote", ex: e, stacktrace: stacktrace);
|
||||||
@ -571,7 +571,7 @@ class GitHostSetupScreenState extends State<GitHostSetupScreen> {
|
|||||||
if (cloneR.isFailure) {
|
if (cloneR.isFailure) {
|
||||||
Log.e("Failed to clone", ex: cloneR.error, stacktrace: cloneR.stackTrace);
|
Log.e("Failed to clone", ex: cloneR.error, stacktrace: cloneR.stackTrace);
|
||||||
var error = cloneR.error.toString();
|
var error = cloneR.error.toString();
|
||||||
await _removeRemote();
|
_removeRemote();
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
logEvent(Event.GitHostSetupGitCloneError, parameters: {
|
logEvent(Event.GitHostSetupGitCloneError, parameters: {
|
||||||
|
@ -13,6 +13,7 @@ import 'package:dart_git/utils/result.dart';
|
|||||||
import 'package:universal_io/io.dart';
|
import 'package:universal_io/io.dart';
|
||||||
|
|
||||||
import 'package:gitjournal/logger/logger.dart';
|
import 'package:gitjournal/logger/logger.dart';
|
||||||
|
import 'package:gitjournal/settings/settings.dart';
|
||||||
|
|
||||||
Future<Result<void>> gitFetchViaExecutable({
|
Future<Result<void>> gitFetchViaExecutable({
|
||||||
required String repoPath,
|
required String repoPath,
|
||||||
@ -60,7 +61,7 @@ Future<Result<void>> _gitCommandViaExecutable({
|
|||||||
var dir = Directory.systemTemp.createTempSync();
|
var dir = Directory.systemTemp.createTempSync();
|
||||||
var temp = File("${dir.path}/key");
|
var temp = File("${dir.path}/key");
|
||||||
_ = await temp.writeAsString(privateKey);
|
_ = await temp.writeAsString(privateKey);
|
||||||
await temp.chmod(int.parse('0600', radix: 8));
|
temp.chmodSync(int.parse('0600', radix: 8));
|
||||||
|
|
||||||
Log.i("Running git $command $remoteName");
|
Log.i("Running git $command $remoteName");
|
||||||
var process = await Process.start(
|
var process = await Process.start(
|
||||||
@ -113,7 +114,7 @@ Future<Result<String>> gitDefaultBranchViaExecutable({
|
|||||||
var dir = Directory.systemTemp.createTempSync();
|
var dir = Directory.systemTemp.createTempSync();
|
||||||
var temp = File("${dir.path}/key");
|
var temp = File("${dir.path}/key");
|
||||||
_ = await temp.writeAsString(privateKey);
|
_ = await temp.writeAsString(privateKey);
|
||||||
await temp.chmod(int.parse('0600', radix: 8));
|
temp.chmodSync(int.parse('0600', radix: 8));
|
||||||
|
|
||||||
var process = await Process.start(
|
var process = await Process.start(
|
||||||
'git',
|
'git',
|
||||||
@ -147,9 +148,8 @@ Future<Result<String>> gitDefaultBranchViaExecutable({
|
|||||||
for (var line in LineSplitter.split(stdout)) {
|
for (var line in LineSplitter.split(stdout)) {
|
||||||
if (line.contains('HEAD branch:')) {
|
if (line.contains('HEAD branch:')) {
|
||||||
var branch = line.split(':')[1].trim();
|
var branch = line.split(':')[1].trim();
|
||||||
// Everyone seems to default to 'main' these days
|
|
||||||
if (branch == '(unknown)') {
|
if (branch == '(unknown)') {
|
||||||
return Result('main');
|
return Result(DEFAULT_BRANCH);
|
||||||
}
|
}
|
||||||
return Result(branch);
|
return Result(branch);
|
||||||
}
|
}
|
||||||
|
@ -346,7 +346,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: HEAD
|
ref: HEAD
|
||||||
resolved-ref: f1cb3b0376a2f3222a84b034906f156b237766d3
|
resolved-ref: d02e1ea8712a31d1e51211091de7b56e6f2158b8
|
||||||
url: "https://github.com/GitJournal/dart-git.git"
|
url: "https://github.com/GitJournal/dart-git.git"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.2"
|
version: "0.0.2"
|
||||||
|
@ -58,7 +58,7 @@ void main() {
|
|||||||
var tempDir = await io.Directory.systemTemp.createTemp('__fnft__');
|
var tempDir = await io.Directory.systemTemp.createTemp('__fnft__');
|
||||||
var repoPath = tempDir.path;
|
var repoPath = tempDir.path;
|
||||||
|
|
||||||
await GitRepository.init(repoPath).throwOnError();
|
GitRepository.init(repoPath).throwOnError();
|
||||||
|
|
||||||
var fileStorage = FileStorage(
|
var fileStorage = FileStorage(
|
||||||
repoPath: repoPath,
|
repoPath: repoPath,
|
||||||
@ -74,12 +74,19 @@ void main() {
|
|||||||
|
|
||||||
var deepEq = const DeepCollectionEquality().equals;
|
var deepEq = const DeepCollectionEquality().equals;
|
||||||
expect(
|
expect(
|
||||||
deepEq(fileStorage2.blobCTimeBuilder.processedCommits, commits), true);
|
deepEq(fileStorage2.blobCTimeBuilder.processedCommits.set, commits),
|
||||||
expect(deepEq(fileStorage2.blobCTimeBuilder.processedTrees, trees), true);
|
true,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
deepEq(fileStorage2.blobCTimeBuilder.processedTrees.set, trees),
|
||||||
|
true,
|
||||||
|
);
|
||||||
expect(deepEq(fileStorage2.blobCTimeBuilder.map, cMap), true);
|
expect(deepEq(fileStorage2.blobCTimeBuilder.map, cMap), true);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
deepEq(fileStorage2.fileMTimeBuilder.processedCommits, commits), true);
|
deepEq(fileStorage2.fileMTimeBuilder.processedCommits.set, commits),
|
||||||
|
true,
|
||||||
|
);
|
||||||
expect(deepEq(fileStorage2.fileMTimeBuilder.map, mMap), true);
|
expect(deepEq(fileStorage2.fileMTimeBuilder.map, mMap), true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -108,8 +108,8 @@ void main() {
|
|||||||
await storage.save(note).throwOnError();
|
await storage.save(note).throwOnError();
|
||||||
}
|
}
|
||||||
|
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = GitRepository.load(repoPath).getOrThrow();
|
||||||
await repo
|
repo
|
||||||
.commit(
|
.commit(
|
||||||
message: "Prepare Test Env",
|
message: "Prepare Test Env",
|
||||||
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
||||||
|
@ -42,8 +42,8 @@ void main() {
|
|||||||
await _writeRandomNote(random, repoPath, config, fileStorage);
|
await _writeRandomNote(random, repoPath, config, fileStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = GitRepository.load(repoPath).getOrThrow();
|
||||||
await repo
|
repo
|
||||||
.commit(
|
.commit(
|
||||||
message: "Prepare Test Env",
|
message: "Prepare Test Env",
|
||||||
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
||||||
@ -72,8 +72,8 @@ void main() {
|
|||||||
var newFileStorage = await FileStorage.fake(newRepoPath);
|
var newFileStorage = await FileStorage.fake(newRepoPath);
|
||||||
await _writeRandomNote(Random(), newRepoPath, config, newFileStorage);
|
await _writeRandomNote(Random(), newRepoPath, config, newFileStorage);
|
||||||
|
|
||||||
var repo = await GitRepository.load(newRepoPath).getOrThrow();
|
var repo = GitRepository.load(newRepoPath).getOrThrow();
|
||||||
await repo
|
repo
|
||||||
.commit(
|
.commit(
|
||||||
message: "Prepare Test Env",
|
message: "Prepare Test Env",
|
||||||
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
||||||
|
@ -109,8 +109,8 @@ void main() {
|
|||||||
await storage.save(note).throwOnError();
|
await storage.save(note).throwOnError();
|
||||||
}
|
}
|
||||||
|
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = GitRepository.load(repoPath).getOrThrow();
|
||||||
await repo
|
repo
|
||||||
.commit(
|
.commit(
|
||||||
message: "Prepare Test Env",
|
message: "Prepare Test Env",
|
||||||
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
||||||
|
@ -46,8 +46,8 @@ void main() {
|
|||||||
await generateNote(repoPath, "zeplin.txt");
|
await generateNote(repoPath, "zeplin.txt");
|
||||||
await generateNote(repoPath, "Goat Sim.md");
|
await generateNote(repoPath, "Goat Sim.md");
|
||||||
|
|
||||||
var repo = await GitRepository.load(repoPath).getOrThrow();
|
var repo = GitRepository.load(repoPath).getOrThrow();
|
||||||
await repo
|
repo
|
||||||
.commit(
|
.commit(
|
||||||
message: "Prepare Test Env",
|
message: "Prepare Test Env",
|
||||||
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
||||||
|
@ -67,8 +67,8 @@ void main() {
|
|||||||
|
|
||||||
notes = [n1, n2];
|
notes = [n1, n2];
|
||||||
|
|
||||||
var repo = await GitRepository.load(tempDir.path).getOrThrow();
|
var repo = GitRepository.load(tempDir.path).getOrThrow();
|
||||||
await repo
|
repo
|
||||||
.commit(
|
.commit(
|
||||||
message: "Prepare Test Env",
|
message: "Prepare Test Env",
|
||||||
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
author: GitAuthor(name: 'Name', email: "name@example.com"),
|
||||||
|
@ -28,7 +28,7 @@ Future<void> populateWithData(SharedPreferences pref) async {
|
|||||||
var dir = await getApplicationDocumentsDirectory();
|
var dir = await getApplicationDocumentsDirectory();
|
||||||
|
|
||||||
var repoPath = p.join(dir.path, "journal_local");
|
var repoPath = p.join(dir.path, "journal_local");
|
||||||
await GitRepository.init(repoPath);
|
GitRepository.init(repoPath);
|
||||||
|
|
||||||
stderr.writeln("Filling fake data in $repoPath");
|
stderr.writeln("Filling fake data in $repoPath");
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user