6 #include "run-command.h"
10 static const char push_usage
[] = "git-push [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
12 static int all
, dry_run
, force
, thin
, verbose
;
13 static const char *receivepack
;
15 static const char **refspec
;
16 static int refspec_nr
;
18 static void add_refspec(const char *ref
)
20 int nr
= refspec_nr
+ 1;
21 refspec
= xrealloc(refspec
, nr
* sizeof(char *));
26 static void set_refspecs(const char **refs
, int nr
)
29 for (i
= 0; i
< nr
; i
++) {
30 const char *ref
= refs
[i
];
31 if (!strcmp("tag", ref
)) {
35 die("tag shorthand without <tag>");
36 len
= strlen(refs
[i
]) + 11;
38 strcpy(tag
, "refs/tags/");
46 static int do_push(const char *repo
)
52 struct remote
*remote
= remote_get(repo
);
55 die("bad repository '%s'", repo
);
57 if (remote
->receivepack
) {
58 char *rp
= xmalloc(strlen(remote
->receivepack
) + 16);
59 sprintf(rp
, "--receive-pack=%s", remote
->receivepack
);
62 if (!refspec
&& !all
&& remote
->push_refspec_nr
) {
63 refspec
= remote
->push_refspec
;
64 refspec_nr
= remote
->push_refspec_nr
;
67 argv
= xmalloc((refspec_nr
+ 10) * sizeof(char *));
68 argv
[0] = "dummy-send-pack";
71 argv
[argc
++] = "--all";
73 argv
[argc
++] = "--dry-run";
75 argv
[argc
++] = "--force";
77 argv
[argc
++] = receivepack
;
81 for (i
= 0; i
< remote
->uri_nr
; i
++) {
83 int dest_argc
= common_argc
;
84 int dest_refspec_nr
= refspec_nr
;
85 const char **dest_refspec
= refspec
;
86 const char *dest
= remote
->uri
[i
];
87 const char *sender
= "send-pack";
88 if (!prefixcmp(dest
, "http://") ||
89 !prefixcmp(dest
, "https://"))
92 char *rem
= xmalloc(strlen(remote
->name
) + 10);
93 sprintf(rem
, "--remote=%s", remote
->name
);
94 argv
[dest_argc
++] = rem
;
96 argv
[dest_argc
++] = "--thin";
99 argv
[dest_argc
++] = dest
;
100 while (dest_refspec_nr
--)
101 argv
[dest_argc
++] = *dest_refspec
++;
102 argv
[dest_argc
] = NULL
;
104 fprintf(stderr
, "Pushing to %s\n", dest
);
105 err
= run_command_v_opt(argv
, RUN_GIT_CMD
);
109 error("failed to push to '%s'", remote
->uri
[i
]);
111 case -ERR_RUN_COMMAND_FORK
:
112 error("unable to fork for %s", sender
);
113 case -ERR_RUN_COMMAND_EXEC
:
114 error("unable to exec %s", sender
);
116 case -ERR_RUN_COMMAND_WAITPID
:
117 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID
:
118 case -ERR_RUN_COMMAND_WAITPID_SIGNAL
:
119 case -ERR_RUN_COMMAND_WAITPID_NOEXIT
:
120 error("%s died with strange error", sender
);
127 int cmd_push(int argc
, const char **argv
, const char *prefix
)
130 const char *repo
= NULL
; /* default repository */
132 for (i
= 1; i
< argc
; i
++) {
133 const char *arg
= argv
[i
];
140 if (!strcmp(arg
, "-v")) {
144 if (!prefixcmp(arg
, "--repo=")) {
148 if (!strcmp(arg
, "--all")) {
152 if (!strcmp(arg
, "--dry-run")) {
156 if (!strcmp(arg
, "--tags")) {
157 add_refspec("refs/tags/*");
160 if (!strcmp(arg
, "--force") || !strcmp(arg
, "-f")) {
164 if (!strcmp(arg
, "--thin")) {
168 if (!strcmp(arg
, "--no-thin")) {
172 if (!prefixcmp(arg
, "--receive-pack=")) {
176 if (!prefixcmp(arg
, "--exec=")) {
182 set_refspecs(argv
+ i
, argc
- i
);
186 return do_push(repo
);