mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-12 23:23:20 +00:00
rewrite::move_commits()
: preserve order of parent commits
When rebasing a new child commit on top of the moved commit(s), the order of the new child commit's parent commits is now correctly preserved if the original parent commit is now a parent of the moved commit(s). Closes #3969.
This commit is contained in:
parent
4a17b9fbe4
commit
ab604b4ecd
2 changed files with 32 additions and 26 deletions
|
@ -1470,11 +1470,11 @@ fn test_rebase_revisions_after() {
|
|||
├─╯
|
||||
○ c
|
||||
├─╮
|
||||
│ @ f
|
||||
│ ○ b2
|
||||
│ ○ b1
|
||||
○ │ b4
|
||||
○ │ b3
|
||||
│ ○ b4
|
||||
│ ○ b3
|
||||
@ │ f
|
||||
○ │ b2
|
||||
○ │ b1
|
||||
├─╯
|
||||
○ a
|
||||
◆
|
||||
|
|
|
@ -643,33 +643,39 @@ pub fn move_commits(
|
|||
new_children
|
||||
.iter()
|
||||
.map(|child_commit| {
|
||||
let mut new_child_parent_ids: IndexSet<_> = child_commit
|
||||
.parent_ids()
|
||||
.iter()
|
||||
let mut new_child_parent_ids = IndexSet::new();
|
||||
for old_child_parent_id in child_commit.parent_ids() {
|
||||
// Replace target commits with their parents outside the target set.
|
||||
.flat_map(|id| {
|
||||
if let Some(parents) = target_commits_external_parents.get(id) {
|
||||
parents.iter().cloned().collect_vec()
|
||||
} else {
|
||||
[id.clone()].to_vec()
|
||||
}
|
||||
})
|
||||
// Exclude any of the new parents of the target commits, since we are
|
||||
// "inserting" the target commits in between the new parents and the new
|
||||
// children.
|
||||
.filter(|id| {
|
||||
!new_parent_ids
|
||||
.iter()
|
||||
.any(|new_parent_id| new_parent_id == id)
|
||||
})
|
||||
.collect();
|
||||
let old_child_parent_ids = if let Some(parents) =
|
||||
target_commits_external_parents.get(old_child_parent_id)
|
||||
{
|
||||
parents.iter().collect_vec()
|
||||
} else {
|
||||
vec![old_child_parent_id]
|
||||
};
|
||||
|
||||
// Add `target_heads` as parents of the new child commit.
|
||||
// If the original parents of the new children are the new parents of the
|
||||
// `target_heads`, replace them with the target heads since we are "inserting"
|
||||
// the target commits in between the new parents and the new children.
|
||||
for id in old_child_parent_ids {
|
||||
if new_parent_ids
|
||||
.iter()
|
||||
.any(|new_parent_id| *new_parent_id == *id)
|
||||
{
|
||||
new_child_parent_ids.extend(target_heads.clone());
|
||||
} else {
|
||||
new_child_parent_ids.insert(id.clone());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// If not already present, add `target_heads` as parents of the new child
|
||||
// commit.
|
||||
new_child_parent_ids.extend(target_heads.clone());
|
||||
|
||||
(
|
||||
child_commit.id().clone(),
|
||||
new_child_parent_ids.iter().cloned().collect_vec(),
|
||||
new_child_parent_ids.into_iter().collect_vec(),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
|
|
Loading…
Reference in a new issue