Skip to content

Commit 8a760d4

Browse files
fix(record): correct handling of --stash with detached head
This addresses an overlooked review comment from #1150: > issue: Won't this not work if no branch is checked out before trying to > stash? In that case, it seems like git record --stash would make the commit > without switching back to the parent commit. And, indeed, that's exactly the case! Ref: #1150 (comment)
1 parent 3900942 commit 8a760d4

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

git-branchless-record/src/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,19 @@ fn record(
221221
ResolvedReferenceInfo {
222222
oid: Some(oid),
223223
reference_name: _,
224-
} => Some(CheckoutTarget::Oid(oid)),
224+
} => {
225+
let head_commit = repo.find_commit_or_fail(oid)?;
226+
match head_commit.get_parents().as_slice() {
227+
[] => None,
228+
[parent_commit] => Some(CheckoutTarget::Oid(parent_commit.get_oid())),
229+
parent_commits => {
230+
eyre::bail!("git-branchless record --stash seems to have created a merge commit, but this should be impossible. Parents: {parent_commits:?}");
231+
}
232+
}
233+
}
225234
_ => None,
226235
};
236+
227237
if stash && checkout_target.is_some() {
228238
try_exit_code!(check_out_commit(
229239
effects,

git-branchless-record/tests/test_record.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,53 @@ fn test_record_stash() -> eyre::Result<()> {
342342
Ok(())
343343
}
344344

345+
#[test]
346+
fn test_record_stash_detached_head() -> eyre::Result<()> {
347+
let git = make_git()?;
348+
349+
if !git.supports_reference_transactions()? {
350+
return Ok(());
351+
}
352+
git.init_repo()?;
353+
354+
git.detach_head()?;
355+
356+
{
357+
git.commit_file("test1", 1)?;
358+
359+
let stdout = git.smartlog()?;
360+
insta::assert_snapshot!(stdout, @r###"
361+
O f777ecc (master) create initial.txt
362+
|
363+
@ 62fc20d create test1.txt
364+
"###);
365+
}
366+
367+
{
368+
git.write_file_txt("test1", "new test1 contents\n")?;
369+
370+
let (stdout, _stderr) = git.branchless("record", &["-m", "foo", "--stash"])?;
371+
insta::assert_snapshot!(stdout, @r###"
372+
[detached HEAD 9b6164c] foo
373+
1 file changed, 1 insertion(+), 1 deletion(-)
374+
branchless: running command: <git-executable> checkout 62fc20d2a290daea0d52bdc2ed2ad4be6491010e
375+
"###);
376+
}
377+
378+
{
379+
let stdout = git.smartlog()?;
380+
insta::assert_snapshot!(stdout, @r###"
381+
O f777ecc (master) create initial.txt
382+
|
383+
@ 62fc20d create test1.txt
384+
|
385+
o 9b6164c foo
386+
"###);
387+
}
388+
389+
Ok(())
390+
}
391+
345392
#[test]
346393
fn test_record_stash_default_message() -> eyre::Result<()> {
347394
let git = make_git()?;

0 commit comments

Comments
 (0)