Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions asyncgit/src/blame.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
error::Result,
hash,
sync::{self, FileBlame, RepoPath},
sync::{self, CommitId, FileBlame, RepoPath},
AsyncGitNotification,
};
use crossbeam_channel::Sender;
Expand All @@ -18,6 +18,8 @@ use std::{
pub struct BlameParams {
/// path to the file to blame
pub file_path: String,
/// blame at a specific revision
pub commit_id: Option<CommitId>,
}

struct Request<R, A>(R, Option<A>);
Expand Down Expand Up @@ -145,8 +147,11 @@ impl AsyncBlame {
arc_current: &Arc<Mutex<Request<u64, FileBlame>>>,
hash: u64,
) -> Result<bool> {
let file_blame =
sync::blame::blame_file(repo_path, &params.file_path)?;
let file_blame = sync::blame::blame_file(
repo_path,
&params.file_path,
params.commit_id,
)?;

let mut notify = false;
{
Expand Down
2 changes: 2 additions & 0 deletions asyncgit/src/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,13 @@ impl AsyncDiff {
repo_path,
id,
params.path.clone(),
Some(params.options),
)?,
DiffType::Commits(ids) => sync::diff::get_diff_commits(
repo_path,
ids,
params.path.clone(),
Some(params.options),
)?,
};

Expand Down
2 changes: 1 addition & 1 deletion asyncgit/src/revlog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl AsyncLog {
}

///
pub fn count(&mut self) -> Result<usize> {
pub fn count(&self) -> Result<usize> {
Ok(self.current.lock()?.len())
}

Expand Down
29 changes: 21 additions & 8 deletions asyncgit/src/sync/blame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
error::{Error, Result},
sync::{get_commits_info, repository::repo},
};
use git2::BlameOptions;
use scopetime::scope_time;
use std::collections::{HashMap, HashSet};
use std::io::{BufRead, BufReader};
Expand Down Expand Up @@ -56,12 +57,17 @@ fn fixup_windows_path(path: &str) -> String {
pub fn blame_file(
repo_path: &RepoPath,
file_path: &str,
commit_id: Option<CommitId>,
) -> Result<FileBlame> {
scope_time!("blame_file");

let repo = repo(repo_path)?;

let commit_id = utils::get_head_repo(&repo)?;
let commit_id = if let Some(commit_id) = commit_id {
commit_id
} else {
utils::get_head_repo(&repo)?
};

let spec = format!(
"{}:{}",
Expand All @@ -76,7 +82,11 @@ pub fn blame_file(
return Err(Error::NoBlameOnBinaryFile);
}

let blame = repo.blame_file(Path::new(file_path), None)?;
let mut opts = BlameOptions::new();
opts.newest_commit(commit_id.into());

let blame =
repo.blame_file(Path::new(file_path), Some(&mut opts))?;

let reader = BufReader::new(blob.content());

Expand Down Expand Up @@ -160,15 +170,18 @@ mod tests {
let repo_path: &RepoPath =
&root.as_os_str().to_str().unwrap().into();

assert!(matches!(blame_file(&repo_path, "foo"), Err(_)));
assert!(matches!(
blame_file(&repo_path, "foo", None),
Err(_)
));

File::create(&root.join(file_path))?
.write_all(b"line 1\n")?;

stage_add_file(repo_path, file_path)?;
commit(repo_path, "first commit")?;

let blame = blame_file(&repo_path, "foo")?;
let blame = blame_file(&repo_path, "foo", None)?;

assert!(matches!(
blame.lines.as_slice(),
Expand All @@ -192,7 +205,7 @@ mod tests {
stage_add_file(repo_path, file_path)?;
commit(repo_path, "second commit")?;

let blame = blame_file(&repo_path, "foo")?;
let blame = blame_file(&repo_path, "foo", None)?;

assert!(matches!(
blame.lines.as_slice(),
Expand All @@ -219,14 +232,14 @@ mod tests {

file.write(b"line 3\n")?;

let blame = blame_file(&repo_path, "foo")?;
let blame = blame_file(&repo_path, "foo", None)?;

assert_eq!(blame.lines.len(), 2);

stage_add_file(repo_path, file_path)?;
commit(repo_path, "third commit")?;

let blame = blame_file(&repo_path, "foo")?;
let blame = blame_file(&repo_path, "foo", None)?;

assert_eq!(blame.lines.len(), 3);

Expand All @@ -251,6 +264,6 @@ mod tests {
stage_add_file(repo_path, file_path).unwrap();
commit(repo_path, "first commit").unwrap();

assert!(blame_file(&repo_path, "bar\\foo").is_ok());
assert!(blame_file(&repo_path, "bar\\foo", None).is_ok());
}
}
27 changes: 21 additions & 6 deletions asyncgit/src/sync/commit_files.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//! Functions for getting infos about files in commits

use super::{stash::is_stash_commit, CommitId, RepoPath};
use super::{
diff::DiffOptions, stash::is_stash_commit, CommitId, RepoPath,
};
use crate::{
error::Result, sync::repository::repo, StatusItem, StatusItemType,
};
use git2::{Diff, DiffOptions, Repository};
use git2::{Diff, Repository};
use scopetime::scope_time;
use std::cmp::Ordering;

Expand All @@ -19,9 +21,9 @@ pub fn get_commit_files(
let repo = repo(repo_path)?;

let diff = if let Some(other) = other {
get_compare_commits_diff(&repo, (id, other), None)?
get_compare_commits_diff(&repo, (id, other), None, None)?
} else {
get_commit_diff(repo_path, &repo, id, None)?
get_commit_diff(repo_path, &repo, id, None, None)?
};

let res = diff
Expand Down Expand Up @@ -49,6 +51,7 @@ pub fn get_compare_commits_diff(
repo: &Repository,
ids: (CommitId, CommitId),
pathspec: Option<String>,
options: Option<DiffOptions>,
) -> Result<Diff<'_>> {
// scope_time!("get_compare_commits_diff");

Expand All @@ -67,7 +70,12 @@ pub fn get_compare_commits_diff(

let trees = (commits.0.tree()?, commits.1.tree()?);

let mut opts = DiffOptions::new();
let mut opts = git2::DiffOptions::new();
if let Some(options) = options {
opts.context_lines(options.context);
opts.ignore_whitespace(options.ignore_whitespace);
opts.interhunk_lines(options.interhunk_lines);
}
if let Some(p) = &pathspec {
opts.pathspec(p.clone());
}
Expand All @@ -88,6 +96,7 @@ pub fn get_commit_diff<'a>(
repo: &'a Repository,
id: CommitId,
pathspec: Option<String>,
options: Option<DiffOptions>,
) -> Result<Diff<'a>> {
// scope_time!("get_commit_diff");

Expand All @@ -102,7 +111,12 @@ pub fn get_commit_diff<'a>(
None
};

let mut opts = DiffOptions::new();
let mut opts = git2::DiffOptions::new();
if let Some(options) = options {
opts.context_lines(options.context);
opts.ignore_whitespace(options.ignore_whitespace);
opts.interhunk_lines(options.interhunk_lines);
}
if let Some(p) = &pathspec {
opts.pathspec(p.clone());
}
Expand All @@ -121,6 +135,7 @@ pub fn get_commit_diff<'a>(
repo,
CommitId::new(untracked_commit),
pathspec,
options,
)?;

diff.merge(&untracked_diff)?;
Expand Down
16 changes: 12 additions & 4 deletions asyncgit/src/sync/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,14 @@ pub fn get_diff_commit(
repo_path: &RepoPath,
id: CommitId,
p: String,
options: Option<DiffOptions>,
) -> Result<FileDiff> {
scope_time!("get_diff_commit");

let repo = repo(repo_path)?;
let work_dir = work_dir(&repo)?;
let diff = get_commit_diff(repo_path, &repo, id, Some(p))?;
let diff =
get_commit_diff(repo_path, &repo, id, Some(p), options)?;

raw_diff_to_file_diff(&diff, work_dir)
}
Expand All @@ -229,13 +231,18 @@ pub fn get_diff_commits(
repo_path: &RepoPath,
ids: (CommitId, CommitId),
p: String,
options: Option<DiffOptions>,
) -> Result<FileDiff> {
scope_time!("get_diff_commits");

let repo = repo(repo_path)?;
let work_dir = work_dir(&repo)?;
let diff =
get_compare_commits_diff(&repo, (ids.0, ids.1), Some(p))?;
let diff = get_compare_commits_diff(
&repo,
(ids.0, ids.1),
Some(p),
options,
)?;

raw_diff_to_file_diff(&diff, work_dir)
}
Expand Down Expand Up @@ -649,7 +656,8 @@ mod tests {
let id = commit(repo_path, "").unwrap();

let diff =
get_diff_commit(repo_path, id, String::new()).unwrap();
get_diff_commit(repo_path, id, String::new(), None)
.unwrap();

dbg!(&diff);
assert_eq!(diff.sizes, (1, 2));
Expand Down
1 change: 1 addition & 0 deletions asyncgit/src/sync/logwalker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub fn diff_contains_file(
repo,
*commit_id,
Some(file_path.clone()),
None,
)?;

let contains_file = diff.deltas().len() > 0;
Expand Down
5 changes: 3 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ impl App {
sender,
theme.clone(),
key_config.clone(),
options.clone(),
),
revision_files_popup: RevisionFilesPopup::new(
repo.clone(),
Expand Down Expand Up @@ -714,8 +715,8 @@ impl App {
InternalEvent::TagCommit(id) => {
self.tag_commit_popup.open(id)?;
}
InternalEvent::BlameFile(path) => {
self.blame_file_popup.open(&path)?;
InternalEvent::BlameFile(path, commit_id) => {
self.blame_file_popup.open(&path, commit_id)?;
flags
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
}
Expand Down
Loading