add receive.denyNonFastforwards config variable
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>
Wed, 20 Sep 2006 23:07:54 +0000 (01:07 +0200)
committerJunio C Hamano <junkio@cox.net>
Wed, 20 Sep 2006 23:15:45 +0000 (16:15 -0700)
If receive.denyNonFastforwards is set to true, git-receive-pack will deny
non fast-forwards, i.e. forced updates. Most notably, a push to a repository
which has that flag set will fail.

As a first user, 'git-init-db --shared' sets this flag, since in a shared
setup, you are most unlikely to want forced pushes to succeed.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
builtin-init-db.c
cache.h
environment.c
receive-pack.c
setup.c

index 5085018e46d8ebefaf797d62dcc7c9f8f1d06d02..c3ed1ce4929472b4e3fb7577ac61bd914baf0954 100644 (file)
@@ -311,6 +311,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
                 */
                sprintf(buf, "%d", shared_repository);
                git_config_set("core.sharedrepository", buf);
+               git_config_set("receive.denyNonFastforwards", "true");
        }
 
        return 0;
diff --git a/cache.h b/cache.h
index d557e75eb29f260f34d246437c470e3cbf61db1c..ef2e58147535c455c5be2b014af9945fb41c35d0 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -188,6 +188,7 @@ extern int prefer_symlink_refs;
 extern int log_all_ref_updates;
 extern int warn_ambiguous_refs;
 extern int shared_repository;
+extern int deny_non_fast_forwards;
 extern const char *apply_default_whitespace;
 extern int zlib_compression_level;
 
index 84d870ca4eca6e202bcbec388e9a299b887f9a12..63b1d155be1aca2f9fe7aad5f747c06b9102fd60 100644 (file)
@@ -20,6 +20,7 @@ int warn_ambiguous_refs = 1;
 int repository_format_version;
 char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8";
 int shared_repository = PERM_UMASK;
+int deny_non_fast_forwards = 0;
 const char *apply_default_whitespace;
 int zlib_compression_level = Z_DEFAULT_COMPRESSION;
 int pager_in_use;
index 78f75da5ca99bd5457fd4e0f6e3af2737afc335a..a6ec9f900d6ff57d6123dbd599e63324c642a79c 100644 (file)
@@ -2,6 +2,8 @@
 #include "refs.h"
 #include "pkt-line.h"
 #include "run-command.h"
+#include "commit.h"
+#include "object.h"
 
 static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
 
@@ -127,6 +129,20 @@ static int update(struct command *cmd)
                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)) {
+               struct commit *old_commit, *new_commit;
+               struct commit_list *bases;
+
+               old_commit = (struct commit *)parse_object(old_sha1);
+               new_commit = (struct commit *)parse_object(new_sha1);
+               for (bases = get_merge_bases(old_commit, new_commit, 1);
+                               bases; bases = bases->next)
+                       if (!hashcmp(old_sha1, bases->item->object.sha1))
+                               break;
+               if (!bases)
+                       return error("denying non-fast forward;"
+                                       " you should pull first");
+       }
        safe_create_leading_directories(lock_name);
 
        newfd = open(lock_name, O_CREAT | O_EXCL | O_WRONLY, 0666);
diff --git a/setup.c b/setup.c
index 2afdba414a073705440f887593a1b5daa1023758..9a46a58a4a34a345eb9f9b623a255c9bcba4c757 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -244,6 +244,8 @@ int check_repository_format_version(const char *var, const char *value)
                repository_format_version = git_config_int(var, value);
        else if (strcmp(var, "core.sharedrepository") == 0)
                shared_repository = git_config_perm(var, value);
+       else if (strcmp(var, "receive.denynonfastforwards") == 0)
+               deny_non_fast_forwards = git_config_bool(var, value);
        return 0;
 }