Skip to content

Commit f94a071

Browse files
feat(split): extend branch if checked out on split commit
1 parent 3726ed1 commit f94a071

File tree

2 files changed

+61
-42
lines changed

2 files changed

+61
-42
lines changed

git-branchless/src/commands/split.rs

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use eyre::Context;
44
use rayon::ThreadPoolBuilder;
55
use std::{
6-
collections::HashMap,
76
fmt::Write,
87
path::Path,
98
time::{SystemTime, UNIX_EPOCH},
@@ -250,34 +249,65 @@ pub fn split(
250249
event_tx_id,
251250
commit_oid: extracted_commit_oid,
252251
}])?;
253-
move_branches(effects, git_run_info, &repo, event_tx_id, &{
254-
let mut result = HashMap::new();
255-
result.insert(commit_to_split_oid, MaybeZeroOid::NonZero(split_commit_oid));
256-
result
257-
})?;
258252

259253
let head_info = repo.get_head_info()?;
260-
if let ResolvedReferenceInfo {
261-
oid: Some(oid),
262-
reference_name: _,
263-
} = head_info
264-
{
265-
if oid == commit_to_split_oid {
266-
try_exit_code!(check_out_commit(
267-
effects,
268-
git_run_info,
269-
&repo,
270-
&event_log_db,
271-
event_tx_id,
272-
Some(CheckoutTarget::Oid(split_commit_oid)),
273-
&CheckOutCommitOptions {
274-
additional_args: Default::default(),
275-
force_detach: true,
276-
reset: false,
277-
render_smartlog: false,
278-
},
279-
)?);
280-
}
254+
let (checkout_target, rewritten_oids) = match head_info {
255+
// branch @ split commit checked out: extend branch to include extracted
256+
// commit; branch will stay checked out w/ any explicit checkout
257+
ResolvedReferenceInfo {
258+
oid: Some(oid),
259+
reference_name: Some(_),
260+
} if oid == commit_to_split_oid => (
261+
None,
262+
vec![(
263+
commit_to_split_oid,
264+
MaybeZeroOid::NonZero(extracted_commit_oid),
265+
)],
266+
),
267+
268+
// commit to split checked out as detached HEAD, don't extend any
269+
// branches, but explicitly check out the newly split commit
270+
ResolvedReferenceInfo {
271+
oid: Some(oid),
272+
reference_name: None,
273+
} if oid == commit_to_split_oid => (
274+
Some(CheckoutTarget::Oid(split_commit_oid)),
275+
vec![(commit_to_split_oid, MaybeZeroOid::NonZero(split_commit_oid))],
276+
),
277+
278+
// some other commit or branch was checked out, default behavior is fine
279+
ResolvedReferenceInfo {
280+
oid: _,
281+
reference_name: _,
282+
} => (
283+
None,
284+
vec![(commit_to_split_oid, MaybeZeroOid::NonZero(split_commit_oid))],
285+
),
286+
};
287+
288+
move_branches(
289+
effects,
290+
git_run_info,
291+
&repo,
292+
event_tx_id,
293+
&(rewritten_oids.into_iter().collect()),
294+
)?;
295+
296+
if checkout_target.is_some() {
297+
try_exit_code!(check_out_commit(
298+
effects,
299+
git_run_info,
300+
&repo,
301+
&event_log_db,
302+
event_tx_id,
303+
Some(CheckoutTarget::Oid(split_commit_oid)),
304+
&CheckOutCommitOptions {
305+
additional_args: Default::default(),
306+
force_detach: true,
307+
reset: false,
308+
render_smartlog: false,
309+
},
310+
)?);
281311
}
282312

283313
let mut builder = RebasePlanBuilder::new(&dag, permissions);

git-branchless/tests/test_split.rs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::PathBuf;
2+
13
use lib::testing::{make_git, GitRunOptions};
24

35
#[test]
@@ -364,23 +366,10 @@ fn test_split_attached_branch() -> eyre::Result<()> {
364366
Nothing to restack.
365367
O f777ecc (master) create initial.txt
366368
|
367-
@ 2932db7 (> branch-name) first commit
369+
o 2932db7 first commit
368370
|
369-
o c159d6a temp(split): test2.txt
371+
@ c159d6a (> branch-name) temp(split): test2.txt
370372
"###);
371-
}
372-
373-
{
374-
// TODO confirm that this is correct: the file exists as unstaged & new
375-
// in this commit, but is still part of the next commit Should this
376-
// instead delete the file from working copy and leave it only in the
377-
// extracted commit?
378-
let (stdout, _stderr) = git.run(&["status", "--short"])?;
379-
insta::assert_snapshot!(&stdout, @r#"
380-
A test2.txt
381-
"#);
382-
383-
git.branchless("next", &[])?;
384373

385374
let (stdout, _stderr) = git.run(&["status", "--short"])?;
386375
insta::assert_snapshot!(&stdout, @r#""#);

0 commit comments

Comments
 (0)