Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion gix/src/revision/spec/parse/delegate/revision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,16 @@ impl delegate::Revision for Delegate<'_> {
self.refs[self.idx] = Some(r.detach());
id
}
Err(_) => id,
Err(_) => match ObjectId::from_hex(ref_name.as_ref()) {
Ok(id) if id.kind() == self.repo.object_hash() => id,
_ => {
return Err(message!(
"Previous checkout '{name}' does not resolve to an existing revision",
name = ref_name.as_bstr()
)
.raise_erased());
}
},
};
let objs = self.objs[self.idx].get_or_insert_with(Vec::new);
if !objs.contains(&id) {
Expand Down
Binary file not shown.
31 changes: 31 additions & 0 deletions gix/tests/fixtures/make_rev_spec_parse_repos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,37 @@ EOF
baseline @...@
)

git init deleted_prior_checkout
(
cd deleted_prior_checkout
tick

git commit --allow-empty -m c1
git checkout -b prev-target
git checkout main
git branch -d prev-target

# `@{-1}` replays the previous checkout name through regular revision
# parsing. Once that branch is deleted, Git rejects it even though HEAD's
# reflog still contains the previous object id.
baseline "@{-1}"
)

git init deleted_prior_checkout_named_like_object
(
cd deleted_prior_checkout_named_like_object
tick

git commit --allow-empty -m c1
git checkout -b 0123456789012345678901234567890123456789
git checkout main
git branch -d 0123456789012345678901234567890123456789

# Git interprets a previous checkout name that is a full object id as
# that object id, even when no such object exists in the database.
baseline "@{-1}"
)

git init new
(cd new
baseline '@{1}'
Expand Down
24 changes: 24 additions & 0 deletions gix/tests/gix/revision/spec/from_bytes/reflog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,30 @@ fn nth_prior_checkout() {
);
}

#[test]
fn nth_prior_checkout_to_deleted_branch_fails_like_git() -> crate::Result {
let repo = repo("deleted_prior_checkout")?;
let err = parse_spec("@{-1}", &repo).expect_err("deleted prior checkout branch must not resolve by object id");
assert!(
err.probable_cause()
.to_string()
.contains("Previous checkout 'prev-target' does not resolve"),
"error should explain that the reflog name no longer resolves"
);
Ok(())
}

#[test]
fn nth_prior_checkout_to_deleted_branch_named_like_object_matches_git() -> crate::Result {
let repo = repo("deleted_prior_checkout_named_like_object")?;
assert_eq!(
parse_spec("@{-1}", &repo)?,
Spec::from_id(hex_to_id_sha1_only("0123456789012345678901234567890123456789").attach(&repo)),
"full object ids are accepted as previous checkout names, even without matching objects"
);
Ok(())
}

#[test]
fn by_index_unborn_head() {
let repo = &repo("new").unwrap();
Expand Down
Loading