add_ref(): take a (struct ref_entry *) parameter
[gitweb.git] / builtin / push.c
index 8c8d8c717be6be5b4c701d6af53307ac684c54a5..35cce532f2bb632e01c0de0a8e6f9e1395eece88 100644 (file)
@@ -8,6 +8,7 @@
 #include "remote.h"
 #include "transport.h"
 #include "parse-options.h"
+#include "submodule.h"
 
 static const char * const push_usage[] = {
        "git push [<options>] [<repository> [<refspec>...]]",
@@ -64,23 +65,33 @@ static void set_refspecs(const char **refs, int nr)
        }
 }
 
-static void setup_push_tracking(void)
+static void setup_push_upstream(struct remote *remote)
 {
        struct strbuf refspec = STRBUF_INIT;
        struct branch *branch = branch_get(NULL);
        if (!branch)
-               die(_("You are not currently on a branch."));
+               die(_("You are not currently on a branch.\n"
+                   "To push the history leading to the current (detached HEAD)\n"
+                   "state now, use\n"
+                   "\n"
+                   "    git push %s HEAD:<name-of-remote-branch>\n"),
+                   remote->name);
        if (!branch->merge_nr || !branch->merge)
-               die(_("The current branch %s is not tracking anything."),
+               die(_("The current branch %s has no upstream branch.\n"
+                   "To push the current branch and set the remote as upstream, use\n"
+                   "\n"
+                   "    git push --set-upstream %s %s\n"),
+                   branch->name,
+                   remote->name,
                    branch->name);
        if (branch->merge_nr != 1)
-               die(_("The current branch %s is tracking multiple branches, "
+               die(_("The current branch %s has multiple upstream branches, "
                    "refusing to push."), branch->name);
        strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
        add_refspec(refspec.buf);
 }
 
-static void setup_default_push_refspecs(void)
+static void setup_default_push_refspecs(struct remote *remote)
 {
        switch (push_default) {
        default:
@@ -88,8 +99,8 @@ static void setup_default_push_refspecs(void)
                add_refspec(":");
                break;
 
-       case PUSH_DEFAULT_TRACKING:
-               setup_push_tracking();
+       case PUSH_DEFAULT_UPSTREAM:
+               setup_push_upstream(remote);
                break;
 
        case PUSH_DEFAULT_CURRENT:
@@ -147,7 +158,14 @@ static int do_push(const char *repo, int flags)
        if (!remote) {
                if (repo)
                        die(_("bad repository '%s'"), repo);
-               die(_("No destination configured to push to."));
+               die(_("No configured push destination.\n"
+                   "Either specify the URL from the command-line or configure a remote repository using\n"
+                   "\n"
+                   "    git remote add <name> <url>\n"
+                   "\n"
+                   "and then push using the remote name\n"
+                   "\n"
+                   "    git push <name>\n"));
        }
 
        if (remote->mirror)
@@ -175,7 +193,7 @@ static int do_push(const char *repo, int flags)
                        refspec = remote->push_refspec;
                        refspec_nr = remote->push_refspec_nr;
                } else if (!(flags & TRANSPORT_PUSH_MIRROR))
-                       setup_default_push_refspecs();
+                       setup_default_push_refspecs(remote);
        }
        errs = 0;
        if (remote->pushurl_nr) {
@@ -202,6 +220,21 @@ static int do_push(const char *repo, int flags)
        return !!errs;
 }
 
+static int option_parse_recurse_submodules(const struct option *opt,
+                                  const char *arg, int unset)
+{
+       int *flags = opt->value;
+       if (arg) {
+               if (!strcmp(arg, "check"))
+                       *flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
+               else
+                       die("bad %s argument: %s", opt->long_name, arg);
+       } else
+               die("option %s needs an argument (check)", opt->long_name);
+
+       return 0;
+}
+
 int cmd_push(int argc, const char **argv, const char *prefix)
 {
        int flags = 0;
@@ -219,6 +252,9 @@ int cmd_push(int argc, const char **argv, const char *prefix)
                OPT_BIT('n' , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN),
                OPT_BIT( 0,  "porcelain", &flags, "machine-readable output", TRANSPORT_PUSH_PORCELAIN),
                OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE),
+               { OPTION_CALLBACK, 0, "recurse-submodules", &flags, "check",
+                       "controls recursive pushing of submodules",
+                       PARSE_OPT_OPTARG, option_parse_recurse_submodules },
                OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"),
                OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"),
                OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"),
@@ -228,6 +264,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
                OPT_END()
        };
 
+       packet_trace_identity("push");
        git_config(git_default_config, NULL);
        argc = parse_options(argc, argv, prefix, options, push_usage, 0);