summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-fast-import.txt3
-rw-r--r--fast-import.c13
-rwxr-xr-xt/t9300-fast-import.sh18
3 files changed, 31 insertions, 3 deletions
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index fd22a9a0c1..c32a9a5aee 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -483,6 +483,9 @@ Marks must be declared (via `mark`) before they can be used.
* Any valid Git SHA-1 expression that resolves to a commit. See
``SPECIFYING REVISIONS'' in linkgit:gitrevisions[7] for details.
+* The special null SHA-1 (40 zeros) specifies that the branch is to be
+ removed.
+
The special case of restarting an incremental import from the
current branch value should be written as:
----
diff --git a/fast-import.c b/fast-import.c
index fb4738d373..6707a66471 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -248,6 +248,7 @@ struct branch {
uintmax_t last_commit;
uintmax_t num_notes;
unsigned active : 1;
+ unsigned delete : 1;
unsigned pack_id : PACK_ID_BITS;
unsigned char sha1[20];
};
@@ -1681,10 +1682,13 @@ static int update_branch(struct branch *b)
struct ref_lock *lock;
unsigned char old_sha1[20];
- if (is_null_sha1(b->sha1))
- return 0;
if (read_ref(b->name, old_sha1))
hashclr(old_sha1);
+ if (is_null_sha1(b->sha1)) {
+ if (b->delete)
+ delete_ref(b->name, old_sha1, 0);
+ return 0;
+ }
lock = lock_any_ref_for_update(b->name, old_sha1, 0, NULL);
if (!lock)
return error("Unable to lock %s", b->name);
@@ -2611,8 +2615,11 @@ static int parse_from(struct branch *b)
free(buf);
} else
parse_from_existing(b);
- } else if (!get_sha1(from, b->sha1))
+ } else if (!get_sha1(from, b->sha1)) {
parse_from_existing(b);
+ if (is_null_sha1(b->sha1))
+ b->delete = 1;
+ }
else
die("Invalid ref name or SHA1 expression: %s", from);
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 27263dfb80..5fc9ef262a 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -2999,4 +2999,22 @@ test_expect_success 'T: ls root tree' '
test_cmp expect actual
'
+test_expect_success 'T: delete branch' '
+ git branch to-delete &&
+ git fast-import <<-EOF &&
+ reset refs/heads/to-delete
+ from 0000000000000000000000000000000000000000
+ EOF
+ test_must_fail git rev-parse --verify refs/heads/to-delete
+'
+
+test_expect_success 'T: empty reset doesnt delete branch' '
+ git branch not-to-delete &&
+ git fast-import <<-EOF &&
+ reset refs/heads/not-to-delete
+ EOF
+ git show-ref &&
+ git rev-parse --verify refs/heads/not-to-delete
+'
+
test_done