Skip to content

Commit 8eaa065

Browse files
committed
Merge branch 'en/fast-import-avoid-self-replace'
"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
2 parents 89ceab7 + 5e904f1 commit 8eaa065

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

builtin/fast-import.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ static unsigned long branch_load_count;
179179
static int failure;
180180
static FILE *pack_edges;
181181
static unsigned int show_stats = 1;
182+
static unsigned int quiet;
182183
static int global_argc;
183184
static const char **global_argv;
184185
static const char *global_prefix;
@@ -1602,7 +1603,19 @@ static int update_branch(struct branch *b)
16021603
struct ref_transaction *transaction;
16031604
struct object_id old_oid;
16041605
struct strbuf err = STRBUF_INIT;
1605-
1606+
static const char *replace_prefix = "refs/replace/";
1607+
1608+
if (starts_with(b->name, replace_prefix) &&
1609+
!strcmp(b->name + strlen(replace_prefix),
1610+
oid_to_hex(&b->oid))) {
1611+
if (!quiet)
1612+
warning("Dropping %s since it would point to "
1613+
"itself (i.e. to %s)",
1614+
b->name, oid_to_hex(&b->oid));
1615+
refs_delete_ref(get_main_ref_store(the_repository),
1616+
NULL, b->name, NULL, 0);
1617+
return 0;
1618+
}
16061619
if (is_null_oid(&b->oid)) {
16071620
if (b->delete)
16081621
refs_delete_ref(get_main_ref_store(the_repository),
@@ -3388,6 +3401,7 @@ static int parse_one_option(const char *option)
33883401
option_export_pack_edges(option);
33893402
} else if (!strcmp(option, "quiet")) {
33903403
show_stats = 0;
3404+
quiet = 1;
33913405
} else if (!strcmp(option, "stats")) {
33923406
show_stats = 1;
33933407
} else if (!strcmp(option, "allow-unsafe-features")) {

t/t9300-fast-import.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3692,6 +3692,34 @@ test_expect_success ICONV 'X: handling encoding' '
36923692
git log -1 --format=%B encoding | grep $(printf "\317\200")
36933693
'
36943694

3695+
test_expect_success 'X: replace ref that becomes useless is removed' '
3696+
git init -qb main testrepo &&
3697+
cd testrepo &&
3698+
(
3699+
test_commit test &&
3700+
3701+
test_commit msg somename content &&
3702+
3703+
git mv somename othername &&
3704+
NEW_TREE=$(git write-tree) &&
3705+
MSG="$(git log -1 --format=%B HEAD)" &&
3706+
NEW_COMMIT=$(git commit-tree -p HEAD^1 -m "$MSG" $NEW_TREE) &&
3707+
git replace main $NEW_COMMIT &&
3708+
3709+
echo more >>othername &&
3710+
git add othername &&
3711+
git commit -qm more &&
3712+
3713+
git fast-export --all >tmp &&
3714+
sed -e s/othername/somename/ tmp >tmp2 &&
3715+
git fast-import --force <tmp2 2>msgs &&
3716+
3717+
grep "Dropping.*since it would point to itself" msgs &&
3718+
git show-ref >refs &&
3719+
! grep refs/replace refs
3720+
)
3721+
'
3722+
36953723
###
36963724
### series Y (submodules and hash algorithms)
36973725
###

0 commit comments

Comments
 (0)