mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-28 23:32:41 +00:00
rewrite: update all checkouts, not just the default workspace's (#13)
This commit is contained in:
parent
6d3e2017f8
commit
ac0d040bb5
3 changed files with 64 additions and 19 deletions
|
@ -543,10 +543,6 @@ impl MutableRepo {
|
|||
rebaser.rebased().len()
|
||||
}
|
||||
|
||||
pub fn get_checkout(&mut self) -> CommitId {
|
||||
self.view.borrow().checkout().clone()
|
||||
}
|
||||
|
||||
pub fn set_checkout(&mut self, workspace_id: WorkspaceId, commit_id: CommitId) {
|
||||
self.view_mut().set_checkout(workspace_id, commit_id);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::backend::CommitId;
|
|||
use crate::commit::Commit;
|
||||
use crate::commit_builder::CommitBuilder;
|
||||
use crate::dag_walk;
|
||||
use crate::op_store::{RefTarget, WorkspaceId};
|
||||
use crate::op_store::RefTarget;
|
||||
use crate::repo::{MutableRepo, RepoRef};
|
||||
use crate::repo_path::RepoPath;
|
||||
use crate::revset::RevsetExpression;
|
||||
|
@ -291,15 +291,7 @@ impl<'settings, 'repo> DescendantRebaser<'settings, 'repo> {
|
|||
}
|
||||
|
||||
fn update_references(&mut self, old_commit_id: CommitId, new_commit_ids: Vec<CommitId>) {
|
||||
// TODO: Either make this update the checkout in all workspaces or pass in a
|
||||
// particular workspace ID to this function
|
||||
if self.mut_repo.get_checkout() == old_commit_id {
|
||||
// We arbitrarily pick a new checkout among the candidates.
|
||||
let new_commit_id = new_commit_ids[0].clone();
|
||||
let new_commit = self.mut_repo.store().get_commit(&new_commit_id).unwrap();
|
||||
self.mut_repo
|
||||
.check_out(WorkspaceId::default(), self.settings, &new_commit);
|
||||
}
|
||||
self.update_checkouts(&old_commit_id, &new_commit_ids);
|
||||
|
||||
if let Some(branch_names) = self.branches.get(&old_commit_id) {
|
||||
let mut branch_updates = vec![];
|
||||
|
@ -343,7 +335,36 @@ impl<'settings, 'repo> DescendantRebaser<'settings, 'repo> {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Perhaps the interface since it's not just about rebasing commits.
|
||||
fn update_checkouts(&mut self, old_commit_id: &CommitId, new_commit_ids: &[CommitId]) {
|
||||
let mut workspaces_to_update = vec![];
|
||||
for (workspace_id, checkout_id) in self.mut_repo.view().checkouts() {
|
||||
if checkout_id == old_commit_id {
|
||||
workspaces_to_update.push(workspace_id.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if workspaces_to_update.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
// If several workspaces had the same old commit checked out, we want them all
|
||||
// to have the same commit checked out afterwards as well, so we avoid
|
||||
// calling MutableRepo::check_out() multiple times, since that might
|
||||
// otherwise create a separate new commit for each workspace.
|
||||
// We arbitrarily pick a new checkout among the candidates.
|
||||
let new_commit_id = new_commit_ids[0].clone();
|
||||
let new_commit = self.mut_repo.store().get_commit(&new_commit_id).unwrap();
|
||||
let new_checkout_commit =
|
||||
self.mut_repo
|
||||
.check_out(workspaces_to_update[0].clone(), self.settings, &new_commit);
|
||||
for workspace_id in workspaces_to_update.into_iter().skip(1) {
|
||||
self.mut_repo
|
||||
.check_out(workspace_id, self.settings, &new_checkout_commit);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Perhaps change the interface since it's not just about rebasing
|
||||
// commits.
|
||||
pub fn rebase_next(&mut self) -> Option<RebasedDescendant> {
|
||||
while let Some(old_commit_id) = self.to_visit.pop() {
|
||||
if let Some(new_parent_ids) = self.new_parents.get(&old_commit_id).cloned() {
|
||||
|
|
|
@ -1226,8 +1226,15 @@ fn test_rebase_descendants_update_checkout_open(use_git: bool) {
|
|||
.set_parents(vec![commit_a.id().clone()])
|
||||
.set_open(true)
|
||||
.write_to_repo(tx.mut_repo());
|
||||
let ws1_id = WorkspaceId::new("ws1".to_string());
|
||||
let ws2_id = WorkspaceId::new("ws2".to_string());
|
||||
let ws3_id = WorkspaceId::new("ws3".to_string());
|
||||
tx.mut_repo()
|
||||
.set_checkout(WorkspaceId::default(), commit_b.id().clone());
|
||||
.set_checkout(ws1_id.clone(), commit_b.id().clone());
|
||||
tx.mut_repo()
|
||||
.set_checkout(ws2_id.clone(), commit_b.id().clone());
|
||||
tx.mut_repo()
|
||||
.set_checkout(ws3_id.clone(), commit_a.id().clone());
|
||||
let repo = tx.commit();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
|
@ -1237,7 +1244,11 @@ fn test_rebase_descendants_update_checkout_open(use_git: bool) {
|
|||
tx.mut_repo().rebase_descendants(&settings);
|
||||
let repo = tx.commit();
|
||||
|
||||
assert_eq!(repo.view().checkout(), commit_c.id());
|
||||
// Workspaces 1 and 2 had B checked out, so they get updated to C. Workspace 3
|
||||
// had A checked out, so it doesn't get updated.
|
||||
assert_eq!(repo.view().get_checkout(&ws1_id), Some(commit_c.id()));
|
||||
assert_eq!(repo.view().get_checkout(&ws2_id), Some(commit_c.id()));
|
||||
assert_eq!(repo.view().get_checkout(&ws3_id), Some(commit_a.id()));
|
||||
}
|
||||
|
||||
#[test_case(false ; "local backend")]
|
||||
|
@ -1259,8 +1270,15 @@ fn test_rebase_descendants_update_checkout_closed(use_git: bool) {
|
|||
.set_parents(vec![commit_a.id().clone()])
|
||||
.set_open(true)
|
||||
.write_to_repo(tx.mut_repo());
|
||||
let ws1_id = WorkspaceId::new("ws1".to_string());
|
||||
let ws2_id = WorkspaceId::new("ws2".to_string());
|
||||
let ws3_id = WorkspaceId::new("ws3".to_string());
|
||||
tx.mut_repo()
|
||||
.set_checkout(WorkspaceId::default(), commit_b.id().clone());
|
||||
.set_checkout(ws1_id.clone(), commit_b.id().clone());
|
||||
tx.mut_repo()
|
||||
.set_checkout(ws2_id.clone(), commit_b.id().clone());
|
||||
tx.mut_repo()
|
||||
.set_checkout(ws3_id.clone(), commit_a.id().clone());
|
||||
let repo = tx.commit();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
|
@ -1271,9 +1289,19 @@ fn test_rebase_descendants_update_checkout_closed(use_git: bool) {
|
|||
tx.mut_repo().rebase_descendants(&settings);
|
||||
let repo = tx.commit();
|
||||
|
||||
let checkout = repo.store().get_commit(repo.view().checkout()).unwrap();
|
||||
// Workspaces 1 and 2 had B checked out, so they get updated to the same new
|
||||
// commit on top of C. Workspace 3 had A checked out, so it doesn't get updated.
|
||||
assert_eq!(
|
||||
repo.view().get_checkout(&ws1_id),
|
||||
repo.view().get_checkout(&ws2_id)
|
||||
);
|
||||
let checkout = repo
|
||||
.store()
|
||||
.get_commit(repo.view().get_checkout(&ws1_id).unwrap())
|
||||
.unwrap();
|
||||
assert!(checkout.is_open());
|
||||
assert_eq!(checkout.parent_ids(), vec![commit_c.id().clone()]);
|
||||
assert_eq!(repo.view().get_checkout(&ws3_id), Some(commit_a.id()));
|
||||
}
|
||||
|
||||
#[test_case(false ; "local backend")]
|
||||
|
|
Loading…
Reference in a new issue