mirror of
https://github.com/martinvonz/jj.git
synced 2025-02-06 11:34:54 +00:00
working_copy: get conflict id from the current tree
This prepares for allowing the base tree to be a conflict at the root-tree level (#1624). We could remove the `Conflict` variant completely. I tried doing that and it slowed down `jj diff` by ~3% in the Linux repo with a clean working copy with only mtime bumped on all files.
This commit is contained in:
parent
3ca42908ee
commit
dc8a207737
3 changed files with 20 additions and 21 deletions
|
@ -29,7 +29,7 @@ message FileState {
|
|||
uint64 size = 2;
|
||||
FileType file_type = 3;
|
||||
// Set only if file_type is Conflict
|
||||
bytes conflict_id = 4;
|
||||
bytes conflict_id = 4 [deprecated = true];
|
||||
}
|
||||
|
||||
message SparsePatterns {
|
||||
|
|
|
@ -8,6 +8,7 @@ pub struct FileState {
|
|||
#[prost(enumeration = "FileType", tag = "3")]
|
||||
pub file_type: i32,
|
||||
/// Set only if file_type is Conflict
|
||||
#[deprecated]
|
||||
#[prost(bytes = "vec", tag = "4")]
|
||||
pub conflict_id: ::prost::alloc::vec::Vec<u8>,
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ pub enum FileType {
|
|||
Normal { executable: bool },
|
||||
Symlink,
|
||||
GitSubmodule,
|
||||
Conflict { id: ConflictId },
|
||||
Conflict,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
|
@ -82,9 +82,9 @@ impl FileState {
|
|||
}
|
||||
}
|
||||
|
||||
fn for_conflict(id: ConflictId, size: u64, metadata: &Metadata) -> Self {
|
||||
fn for_conflict(size: u64, metadata: &Metadata) -> Self {
|
||||
FileState {
|
||||
file_type: FileType::Conflict { id },
|
||||
file_type: FileType::Conflict,
|
||||
mtime: mtime_from_metadata(metadata),
|
||||
size,
|
||||
}
|
||||
|
@ -130,10 +130,7 @@ fn file_state_from_proto(proto: crate::protos::working_copy::FileState) -> FileS
|
|||
crate::protos::working_copy::FileType::Normal => FileType::Normal { executable: false },
|
||||
crate::protos::working_copy::FileType::Executable => FileType::Normal { executable: true },
|
||||
crate::protos::working_copy::FileType::Symlink => FileType::Symlink,
|
||||
crate::protos::working_copy::FileType::Conflict => {
|
||||
let id = ConflictId::new(proto.conflict_id);
|
||||
FileType::Conflict { id }
|
||||
}
|
||||
crate::protos::working_copy::FileType::Conflict => FileType::Conflict,
|
||||
crate::protos::working_copy::FileType::GitSubmodule => FileType::GitSubmodule,
|
||||
};
|
||||
FileState {
|
||||
|
@ -149,10 +146,7 @@ fn file_state_to_proto(file_state: &FileState) -> crate::protos::working_copy::F
|
|||
FileType::Normal { executable: false } => crate::protos::working_copy::FileType::Normal,
|
||||
FileType::Normal { executable: true } => crate::protos::working_copy::FileType::Executable,
|
||||
FileType::Symlink => crate::protos::working_copy::FileType::Symlink,
|
||||
FileType::Conflict { id } => {
|
||||
proto.conflict_id = id.to_bytes();
|
||||
crate::protos::working_copy::FileType::Conflict
|
||||
}
|
||||
FileType::Conflict => crate::protos::working_copy::FileType::Conflict,
|
||||
FileType::GitSubmodule => crate::protos::working_copy::FileType::GitSubmodule,
|
||||
};
|
||||
proto.file_type = file_type as i32;
|
||||
|
@ -494,6 +488,7 @@ impl TreeState {
|
|||
base_ignores,
|
||||
)];
|
||||
|
||||
let current_tree = self.store.get_tree(&RepoPath::root(), &self.tree_id)?;
|
||||
let mut tree_builder = self.store.tree_builder(self.tree_id.clone());
|
||||
let mut deleted_files: HashSet<_> = self
|
||||
.file_states
|
||||
|
@ -546,6 +541,7 @@ impl TreeState {
|
|||
sub_path,
|
||||
&entry,
|
||||
git_ignore.as_ref(),
|
||||
¤t_tree,
|
||||
&mut tree_builder,
|
||||
)?;
|
||||
}
|
||||
|
@ -586,6 +582,7 @@ impl TreeState {
|
|||
repo_path: RepoPath,
|
||||
dir_entry: &DirEntry,
|
||||
git_ignore: &GitIgnoreFile,
|
||||
current_tree: &Tree,
|
||||
tree_builder: &mut TreeBuilder,
|
||||
) -> Result<(), SnapshotError> {
|
||||
let maybe_current_file_state = self.file_states.get_mut(&repo_path);
|
||||
|
@ -638,7 +635,7 @@ impl TreeState {
|
|||
// conflict and the contents are now a file, then we take interpret that as if
|
||||
// it is still a conflict.
|
||||
if !clean
|
||||
&& matches!(current_file_state.file_type, FileType::Conflict { .. })
|
||||
&& current_file_state.file_type == FileType::Conflict
|
||||
&& matches!(new_file_state.file_type, FileType::Normal { .. })
|
||||
{
|
||||
// If the only change is that the type changed from conflict to regular file,
|
||||
|
@ -649,11 +646,14 @@ impl TreeState {
|
|||
{
|
||||
clean = true;
|
||||
} else {
|
||||
let current_tree_value = current_tree.path_value(&repo_path);
|
||||
// If the file contained a conflict before and is now a normal file on disk
|
||||
// (new_file_state cannot be a Conflict at this point), we try to parse
|
||||
// any conflict markers in the file into a conflict.
|
||||
if let (FileType::Conflict { id }, FileType::Normal { executable: _ }) =
|
||||
(¤t_file_state.file_type, &new_file_state.file_type)
|
||||
if let (
|
||||
Some(TreeValue::Conflict(conflict_id)),
|
||||
FileType::Normal { executable: _ },
|
||||
) = (¤t_tree_value, &new_file_state.file_type)
|
||||
{
|
||||
let mut file = File::open(&disk_path).unwrap();
|
||||
let mut content = vec![];
|
||||
|
@ -661,14 +661,12 @@ impl TreeState {
|
|||
if let Some(new_conflict_id) = update_conflict_from_content(
|
||||
self.store.as_ref(),
|
||||
&repo_path,
|
||||
id,
|
||||
conflict_id,
|
||||
&content,
|
||||
)
|
||||
.unwrap()
|
||||
{
|
||||
new_file_state.file_type = FileType::Conflict {
|
||||
id: new_conflict_id.clone(),
|
||||
};
|
||||
new_file_state.file_type = FileType::Conflict;
|
||||
*current_file_state = new_file_state;
|
||||
tree_builder.set(repo_path, TreeValue::Conflict(new_conflict_id));
|
||||
return Ok(());
|
||||
|
@ -801,7 +799,7 @@ impl TreeState {
|
|||
let metadata = file
|
||||
.metadata()
|
||||
.map_err(|err| CheckoutError::for_stat_error(err, disk_path))?;
|
||||
Ok(FileState::for_conflict(id.clone(), size, &metadata))
|
||||
Ok(FileState::for_conflict(size, &metadata))
|
||||
}
|
||||
|
||||
#[cfg_attr(windows, allow(unused_variables))]
|
||||
|
@ -982,7 +980,7 @@ impl TreeState {
|
|||
let file_type = match after {
|
||||
TreeValue::File { id: _, executable } => FileType::Normal { executable },
|
||||
TreeValue::Symlink(_id) => FileType::Symlink,
|
||||
TreeValue::Conflict(id) => FileType::Conflict { id },
|
||||
TreeValue::Conflict(_id) => FileType::Conflict,
|
||||
TreeValue::GitSubmodule(_id) => {
|
||||
println!("ignoring git submodule at {path:?}");
|
||||
FileType::GitSubmodule
|
||||
|
|
Loading…
Reference in a new issue