Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 1 | /* |
| 2 | * "git push" |
| 3 | */ |
| 4 | #include "cache.h" |
| 5 | #include "refs.h" |
| 6 | #include "run-command.h" |
| 7 | #include "builtin.h" |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 8 | #include "remote.h" |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 9 | #include "transport.h" |
Daniel Barkalow | 378c483 | 2007-11-04 22:35:37 -0500 | [diff] [blame] | 10 | #include "parse-options.h" |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 11 | |
Daniel Barkalow | 378c483 | 2007-11-04 22:35:37 -0500 | [diff] [blame] | 12 | static const char * const push_usage[] = { |
| 13 | "git-push [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]", |
| 14 | NULL, |
| 15 | }; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 16 | |
Shawn O. Pearce | 18184f7 | 2007-10-16 00:25:34 -0400 | [diff] [blame] | 17 | static int thin, verbose; |
Uwe Kleine-König | d23842f | 2007-01-19 13:49:27 +0100 | [diff] [blame] | 18 | static const char *receivepack; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 19 | |
David Rientjes | 96f1e58 | 2006-08-15 10:23:48 -0700 | [diff] [blame] | 20 | static const char **refspec; |
| 21 | static int refspec_nr; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 22 | |
| 23 | static void add_refspec(const char *ref) |
| 24 | { |
| 25 | int nr = refspec_nr + 1; |
| 26 | refspec = xrealloc(refspec, nr * sizeof(char *)); |
| 27 | refspec[nr-1] = ref; |
| 28 | refspec_nr = nr; |
| 29 | } |
| 30 | |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 31 | static void set_refspecs(const char **refs, int nr) |
| 32 | { |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 33 | int i; |
| 34 | for (i = 0; i < nr; i++) { |
| 35 | const char *ref = refs[i]; |
| 36 | if (!strcmp("tag", ref)) { |
| 37 | char *tag; |
| 38 | int len; |
| 39 | if (nr <= ++i) |
| 40 | die("tag shorthand without <tag>"); |
| 41 | len = strlen(refs[i]) + 11; |
| 42 | tag = xmalloc(len); |
| 43 | strcpy(tag, "refs/tags/"); |
| 44 | strcat(tag, refs[i]); |
| 45 | ref = tag; |
Junio C Hamano | 411fb8b | 2006-12-13 10:03:39 -0800 | [diff] [blame] | 46 | } |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 47 | add_refspec(ref); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 48 | } |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 49 | } |
| 50 | |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 51 | static int do_push(const char *repo, int flags) |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 52 | { |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 53 | int i, errs; |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 54 | struct remote *remote = remote_get(repo); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 55 | |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 56 | if (!remote) |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 57 | die("bad repository '%s'", repo); |
| 58 | |
Shawn O. Pearce | 18184f7 | 2007-10-16 00:25:34 -0400 | [diff] [blame] | 59 | if (!refspec |
| 60 | && !(flags & TRANSPORT_PUSH_ALL) |
| 61 | && remote->push_refspec_nr) { |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 62 | refspec = remote->push_refspec; |
| 63 | refspec_nr = remote->push_refspec_nr; |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 64 | } |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 65 | errs = 0; |
Shawn O. Pearce | 28b91f8 | 2007-09-19 00:49:27 -0400 | [diff] [blame] | 66 | for (i = 0; i < remote->url_nr; i++) { |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 67 | struct transport *transport = |
Shawn O. Pearce | 28b91f8 | 2007-09-19 00:49:27 -0400 | [diff] [blame] | 68 | transport_get(remote, remote->url[i]); |
Pierre Habouzit | 60b7f38 | 2006-08-23 12:39:10 +0200 | [diff] [blame] | 69 | int err; |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 70 | if (receivepack) |
| 71 | transport_set_option(transport, |
| 72 | TRANS_OPT_RECEIVEPACK, receivepack); |
| 73 | if (thin) |
| 74 | transport_set_option(transport, TRANS_OPT_THIN, "yes"); |
| 75 | |
Linus Torvalds | bcc785f | 2006-10-30 08:28:59 -0800 | [diff] [blame] | 76 | if (verbose) |
Shawn O. Pearce | 28b91f8 | 2007-09-19 00:49:27 -0400 | [diff] [blame] | 77 | fprintf(stderr, "Pushing to %s\n", remote->url[i]); |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 78 | err = transport_push(transport, refspec_nr, refspec, flags); |
| 79 | err |= transport_disconnect(transport); |
| 80 | |
Pierre Habouzit | 60b7f38 | 2006-08-23 12:39:10 +0200 | [diff] [blame] | 81 | if (!err) |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 82 | continue; |
Junio C Hamano | 39878b0 | 2007-04-06 23:04:55 -0700 | [diff] [blame] | 83 | |
Shawn O. Pearce | 28b91f8 | 2007-09-19 00:49:27 -0400 | [diff] [blame] | 84 | error("failed to push to '%s'", remote->url[i]); |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 85 | errs++; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 86 | } |
Junio C Hamano | fd1d1b0 | 2007-04-06 23:04:53 -0700 | [diff] [blame] | 87 | return !!errs; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 88 | } |
| 89 | |
Linus Torvalds | a633fca | 2006-07-28 22:44:25 -0700 | [diff] [blame] | 90 | int cmd_push(int argc, const char **argv, const char *prefix) |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 91 | { |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 92 | int flags = 0; |
Daniel Barkalow | 378c483 | 2007-11-04 22:35:37 -0500 | [diff] [blame] | 93 | int all = 0; |
| 94 | int dry_run = 0; |
| 95 | int force = 0; |
| 96 | int tags = 0; |
Daniel Barkalow | 5751f49 | 2007-05-12 11:45:53 -0400 | [diff] [blame] | 97 | const char *repo = NULL; /* default repository */ |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 98 | |
Daniel Barkalow | 378c483 | 2007-11-04 22:35:37 -0500 | [diff] [blame] | 99 | struct option options[] = { |
| 100 | OPT__VERBOSE(&verbose), |
| 101 | OPT_STRING( 0 , "repo", &repo, "repository", "repository"), |
| 102 | OPT_BOOLEAN( 0 , "all", &all, "push all refs"), |
| 103 | OPT_BOOLEAN( 0 , "tags", &tags, "push tags"), |
| 104 | OPT_BOOLEAN( 0 , "dry-run", &dry_run, "dry run"), |
| 105 | OPT_BOOLEAN('f', "force", &force, "force updates"), |
| 106 | OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"), |
| 107 | OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"), |
| 108 | OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"), |
| 109 | OPT_END() |
| 110 | }; |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 111 | |
Daniel Barkalow | 378c483 | 2007-11-04 22:35:37 -0500 | [diff] [blame] | 112 | argc = parse_options(argc, argv, options, push_usage, 0); |
| 113 | |
| 114 | if (force) |
| 115 | flags |= TRANSPORT_PUSH_FORCE; |
| 116 | if (dry_run) |
| 117 | flags |= TRANSPORT_PUSH_DRY_RUN; |
Steffen Prohaska | 1b2486d | 2007-11-11 15:01:44 +0100 | [diff] [blame] | 118 | if (verbose) |
| 119 | flags |= TRANSPORT_PUSH_VERBOSE; |
Daniel Barkalow | 378c483 | 2007-11-04 22:35:37 -0500 | [diff] [blame] | 120 | if (tags) |
| 121 | add_refspec("refs/tags/*"); |
| 122 | if (all) |
| 123 | flags |= TRANSPORT_PUSH_ALL; |
| 124 | |
| 125 | if (argc > 0) { |
| 126 | repo = argv[0]; |
| 127 | set_refspecs(argv + 1, argc - 1); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 128 | } |
Shawn O. Pearce | 18184f7 | 2007-10-16 00:25:34 -0400 | [diff] [blame] | 129 | if ((flags & TRANSPORT_PUSH_ALL) && refspec) |
Daniel Barkalow | 378c483 | 2007-11-04 22:35:37 -0500 | [diff] [blame] | 130 | usage_with_options(push_usage, options); |
Daniel Barkalow | 8558fd9 | 2007-05-25 01:20:56 -0400 | [diff] [blame] | 131 | |
Daniel Barkalow | 9b28851 | 2007-09-10 23:03:04 -0400 | [diff] [blame] | 132 | return do_push(repo, flags); |
Linus Torvalds | 755225d | 2006-04-29 21:22:49 -0700 | [diff] [blame] | 133 | } |