Merge branch 'en/fast-import-avoid-self-replace' into next

"git fast-import" can be tricked into a replace ref that maps an
object to itself, which is a useless thing to do.

* en/fast-import-avoid-self-replace:
  fast-import: avoid making replace refs point to themselves
This commit is contained in:
Junio C Hamano 2024-11-20 14:51:29 +09:00
commit 751ee6b395
2 changed files with 42 additions and 0 deletions

View File

@ -179,6 +179,7 @@ static unsigned long branch_load_count;
static int failure;
static FILE *pack_edges;
static unsigned int show_stats = 1;
static unsigned int quiet;
static int global_argc;
static const char **global_argv;
static const char *global_prefix;
@ -1602,7 +1603,19 @@ static int update_branch(struct branch *b)
struct ref_transaction *transaction;
struct object_id old_oid;
struct strbuf err = STRBUF_INIT;
static const char *replace_prefix = "refs/replace/";
if (starts_with(b->name, replace_prefix) &&
!strcmp(b->name + strlen(replace_prefix),
oid_to_hex(&b->oid))) {
if (!quiet)
warning("Dropping %s since it would point to "
"itself (i.e. to %s)",
b->name, oid_to_hex(&b->oid));
refs_delete_ref(get_main_ref_store(the_repository),
NULL, b->name, NULL, 0);
return 0;
}
if (is_null_oid(&b->oid)) {
if (b->delete)
refs_delete_ref(get_main_ref_store(the_repository),
@ -3388,6 +3401,7 @@ static int parse_one_option(const char *option)
option_export_pack_edges(option);
} else if (!strcmp(option, "quiet")) {
show_stats = 0;
quiet = 1;
} else if (!strcmp(option, "stats")) {
show_stats = 1;
} else if (!strcmp(option, "allow-unsafe-features")) {

View File

@ -3692,6 +3692,34 @@ test_expect_success ICONV 'X: handling encoding' '
git log -1 --format=%B encoding | grep $(printf "\317\200")
'
test_expect_success 'X: replace ref that becomes useless is removed' '
git init -qb main testrepo &&
cd testrepo &&
(
test_commit test &&
test_commit msg somename content &&
git mv somename othername &&
NEW_TREE=$(git write-tree) &&
MSG="$(git log -1 --format=%B HEAD)" &&
NEW_COMMIT=$(git commit-tree -p HEAD^1 -m "$MSG" $NEW_TREE) &&
git replace main $NEW_COMMIT &&
echo more >>othername &&
git add othername &&
git commit -qm more &&
git fast-export --all >tmp &&
sed -e s/othername/somename/ tmp >tmp2 &&
git fast-import --force <tmp2 2>msgs &&
grep "Dropping.*since it would point to itself" msgs &&
git show-ref >refs &&
! grep refs/replace refs
)
'
###
### series Y (submodules and hash algorithms)
###