mirror of
https://github.com/jj-vcs/jj.git
synced 2025-12-23 06:01:01 +00:00
op_store: minimal change to load/store tracking state of remote branches
We could instead migrate the storage types to (local_branches, remote_views), but that would be more involved and break forward compatibility with little benefit. Maybe we can do that later when we introduce remote tags.
This commit is contained in:
parent
4cd2518be0
commit
4af678848d
3 changed files with 78 additions and 12 deletions
|
|
@ -38,9 +38,16 @@ message RefTarget {
|
|||
}
|
||||
}
|
||||
|
||||
enum RemoteRefState {
|
||||
New = 0;
|
||||
Tracking = 1;
|
||||
}
|
||||
|
||||
message RemoteBranch {
|
||||
string remote_name = 1;
|
||||
RefTarget target = 2;
|
||||
// Introduced in jj 0.11.
|
||||
optional RemoteRefState state = 3;
|
||||
}
|
||||
|
||||
message Branch {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ pub struct RemoteBranch {
|
|||
pub remote_name: ::prost::alloc::string::String,
|
||||
#[prost(message, optional, tag = "2")]
|
||||
pub target: ::core::option::Option<RefTarget>,
|
||||
/// Introduced in jj 0.11.
|
||||
#[prost(enumeration = "RemoteRefState", optional, tag = "3")]
|
||||
pub state: ::core::option::Option<i32>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
|
|
@ -162,3 +165,29 @@ pub struct OperationMetadata {
|
|||
::prost::alloc::string::String,
|
||||
>,
|
||||
}
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
#[repr(i32)]
|
||||
pub enum RemoteRefState {
|
||||
New = 0,
|
||||
Tracking = 1,
|
||||
}
|
||||
impl RemoteRefState {
|
||||
/// String value of the enum field names used in the ProtoBuf definition.
|
||||
///
|
||||
/// The values are not transformed in any way and thus are considered stable
|
||||
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
|
||||
pub fn as_str_name(&self) -> &'static str {
|
||||
match self {
|
||||
RemoteRefState::New => "New",
|
||||
RemoteRefState::Tracking => "Tracking",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"New" => Some(Self::New),
|
||||
"Tracking" => Some(Self::Tracking),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -352,6 +352,7 @@ fn branch_views_to_proto_legacy(
|
|||
|&(remote_name, remote_ref)| crate::protos::op_store::RemoteBranch {
|
||||
remote_name: remote_name.to_owned(),
|
||||
target: ref_target_to_proto(&remote_ref.target),
|
||||
state: remote_ref_state_to_proto(remote_ref.state),
|
||||
},
|
||||
)
|
||||
.collect();
|
||||
|
|
@ -372,17 +373,27 @@ fn branch_views_from_proto_legacy(
|
|||
for branch_proto in branches_legacy {
|
||||
let local_target = ref_target_from_proto(branch_proto.local_target);
|
||||
for remote_branch in branch_proto.remote_branches {
|
||||
// If local branch doesn't exist, we assume that the remote branch hasn't been
|
||||
// merged because git.auto-local-branch was off. That's probably more common
|
||||
// than deleted but yet-to-be-pushed local branch. Alternatively, we could read
|
||||
// git.auto-local-branch setting here, but that wouldn't always work since the
|
||||
// setting could be toggled after the branch got merged.
|
||||
let is_git_tracking = remote_branch.remote_name == git::REMOTE_NAME_FOR_LOCAL_GIT_REPO;
|
||||
let state = if is_git_tracking || local_target.is_present() {
|
||||
RemoteRefState::Tracking
|
||||
} else {
|
||||
RemoteRefState::New
|
||||
};
|
||||
let state = remote_ref_state_from_proto(remote_branch.state).unwrap_or_else(|| {
|
||||
// If local branch doesn't exist, we assume that the remote branch hasn't been
|
||||
// merged because git.auto-local-branch was off. That's probably more common
|
||||
// than deleted but yet-to-be-pushed local branch. Alternatively, we could read
|
||||
// git.auto-local-branch setting here, but that wouldn't always work since the
|
||||
// setting could be toggled after the branch got merged.
|
||||
let is_git_tracking =
|
||||
remote_branch.remote_name == git::REMOTE_NAME_FOR_LOCAL_GIT_REPO;
|
||||
let default_state = if is_git_tracking || local_target.is_present() {
|
||||
RemoteRefState::Tracking
|
||||
} else {
|
||||
RemoteRefState::New
|
||||
};
|
||||
tracing::trace!(
|
||||
?branch_proto.name,
|
||||
?remote_branch.remote_name,
|
||||
?default_state,
|
||||
"generated tracking state",
|
||||
);
|
||||
default_state
|
||||
});
|
||||
let remote_view = remote_views.entry(remote_branch.remote_name).or_default();
|
||||
let remote_ref = RemoteRef {
|
||||
target: ref_target_from_proto(remote_branch.target),
|
||||
|
|
@ -501,6 +512,23 @@ fn ref_target_from_proto(maybe_proto: Option<crate::protos::op_store::RefTarget>
|
|||
}
|
||||
}
|
||||
|
||||
fn remote_ref_state_to_proto(state: RemoteRefState) -> Option<i32> {
|
||||
let proto_state = match state {
|
||||
RemoteRefState::New => crate::protos::op_store::RemoteRefState::New,
|
||||
RemoteRefState::Tracking => crate::protos::op_store::RemoteRefState::Tracking,
|
||||
};
|
||||
Some(proto_state as i32)
|
||||
}
|
||||
|
||||
fn remote_ref_state_from_proto(proto_value: Option<i32>) -> Option<RemoteRefState> {
|
||||
let proto_state = proto_value.and_then(crate::protos::op_store::RemoteRefState::from_i32)?;
|
||||
let state = match proto_state {
|
||||
crate::protos::op_store::RemoteRefState::New => RemoteRefState::New,
|
||||
crate::protos::op_store::RemoteRefState::Tracking => RemoteRefState::Tracking,
|
||||
};
|
||||
Some(state)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use insta::assert_snapshot;
|
||||
|
|
@ -663,8 +691,9 @@ mod tests {
|
|||
},
|
||||
"remote2".to_owned() => RemoteView {
|
||||
branches: btreemap! {
|
||||
// "branch2" is non-tracking. "branch4" is tracking, but locally deleted.
|
||||
"branch2".to_owned() => new_remote_ref(&remote2_branch2_target),
|
||||
"branch4".to_owned() => new_remote_ref(&remote2_branch4_target),
|
||||
"branch4".to_owned() => tracking_remote_ref(&remote2_branch4_target),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -706,6 +735,7 @@ mod tests {
|
|||
|remote_name: &str, ref_target| crate::protos::op_store::RemoteBranch {
|
||||
remote_name: remote_name.to_owned(),
|
||||
target: ref_target_to_proto(ref_target),
|
||||
state: None, // to be generated based on local branch existence
|
||||
};
|
||||
let git_ref_to_proto = |name: &str, ref_target| crate::protos::op_store::GitRef {
|
||||
name: name.to_owned(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue