Detailed changes
@@ -1005,7 +1005,6 @@ impl Database {
is_last_update: true,
merge_message: db_repository_entry.merge_message,
stash_entries: Vec::new(),
- renamed_paths: Default::default(),
});
}
}
@@ -796,7 +796,6 @@ impl Database {
is_last_update: true,
merge_message: db_repository.merge_message,
stash_entries: Vec::new(),
- renamed_paths: Default::default(),
});
}
}
@@ -359,7 +359,6 @@ impl GitRepository for FakeGitRepository {
entries.sort_by(|a, b| a.0.cmp(&b.0));
anyhow::Ok(GitStatus {
entries: entries.into(),
- renamed_paths: HashMap::default(),
})
});
Task::ready(match result {
@@ -2045,7 +2045,7 @@ fn git_status_args(path_prefixes: &[RepoPath]) -> Vec<OsString> {
OsString::from("status"),
OsString::from("--porcelain=v1"),
OsString::from("--untracked-files=all"),
- OsString::from("--find-renames"),
+ OsString::from("--no-renames"),
OsString::from("-z"),
];
args.extend(
@@ -203,14 +203,6 @@ impl FileStatus {
matches!(self, FileStatus::Untracked)
}
- pub fn is_renamed(self) -> bool {
- let FileStatus::Tracked(tracked) = self else {
- return false;
- };
- tracked.index_status == StatusCode::Renamed
- || tracked.worktree_status == StatusCode::Renamed
- }
-
pub fn summary(self) -> GitSummary {
match self {
FileStatus::Ignored => GitSummary::UNCHANGED,
@@ -438,79 +430,34 @@ impl std::ops::Sub for GitSummary {
#[derive(Clone, Debug)]
pub struct GitStatus {
pub entries: Arc<[(RepoPath, FileStatus)]>,
- pub renamed_paths: HashMap<RepoPath, RepoPath>,
}
impl FromStr for GitStatus {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
- let mut parts = s.split('\0').peekable();
- let mut entries = Vec::new();
- let mut renamed_paths = HashMap::default();
-
- while let Some(entry) = parts.next() {
- if entry.is_empty() {
- continue;
- }
-
- if !matches!(entry.get(2..3), Some(" ")) {
- continue;
- }
-
- let path_or_old_path = &entry[3..];
-
- if path_or_old_path.ends_with('/') {
- continue;
- }
-
- let status = match entry.as_bytes()[0..2].try_into() {
- Ok(bytes) => match FileStatus::from_bytes(bytes).log_err() {
- Some(s) => s,
- None => continue,
- },
- Err(_) => continue,
- };
-
- let is_rename = matches!(
- status,
- FileStatus::Tracked(TrackedStatus {
- index_status: StatusCode::Renamed | StatusCode::Copied,
- ..
- }) | FileStatus::Tracked(TrackedStatus {
- worktree_status: StatusCode::Renamed | StatusCode::Copied,
- ..
- })
- );
-
- let (old_path_str, new_path_str) = if is_rename {
- let new_path = match parts.next() {
- Some(new_path) if !new_path.is_empty() => new_path,
- _ => continue,
+ let mut entries = s
+ .split('\0')
+ .filter_map(|entry| {
+ let sep = entry.get(2..3)?;
+ if sep != " " {
+ return None;
};
- (path_or_old_path, new_path)
- } else {
- (path_or_old_path, path_or_old_path)
- };
-
- if new_path_str.ends_with('/') {
- continue;
- }
-
- let new_path = match RelPath::unix(new_path_str).log_err() {
- Some(p) => RepoPath::from_rel_path(p),
- None => continue,
- };
-
- if is_rename {
- if let Some(old_path_rel) = RelPath::unix(old_path_str).log_err() {
- let old_path_repo = RepoPath::from_rel_path(old_path_rel);
- renamed_paths.insert(new_path.clone(), old_path_repo);
+ let path = &entry[3..];
+ // The git status output includes untracked directories as well as untracked files.
+ // We do our own processing to compute the "summary" status of each directory,
+ // so just skip any directories in the output, since they'll otherwise interfere
+ // with our handling of nested repositories.
+ if path.ends_with('/') {
+ return None;
}
- }
-
- entries.push((new_path, status));
- }
+ let status = entry.as_bytes()[0..2].try_into().unwrap();
+ let status = FileStatus::from_bytes(status).log_err()?;
+ // git-status outputs `/`-delimited repo paths, even on Windows.
+ let path = RepoPath::from_rel_path(RelPath::unix(path).log_err()?);
+ Some((path, status))
+ })
+ .collect::<Vec<_>>();
entries.sort_unstable_by(|(a, _), (b, _)| a.cmp(b));
// When a file exists in HEAD, is deleted in the index, and exists again in the working copy,
// git produces two lines for it, one reading `D ` (deleted in index, unmodified in working copy)
@@ -534,7 +481,6 @@ impl FromStr for GitStatus {
});
Ok(Self {
entries: entries.into(),
- renamed_paths,
})
}
}
@@ -543,7 +489,6 @@ impl Default for GitStatus {
fn default() -> Self {
Self {
entries: Arc::new([]),
- renamed_paths: HashMap::default(),
}
}
}
@@ -3957,20 +3957,6 @@ impl GitPanel {
let path_style = self.project.read(cx).path_style(cx);
let display_name = entry.display_name(path_style);
- let active_repo = self
- .project
- .read(cx)
- .active_repository(cx)
- .expect("active repository must be set");
- let repo = active_repo.read(cx);
- let repo_snapshot = repo.snapshot();
-
- let old_path = if entry.status.is_renamed() {
- repo_snapshot.renamed_paths.get(&entry.repo_path)
- } else {
- None
- };
-
let selected = self.selected_entry == Some(ix);
let marked = self.marked_entries.contains(&ix);
let status_style = GitPanelSettings::get_global(cx).status_style;
@@ -3979,16 +3965,15 @@ impl GitPanel {
let has_conflict = status.is_conflicted();
let is_modified = status.is_modified();
let is_deleted = status.is_deleted();
- let is_renamed = status.is_renamed();
let label_color = if status_style == StatusStyle::LabelColor {
if has_conflict {
Color::VersionControlConflict
+ } else if is_modified {
+ Color::VersionControlModified
} else if is_deleted {
// We don't want a bunch of red labels in the list
Color::Disabled
- } else if is_renamed || is_modified {
- Color::VersionControlModified
} else {
Color::VersionControlAdded
}
@@ -4008,6 +3993,12 @@ impl GitPanel {
let checkbox_id: ElementId =
ElementId::Name(format!("entry_{}_{}_checkbox", display_name, ix).into());
+ let active_repo = self
+ .project
+ .read(cx)
+ .active_repository(cx)
+ .expect("active repository must be set");
+ let repo = active_repo.read(cx);
// Checking for current staged/unstaged file status is a chained operation:
// 1. first, we check for any pending operation recorded in repository
// 2. if there are no pending ops either running or finished, we then ask the repository
@@ -4162,32 +4153,23 @@ impl GitPanel {
.items_center()
.flex_1()
// .overflow_hidden()
- .when_some(old_path.as_ref(), |this, old_path| {
- let new_display = old_path.display(path_style).to_string();
- let old_display = entry.repo_path.display(path_style).to_string();
- this.child(self.entry_label(old_display, Color::Muted).strikethrough())
- .child(self.entry_label(" → ", Color::Muted))
- .child(self.entry_label(new_display, label_color))
- })
- .when(old_path.is_none(), |this| {
- this.when_some(entry.parent_dir(path_style), |this, parent| {
- if !parent.is_empty() {
- this.child(
- self.entry_label(
- format!("{parent}{}", path_style.separator()),
- path_color,
- )
- .when(status.is_deleted(), |this| this.strikethrough()),
+ .when_some(entry.parent_dir(path_style), |this, parent| {
+ if !parent.is_empty() {
+ this.child(
+ self.entry_label(
+ format!("{parent}{}", path_style.separator()),
+ path_color,
)
- } else {
- this
- }
- })
- .child(
- self.entry_label(display_name, label_color)
.when(status.is_deleted(), |this| this.strikethrough()),
- )
- }),
+ )
+ } else {
+ this
+ }
+ })
+ .child(
+ self.entry_label(display_name, label_color)
+ .when(status.is_deleted(), |this| this.strikethrough()),
+ ),
)
.into_any_element()
}
@@ -708,11 +708,6 @@ impl RenderOnce for GitStatusIcon {
IconName::SquareMinus,
cx.theme().colors().version_control_deleted,
)
- } else if status.is_renamed() {
- (
- IconName::ArrowRight,
- cx.theme().colors().version_control_modified,
- )
} else if status.is_modified() {
(
IconName::SquareDot,
@@ -256,7 +256,6 @@ pub struct RepositorySnapshot {
pub id: RepositoryId,
pub statuses_by_path: SumTree<StatusEntry>,
pub pending_ops_by_path: SumTree<PendingOps>,
- pub renamed_paths: HashMap<RepoPath, RepoPath>,
pub work_directory_abs_path: Arc<Path>,
pub path_style: PathStyle,
pub branch: Option<Branch>,
@@ -3064,7 +3063,6 @@ impl RepositorySnapshot {
id,
statuses_by_path: Default::default(),
pending_ops_by_path: Default::default(),
- renamed_paths: HashMap::default(),
work_directory_abs_path,
branch: None,
head_commit: None,
@@ -3106,11 +3104,6 @@ impl RepositorySnapshot {
.iter()
.map(stash_to_proto)
.collect(),
- renamed_paths: self
- .renamed_paths
- .iter()
- .map(|(new_path, old_path)| (new_path.to_proto(), old_path.to_proto()))
- .collect(),
}
}
@@ -3180,11 +3173,6 @@ impl RepositorySnapshot {
.iter()
.map(stash_to_proto)
.collect(),
- renamed_paths: self
- .renamed_paths
- .iter()
- .map(|(new_path, old_path)| (new_path.to_proto(), old_path.to_proto()))
- .collect(),
}
}
@@ -4980,17 +4968,6 @@ impl Repository {
}
self.snapshot.stash_entries = new_stash_entries;
- self.snapshot.renamed_paths = update
- .renamed_paths
- .into_iter()
- .filter_map(|(new_path_str, old_path_str)| {
- Some((
- RepoPath::from_proto(&new_path_str).log_err()?,
- RepoPath::from_proto(&old_path_str).log_err()?,
- ))
- })
- .collect();
-
let edits = update
.removed_statuses
.into_iter()
@@ -5766,7 +5743,6 @@ async fn compute_snapshot(
id,
statuses_by_path,
pending_ops_by_path,
- renamed_paths: statuses.renamed_paths,
work_directory_abs_path,
path_style: prev_snapshot.path_style,
scan_id: prev_snapshot.scan_id + 1,
@@ -124,7 +124,6 @@ message UpdateRepository {
optional GitCommitDetails head_commit_details = 11;
optional string merge_message = 12;
repeated StashEntry stash_entries = 13;
- map<string, string> renamed_paths = 14;
}
message RemoveRepository {