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
|
○ c
|
||||||
├─╮
|
├─╮
|
||||||
│ @ f
|
│ ○ b4
|
||||||
│ ○ b2
|
│ ○ b3
|
||||||
│ ○ b1
|
@ │ f
|
||||||
○ │ b4
|
○ │ b2
|
||||||
○ │ b3
|
○ │ b1
|
||||||
├─╯
|
├─╯
|
||||||
○ a
|
○ a
|
||||||
◆
|
◆
|
||||||
|
|
|
@ -643,33 +643,39 @@ pub fn move_commits(
|
||||||
new_children
|
new_children
|
||||||
.iter()
|
.iter()
|
||||||
.map(|child_commit| {
|
.map(|child_commit| {
|
||||||
let mut new_child_parent_ids: IndexSet<_> = child_commit
|
let mut new_child_parent_ids = IndexSet::new();
|
||||||
.parent_ids()
|
for old_child_parent_id in child_commit.parent_ids() {
|
||||||
.iter()
|
|
||||||
// Replace target commits with their parents outside the target set.
|
// Replace target commits with their parents outside the target set.
|
||||||
.flat_map(|id| {
|
let old_child_parent_ids = if let Some(parents) =
|
||||||
if let Some(parents) = target_commits_external_parents.get(id) {
|
target_commits_external_parents.get(old_child_parent_id)
|
||||||
parents.iter().cloned().collect_vec()
|
{
|
||||||
} else {
|
parents.iter().collect_vec()
|
||||||
[id.clone()].to_vec()
|
} else {
|
||||||
}
|
vec![old_child_parent_id]
|
||||||
})
|
};
|
||||||
// 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();
|
|
||||||
|
|
||||||
// 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());
|
new_child_parent_ids.extend(target_heads.clone());
|
||||||
|
|
||||||
(
|
(
|
||||||
child_commit.id().clone(),
|
child_commit.id().clone(),
|
||||||
new_child_parent_ids.iter().cloned().collect_vec(),
|
new_child_parent_ids.into_iter().collect_vec(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
|
Loading…
Reference in a new issue