Merge pull request #3789 from gitbutlerapp/gitbutler-tracked-data-files-implementation

setup for async tasks on oplog update
This commit is contained in:
Kiril Videlov 2024-05-19 16:07:40 +02:00 committed by GitHub
commit bb1b5ce0e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 35 additions and 1 deletions

View File

@ -3,3 +3,5 @@ pub mod oplog;
mod reflog; mod reflog;
pub mod snapshot; pub mod snapshot;
mod state; mod state;
pub const OPLOG_FILE_NAME: &str = "operations-log.toml";

View File

@ -7,6 +7,8 @@ use std::{
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::OPLOG_FILE_NAME;
/// This tracks the head of the oplog, persisted in operations-log.toml. /// This tracks the head of the oplog, persisted in operations-log.toml.
#[derive(Serialize, Deserialize, Debug, Default)] #[derive(Serialize, Deserialize, Debug, Default)]
pub struct Oplog { pub struct Oplog {
@ -22,7 +24,7 @@ pub struct OplogHandle {
impl OplogHandle { impl OplogHandle {
/// Creates a new concurrency-safe handle to the state of the oplog. /// Creates a new concurrency-safe handle to the state of the oplog.
pub fn new(base_path: &Path) -> Self { pub fn new(base_path: &Path) -> Self {
let file_path = base_path.join("operations-log.toml"); let file_path = base_path.join(OPLOG_FILE_NAME);
Self { file_path } Self { file_path }
} }

View File

@ -13,6 +13,8 @@ pub(super) enum InternalEvent {
// From file monitor // From file monitor
GitFilesChange(ProjectId, Vec<PathBuf>), GitFilesChange(ProjectId, Vec<PathBuf>),
ProjectFilesChange(ProjectId, Vec<PathBuf>), ProjectFilesChange(ProjectId, Vec<PathBuf>),
// Triggered on change in the `.git/gitbutler` directory
GitButlerOplogChange(ProjectId),
} }
/// This type captures all operations that can be fed into a watcher that runs in the background. /// This type captures all operations that can be fed into a watcher that runs in the background.
@ -52,6 +54,9 @@ impl Display for InternalEvent {
comma_separated_paths(paths) comma_separated_paths(paths)
) )
} }
InternalEvent::GitButlerOplogChange(project_id) => {
write!(f, "GitButlerOplogChange({})", project_id)
}
InternalEvent::ProjectFilesChange(project_id, paths) => { InternalEvent::ProjectFilesChange(project_id, paths) => {
write!( write!(
f, f,

View File

@ -10,6 +10,7 @@ use notify_debouncer_full::new_debouncer;
use tokio::task; use tokio::task;
use tracing::Level; use tracing::Level;
use gitbutler_core::ops::OPLOG_FILE_NAME;
/// The timeout for debouncing file change events. /// The timeout for debouncing file change events.
/// This is used to prevent multiple events from being sent for a single file change. /// This is used to prevent multiple events from being sent for a single file change.
const DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(100); const DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(100);
@ -114,12 +115,16 @@ pub fn spawn(
.map_or(FileKind::Project, |repo| classify_file(repo, &file)); .map_or(FileKind::Project, |repo| classify_file(repo, &file));
(file, kind) (file, kind)
}); });
let mut oplog_changed = false;
let (mut stripped_git_paths, mut worktree_relative_paths) = let (mut stripped_git_paths, mut worktree_relative_paths) =
(HashSet::new(), HashSet::new()); (HashSet::new(), HashSet::new());
for (file_path, kind) in classified_file_paths { for (file_path, kind) in classified_file_paths {
match kind { match kind {
FileKind::ProjectIgnored => ignored += 1, FileKind::ProjectIgnored => ignored += 1,
FileKind::GitUninteresting => git_noop += 1, FileKind::GitUninteresting => git_noop += 1,
FileKind::GitButlerOplog => {
oplog_changed = true;
}
FileKind::Project | FileKind::Git => match file_path FileKind::Project | FileKind::Git => match file_path
.strip_prefix(&worktree_path) .strip_prefix(&worktree_path)
{ {
@ -165,6 +170,13 @@ pub fn spawn(
break 'outer; break 'outer;
} }
} }
if oplog_changed {
let event = InternalEvent::GitButlerOplogChange(project_id);
if out.send(event).is_err() {
tracing::info!("channel closed - stopping file watcher");
break 'outer;
}
}
} }
} }
} }
@ -201,6 +213,8 @@ enum FileKind {
Project, Project,
/// A file that was ignored in the project, and thus shouldn't trigger a computation. /// A file that was ignored in the project, and thus shouldn't trigger a computation.
ProjectIgnored, ProjectIgnored,
/// GitButler oplog file (`.git/gitbutler/operations-log.toml`)
GitButlerOplog,
} }
fn classify_file(git_repo: &git::Repository, file_path: &Path) -> FileKind { fn classify_file(git_repo: &git::Repository, file_path: &Path) -> FileKind {
@ -212,6 +226,8 @@ fn classify_file(git_repo: &git::Repository, file_path: &Path) -> FileKind {
|| check_file_path == Path::new("index") || check_file_path == Path::new("index")
{ {
FileKind::Git FileKind::Git
} else if check_file_path == Path::new("gitbutler").join(OPLOG_FILE_NAME) {
FileKind::GitButlerOplog
} else { } else {
FileKind::GitUninteresting FileKind::GitUninteresting
} }

View File

@ -60,6 +60,11 @@ impl Handler {
.await .await
.context("failed to handle git file change event"), .context("failed to handle git file change event"),
events::InternalEvent::GitButlerOplogChange(project_id) => self
.gitbutler_oplog_change(project_id)
.await
.context("failed to handle gitbutler oplog change event"),
// This is only produced at the end of mutating Tauri commands to trigger a fresh state being served to the UI. // This is only produced at the end of mutating Tauri commands to trigger a fresh state being served to the UI.
events::InternalEvent::CalculateVirtualBranches(project_id) => self events::InternalEvent::CalculateVirtualBranches(project_id) => self
.calculate_virtual_branches(project_id) .calculate_virtual_branches(project_id)
@ -181,4 +186,8 @@ impl Handler {
} }
Ok(()) Ok(())
} }
async fn gitbutler_oplog_change(&self, _project_id: ProjectId) -> Result<()> {
// TODO: Queue up pushing of data here, if configured
Ok(())
}
} }