Merge branch 'jc/refuse-push-to-current'
authorJunio C Hamano <gitster@pobox.com>
Fri, 6 Feb 2009 03:40:36 +0000 (19:40 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 6 Feb 2009 03:40:36 +0000 (19:40 -0800)
* jc/refuse-push-to-current:
receive-pack: explain what to do when push updates the current branch

1  2 
builtin-receive-pack.c
diff --combined builtin-receive-pack.c
index 596dfe92233e9ad07cebfa7e36a404ea909da716,6f61c45fdd039b20688bedb91b6470c5ae105dad..6de186c397fcd5eaab2331db56546acab5f545f4
@@@ -9,9 -9,10 +9,10 @@@
  #include "remote.h"
  #include "transport.h"
  
 -static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
 +static const char receive_pack_usage[] = "git receive-pack <git-dir>";
  
  enum deny_action {
+       DENY_UNCONFIGURED,
        DENY_IGNORE,
        DENY_WARN,
        DENY_REFUSE,
@@@ -19,7 -20,7 +20,7 @@@
  
  static int deny_deletes = 0;
  static int deny_non_fast_forwards = 0;
- static enum deny_action deny_current_branch = DENY_WARN;
+ static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
  static int receive_fsck_objects;
  static int receive_unpack_limit = -1;
  static int transfer_unpack_limit = -1;
@@@ -214,6 -215,35 +215,35 @@@ static int is_ref_checked_out(const cha
        return !strcmp(head, ref);
  }
  
+ static char *warn_unconfigured_deny_msg[] = {
+       "Updating the currently checked out branch may cause confusion,",
+       "as the index and work tree do not reflect changes that are in HEAD.",
+       "As a result, you may see the changes you just pushed into it",
+       "reverted when you run 'git diff' over there, and you may want",
+       "to run 'git reset --hard' before starting to work to recover.",
+       "",
+       "You can set 'receive.denyCurrentBranch' configuration variable to",
+       "'refuse' in the remote repository to forbid pushing into its",
+       "current branch."
+       "",
+       "To allow pushing into the current branch, you can set it to 'ignore';",
+       "but this is not recommended unless you arranged to update its work",
+       "tree to match what you pushed in some other way.",
+       "",
+       "To squelch this message, you can set it to 'warn'.",
+       "",
+       "Note that the default will change in a future version of git",
+       "to refuse updating the current branch unless you have the",
+       "configuration variable set to either 'ignore' or 'warn'."
+ };
+ static void warn_unconfigured_deny(void)
+ {
+       int i;
+       for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
+               warning(warn_unconfigured_deny_msg[i]);
+ }
  static const char *update(struct command *cmd)
  {
        const char *name = cmd->ref_name;
                return "funny refname";
        }
  
-       switch (deny_current_branch) {
-       case DENY_IGNORE:
-               break;
-       case DENY_WARN:
-               if (!is_ref_checked_out(name))
+       if (is_ref_checked_out(name)) {
+               switch (deny_current_branch) {
+               case DENY_IGNORE:
                        break;
-               warning("updating the currently checked out branch; this may"
-                       " cause confusion,\n"
-                       "as the index and working tree do not reflect changes"
-                       " that are now in HEAD.");
-               break;
-       case DENY_REFUSE:
-               if (!is_ref_checked_out(name))
+               case DENY_UNCONFIGURED:
+               case DENY_WARN:
+                       warning("updating the current branch");
+                       if (deny_current_branch == DENY_UNCONFIGURED)
+                               warn_unconfigured_deny();
                        break;
-               error("refusing to update checked out branch: %s", name);
-               return "branch is currently checked out";
+               case DENY_REFUSE:
+                       error("refusing to update checked out branch: %s", name);
+                       return "branch is currently checked out";
+               }
        }
  
        if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {