diff options
author | Junio C Hamano <junkio@cox.net> | 2006-11-24 00:26:49 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-11-24 03:59:05 -0800 |
commit | d4f694ba89857a87e259557d0f236c761b4041ef (patch) | |
tree | 08453ccc3a39a74ad5e74ff4bf1cf13dd88b85c7 /receive-pack.c | |
parent | 634b8d05142a4812bf35fe8b14cc62c84494c78f (diff) | |
download | git-d4f694ba89857a87e259557d0f236c761b4041ef.tar.gz git-d4f694ba89857a87e259557d0f236c761b4041ef.tar.xz |
Allow git push to delete remote ref.
This allows you to say
git send-pack $URL :refs/heads/$branch
to delete the named remote branch. The refspec $src:$dst means
replace the destination ref with the object known as $src on the
local side, so this is a natural extension to make an empty $src
mean "No object" to delete the target.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'receive-pack.c')
-rw-r--r-- | receive-pack.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/receive-pack.c b/receive-pack.c index d56898c9b..1a141dc1e 100644 --- a/receive-pack.c +++ b/receive-pack.c @@ -14,7 +14,7 @@ static int deny_non_fast_forwards = 0; static int unpack_limit = 5000; static int report_status; -static char capabilities[] = "report-status"; +static char capabilities[] = " report-status delete-refs "; static int capabilities_sent; static int receive_pack_config(const char *var, const char *value) @@ -113,12 +113,14 @@ static int update(struct command *cmd) strcpy(new_hex, sha1_to_hex(new_sha1)); strcpy(old_hex, sha1_to_hex(old_sha1)); - if (!has_sha1_file(new_sha1)) { + + if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) { cmd->error_string = "bad pack"; return error("unpack should have generated %s, " "but I can't find it!", new_hex); } - if (deny_non_fast_forwards && !is_null_sha1(old_sha1)) { + if (deny_non_fast_forwards && !is_null_sha1(new_sha1) && + !is_null_sha1(old_sha1)) { struct commit *old_commit, *new_commit; struct commit_list *bases, *ent; @@ -138,14 +140,22 @@ static int update(struct command *cmd) return error("hook declined to update %s", name); } - lock = lock_any_ref_for_update(name, old_sha1); - if (!lock) { - cmd->error_string = "failed to lock"; - return error("failed to lock %s", name); + if (is_null_sha1(new_sha1)) { + if (delete_ref(name, old_sha1)) { + cmd->error_string = "failed to delete"; + return error("failed to delete %s", name); + } + fprintf(stderr, "%s: %s -> deleted\n", name, old_hex); + } + else { + lock = lock_any_ref_for_update(name, old_sha1); + if (!lock) { + cmd->error_string = "failed to lock"; + return error("failed to lock %s", name); + } + write_ref_sha1(lock, new_sha1, "push"); + fprintf(stderr, "%s: %s -> %s\n", name, old_hex, new_hex); } - write_ref_sha1(lock, new_sha1, "push"); - - fprintf(stderr, "%s: %s -> %s\n", name, old_hex, new_hex); return 0; } @@ -375,6 +385,16 @@ static void report(const char *unpack_status) packet_flush(1); } +static int delete_only(struct command *cmd) +{ + while (cmd) { + if (!is_null_sha1(cmd->new_sha1)) + return 0; + cmd = cmd->next; + } + return 1; +} + int main(int argc, char **argv) { int i; @@ -408,7 +428,10 @@ int main(int argc, char **argv) read_head_info(); if (commands) { - const char *unpack_status = unpack(); + const char *unpack_status = NULL; + + if (!delete_only(commands)) + unpack_status = unpack(); if (!unpack_status) execute_commands(); if (pack_lockfile) |