Coverage Report

Created: 2026-11-12 06:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/transport-helper.c
Line
Count
Source
1
#define USE_THE_REPOSITORY_VARIABLE
2
3
#include "git-compat-util.h"
4
#include "transport.h"
5
#include "quote.h"
6
#include "run-command.h"
7
#include "commit.h"
8
#include "environment.h"
9
#include "gettext.h"
10
#include "hex.h"
11
#include "object-name.h"
12
#include "repository.h"
13
#include "remote.h"
14
#include "string-list.h"
15
#include "thread-utils.h"
16
#include "sigchain.h"
17
#include "strvec.h"
18
#include "refs.h"
19
#include "refspec.h"
20
#include "transport-internal.h"
21
#include "protocol.h"
22
#include "packfile.h"
23
24
static int debug;
25
26
struct helper_data {
27
  char *name;
28
  struct child_process *helper;
29
  FILE *out;
30
  unsigned fetch : 1,
31
    import : 1,
32
    bidi_import : 1,
33
    export : 1,
34
    option : 1,
35
    push : 1,
36
    connect : 1,
37
    stateless_connect : 1,
38
    signed_tags : 1,
39
    check_connectivity : 1,
40
    no_disconnect_req : 1,
41
    no_private_update : 1,
42
    object_format : 1;
43
44
  /*
45
   * As an optimization, the transport code may invoke fetch before
46
   * get_refs_list. If this happens, and if the transport helper doesn't
47
   * support connect or stateless_connect, we need to invoke
48
   * get_refs_list ourselves if we haven't already done so. Keep track of
49
   * whether we have invoked get_refs_list.
50
   */
51
  unsigned get_refs_list_called : 1;
52
53
  char *export_marks;
54
  char *import_marks;
55
  /* These go from remote name (as in "list") to private name */
56
  struct refspec rs;
57
  /* Transport options for fetch-pack/send-pack (should one of
58
   * those be invoked).
59
   */
60
  struct git_transport_options transport_options;
61
};
62
63
static void sendline(struct helper_data *helper, struct strbuf *buffer)
64
0
{
65
0
  if (debug)
66
0
    fprintf(stderr, "Debug: Remote helper: -> %s", buffer->buf);
67
0
  if (write_in_full(helper->helper->in, buffer->buf, buffer->len) < 0)
68
0
    die_errno(_("full write to remote helper failed"));
69
0
}
70
71
static int recvline_fh(FILE *helper, struct strbuf *buffer)
72
0
{
73
0
  strbuf_reset(buffer);
74
0
  if (debug)
75
0
    fprintf(stderr, "Debug: Remote helper: Waiting...\n");
76
0
  if (strbuf_getline(buffer, helper) == EOF) {
77
0
    if (debug)
78
0
      fprintf(stderr, "Debug: Remote helper quit.\n");
79
0
    return 1;
80
0
  }
81
82
0
  if (debug)
83
0
    fprintf(stderr, "Debug: Remote helper: <- %s\n", buffer->buf);
84
0
  return 0;
85
0
}
86
87
static int recvline(struct helper_data *helper, struct strbuf *buffer)
88
0
{
89
0
  return recvline_fh(helper->out, buffer);
90
0
}
91
92
static int write_constant_gently(int fd, const char *str)
93
0
{
94
0
  if (debug)
95
0
    fprintf(stderr, "Debug: Remote helper: -> %s", str);
96
0
  if (write_in_full(fd, str, strlen(str)) < 0)
97
0
    return -1;
98
0
  return 0;
99
0
}
100
101
static void write_constant(int fd, const char *str)
102
0
{
103
0
  if (write_constant_gently(fd, str) < 0)
104
0
    die_errno(_("full write to remote helper failed"));
105
0
}
106
107
static const char *remove_ext_force(const char *url)
108
0
{
109
0
  if (url) {
110
0
    const char *colon = strchr(url, ':');
111
0
    if (colon && colon[1] == ':')
112
0
      return colon + 2;
113
0
  }
114
0
  return url;
115
0
}
116
117
static void do_take_over(struct transport *transport)
118
0
{
119
0
  struct helper_data *data;
120
0
  data = (struct helper_data *)transport->data;
121
0
  transport_take_over(transport, data->helper);
122
0
  fclose(data->out);
123
0
  free(data->name);
124
0
  free(data);
125
0
}
126
127
static void standard_options(struct transport *t);
128
129
static struct child_process *get_helper(struct transport *transport)
130
0
{
131
0
  struct helper_data *data = transport->data;
132
0
  struct strbuf buf = STRBUF_INIT;
133
0
  struct child_process *helper;
134
0
  int duped;
135
0
  int code;
136
137
0
  if (data->helper)
138
0
    return data->helper;
139
140
0
  helper = xmalloc(sizeof(*helper));
141
0
  child_process_init(helper);
142
0
  helper->in = -1;
143
0
  helper->out = -1;
144
0
  helper->err = 0;
145
0
  strvec_pushf(&helper->args, "remote-%s", data->name);
146
0
  strvec_push(&helper->args, transport->remote->name);
147
0
  strvec_push(&helper->args, remove_ext_force(transport->url));
148
0
  helper->git_cmd = 1;
149
0
  helper->silent_exec_failure = 1;
150
151
0
  if (have_git_dir())
152
0
    strvec_pushf(&helper->env, "%s=%s",
153
0
           GIT_DIR_ENVIRONMENT, repo_get_git_dir(the_repository));
154
155
0
  helper->trace2_child_class = helper->args.v[0]; /* "remote-<name>" */
156
157
0
  code = start_command(helper);
158
0
  if (code < 0 && errno == ENOENT)
159
0
    die(_("unable to find remote helper for '%s'"), data->name);
160
0
  else if (code != 0)
161
0
    exit(code);
162
163
0
  data->helper = helper;
164
0
  data->no_disconnect_req = 0;
165
0
  refspec_init_fetch(&data->rs, the_hash_algo);
166
167
  /*
168
   * Open the output as FILE* so strbuf_getline_*() family of
169
   * functions can be used.
170
   * Do this with duped fd because fclose() will close the fd,
171
   * and stuff like taking over will require the fd to remain.
172
   */
173
0
  duped = dup(helper->out);
174
0
  if (duped < 0)
175
0
    die_errno(_("can't dup helper output fd"));
176
0
  data->out = xfdopen(duped, "r");
177
178
0
  sigchain_push(SIGPIPE, SIG_IGN);
179
0
  if (write_constant_gently(helper->in, "capabilities\n") < 0)
180
0
    die("remote helper '%s' aborted session", data->name);
181
0
  sigchain_pop(SIGPIPE);
182
183
0
  while (1) {
184
0
    const char *capname, *arg;
185
0
    int mandatory = 0;
186
0
    if (recvline(data, &buf))
187
0
      die("remote helper '%s' aborted session", data->name);
188
189
0
    if (!*buf.buf)
190
0
      break;
191
192
0
    if (*buf.buf == '*') {
193
0
      capname = buf.buf + 1;
194
0
      mandatory = 1;
195
0
    } else
196
0
      capname = buf.buf;
197
198
0
    if (debug)
199
0
      fprintf(stderr, "Debug: Got cap %s\n", capname);
200
0
    if (!strcmp(capname, "fetch"))
201
0
      data->fetch = 1;
202
0
    else if (!strcmp(capname, "option"))
203
0
      data->option = 1;
204
0
    else if (!strcmp(capname, "push"))
205
0
      data->push = 1;
206
0
    else if (!strcmp(capname, "import"))
207
0
      data->import = 1;
208
0
    else if (!strcmp(capname, "bidi-import"))
209
0
      data->bidi_import = 1;
210
0
    else if (!strcmp(capname, "export"))
211
0
      data->export = 1;
212
0
    else if (!strcmp(capname, "check-connectivity"))
213
0
      data->check_connectivity = 1;
214
0
    else if (skip_prefix(capname, "refspec ", &arg)) {
215
0
      refspec_append(&data->rs, arg);
216
0
    } else if (!strcmp(capname, "connect")) {
217
0
      data->connect = 1;
218
0
    } else if (!strcmp(capname, "stateless-connect")) {
219
0
      data->stateless_connect = 1;
220
0
    } else if (!strcmp(capname, "signed-tags")) {
221
0
      data->signed_tags = 1;
222
0
    } else if (skip_prefix(capname, "export-marks ", &arg)) {
223
0
      data->export_marks = xstrdup(arg);
224
0
    } else if (skip_prefix(capname, "import-marks ", &arg)) {
225
0
      data->import_marks = xstrdup(arg);
226
0
    } else if (starts_with(capname, "no-private-update")) {
227
0
      data->no_private_update = 1;
228
0
    } else if (starts_with(capname, "object-format")) {
229
0
      data->object_format = 1;
230
0
    } else if (mandatory) {
231
0
      die(_("unknown mandatory capability %s; this remote "
232
0
            "helper probably needs newer version of Git"),
233
0
          capname);
234
0
    }
235
0
  }
236
0
  if (!data->rs.nr && (data->import || data->bidi_import || data->export)) {
237
0
    warning(_("this remote helper should implement refspec capability"));
238
0
  }
239
0
  strbuf_release(&buf);
240
0
  if (debug)
241
0
    fprintf(stderr, "Debug: Capabilities complete.\n");
242
0
  standard_options(transport);
243
0
  return data->helper;
244
0
}
245
246
static int disconnect_helper(struct transport *transport)
247
0
{
248
0
  struct helper_data *data = transport->data;
249
0
  int res = 0;
250
251
0
  if (data->helper) {
252
0
    if (debug)
253
0
      fprintf(stderr, "Debug: Disconnecting.\n");
254
0
    if (!data->no_disconnect_req) {
255
      /*
256
       * Ignore write errors; there's nothing we can do,
257
       * since we're about to close the pipe anyway. And the
258
       * most likely error is EPIPE due to the helper dying
259
       * to report an error itself.
260
       */
261
0
      sigchain_push(SIGPIPE, SIG_IGN);
262
0
      xwrite(data->helper->in, "\n", 1);
263
0
      sigchain_pop(SIGPIPE);
264
0
    }
265
0
    close(data->helper->in);
266
0
    close(data->helper->out);
267
0
    fclose(data->out);
268
0
    res = finish_command(data->helper);
269
0
    FREE_AND_NULL(data->helper);
270
0
  }
271
0
  FREE_AND_NULL(data->name);
272
0
  return res;
273
0
}
274
275
static const char *unsupported_options[] = {
276
  TRANS_OPT_UPLOADPACK,
277
  TRANS_OPT_RECEIVEPACK,
278
  TRANS_OPT_THIN,
279
  TRANS_OPT_KEEP
280
  };
281
282
static const char *boolean_options[] = {
283
  TRANS_OPT_THIN,
284
  TRANS_OPT_KEEP,
285
  TRANS_OPT_FOLLOWTAGS,
286
  TRANS_OPT_DEEPEN_RELATIVE
287
  };
288
289
static int strbuf_set_helper_option(struct helper_data *data,
290
            struct strbuf *buf)
291
0
{
292
0
  int ret;
293
294
0
  sendline(data, buf);
295
0
  if (recvline(data, buf))
296
0
    exit(128);
297
298
0
  if (!strcmp(buf->buf, "ok"))
299
0
    ret = 0;
300
0
  else if (starts_with(buf->buf, "error"))
301
0
    ret = -1;
302
0
  else if (!strcmp(buf->buf, "unsupported"))
303
0
    ret = 1;
304
0
  else {
305
0
    warning(_("%s unexpectedly said: '%s'"), data->name, buf->buf);
306
0
    ret = 1;
307
0
  }
308
0
  return ret;
309
0
}
310
311
static int string_list_set_helper_option(struct helper_data *data,
312
           const char *name,
313
           struct string_list *list)
314
0
{
315
0
  struct strbuf buf = STRBUF_INIT;
316
0
  int ret = 0;
317
318
0
  for (size_t i = 0; i < list->nr; i++) {
319
0
    strbuf_addf(&buf, "option %s ", name);
320
0
    quote_c_style(list->items[i].string, &buf, NULL, 0);
321
0
    strbuf_addch(&buf, '\n');
322
323
0
    if ((ret = strbuf_set_helper_option(data, &buf)))
324
0
      break;
325
0
    strbuf_reset(&buf);
326
0
  }
327
0
  strbuf_release(&buf);
328
0
  return ret;
329
0
}
330
331
static int set_helper_option(struct transport *transport,
332
        const char *name, const char *value)
333
0
{
334
0
  struct helper_data *data = transport->data;
335
0
  struct strbuf buf = STRBUF_INIT;
336
0
  int ret, is_bool = 0;
337
338
0
  get_helper(transport);
339
340
0
  if (!data->option)
341
0
    return 1;
342
343
0
  if (!strcmp(name, "deepen-not"))
344
0
    return string_list_set_helper_option(data, name,
345
0
                 (struct string_list *)value);
346
347
0
  for (size_t i = 0; i < ARRAY_SIZE(unsupported_options); i++) {
348
0
    if (!strcmp(name, unsupported_options[i]))
349
0
      return 1;
350
0
  }
351
352
0
  for (size_t i = 0; i < ARRAY_SIZE(boolean_options); i++) {
353
0
    if (!strcmp(name, boolean_options[i])) {
354
0
      is_bool = 1;
355
0
      break;
356
0
    }
357
0
  }
358
359
0
  strbuf_addf(&buf, "option %s ", name);
360
0
  if (is_bool)
361
0
    strbuf_addstr(&buf, value ? "true" : "false");
362
0
  else
363
0
    quote_c_style(value, &buf, NULL, 0);
364
0
  strbuf_addch(&buf, '\n');
365
366
0
  ret = strbuf_set_helper_option(data, &buf);
367
0
  strbuf_release(&buf);
368
0
  return ret;
369
0
}
370
371
static void standard_options(struct transport *t)
372
0
{
373
0
  char buf[16];
374
0
  int v = t->verbose;
375
376
0
  set_helper_option(t, "progress", t->progress ? "true" : "false");
377
378
0
  xsnprintf(buf, sizeof(buf), "%d", v + 1);
379
0
  set_helper_option(t, "verbosity", buf);
380
381
0
  switch (t->family) {
382
0
  case TRANSPORT_FAMILY_ALL:
383
    /*
384
     * this is already the default,
385
     * do not break old remote helpers by setting "all" here
386
     */
387
0
    break;
388
0
  case TRANSPORT_FAMILY_IPV4:
389
0
    set_helper_option(t, "family", "ipv4");
390
0
    break;
391
0
  case TRANSPORT_FAMILY_IPV6:
392
0
    set_helper_option(t, "family", "ipv6");
393
0
    break;
394
0
  }
395
0
}
396
397
static int release_helper(struct transport *transport)
398
0
{
399
0
  int res = 0;
400
0
  struct helper_data *data = transport->data;
401
0
  refspec_clear(&data->rs);
402
0
  free(data->import_marks);
403
0
  free(data->export_marks);
404
0
  transport_options_release(&data->transport_options);
405
0
  res = disconnect_helper(transport);
406
0
  free(transport->data);
407
0
  return res;
408
0
}
409
410
static int fetch_with_fetch(struct transport *transport,
411
          int nr_heads, struct ref **to_fetch)
412
0
{
413
0
  struct helper_data *data = transport->data;
414
0
  int i;
415
0
  struct strbuf buf = STRBUF_INIT;
416
417
0
  for (i = 0; i < nr_heads; i++) {
418
0
    const struct ref *posn = to_fetch[i];
419
0
    if (posn->status & REF_STATUS_UPTODATE)
420
0
      continue;
421
422
0
    strbuf_addf(&buf, "fetch %s %s\n",
423
0
          oid_to_hex(&posn->old_oid),
424
0
          posn->symref ? posn->symref : posn->name);
425
0
  }
426
427
0
  strbuf_addch(&buf, '\n');
428
0
  sendline(data, &buf);
429
430
0
  while (1) {
431
0
    const char *name;
432
433
0
    if (recvline(data, &buf))
434
0
      exit(128);
435
436
0
    if (skip_prefix(buf.buf, "lock ", &name)) {
437
0
      if (transport->pack_lockfiles.nr)
438
0
        warning(_("%s also locked %s"), data->name, name);
439
0
      else
440
0
        string_list_append(&transport->pack_lockfiles,
441
0
               name);
442
0
    }
443
0
    else if (data->check_connectivity &&
444
0
       data->transport_options.check_self_contained_and_connected &&
445
0
       !strcmp(buf.buf, "connectivity-ok"))
446
0
      data->transport_options.self_contained_and_connected = 1;
447
0
    else if (!buf.len)
448
0
      break;
449
0
    else
450
0
      warning(_("%s unexpectedly said: '%s'"), data->name, buf.buf);
451
0
  }
452
0
  strbuf_release(&buf);
453
454
0
  odb_reprepare(the_repository->objects);
455
0
  return 0;
456
0
}
457
458
static int get_importer(struct transport *transport, struct child_process *fastimport)
459
0
{
460
0
  struct child_process *helper = get_helper(transport);
461
0
  struct helper_data *data = transport->data;
462
0
  int cat_blob_fd, code;
463
0
  child_process_init(fastimport);
464
0
  fastimport->in = xdup(helper->out);
465
0
  strvec_push(&fastimport->args, "fast-import");
466
0
  strvec_push(&fastimport->args, "--allow-unsafe-features");
467
0
  strvec_push(&fastimport->args, debug ? "--stats" : "--quiet");
468
469
0
  if (data->bidi_import) {
470
0
    cat_blob_fd = xdup(helper->in);
471
0
    strvec_pushf(&fastimport->args, "--cat-blob-fd=%d", cat_blob_fd);
472
0
  }
473
0
  fastimport->git_cmd = 1;
474
475
0
  code = start_command(fastimport);
476
0
  return code;
477
0
}
478
479
static int get_exporter(struct transport *transport,
480
      struct child_process *fastexport,
481
      struct string_list *revlist_args)
482
0
{
483
0
  struct helper_data *data = transport->data;
484
0
  struct child_process *helper = get_helper(transport);
485
486
0
  child_process_init(fastexport);
487
488
  /* we need to duplicate helper->in because we want to use it after
489
   * fastexport is done with it. */
490
0
  fastexport->out = dup(helper->in);
491
0
  if (fastexport->out < 0)
492
0
    return error_errno(_("could not dup helper output fd"));
493
0
  strvec_push(&fastexport->args, "fast-export");
494
0
  strvec_push(&fastexport->args, "--use-done-feature");
495
0
  strvec_push(&fastexport->args, data->signed_tags ?
496
0
    "--signed-tags=verbatim" : "--signed-tags=warn-strip");
497
0
  if (data->export_marks)
498
0
    strvec_pushf(&fastexport->args, "--export-marks=%s.tmp", data->export_marks);
499
0
  if (data->import_marks)
500
0
    strvec_pushf(&fastexport->args, "--import-marks=%s", data->import_marks);
501
502
0
  for (size_t i = 0; i < revlist_args->nr; i++)
503
0
    strvec_push(&fastexport->args, revlist_args->items[i].string);
504
505
0
  fastexport->git_cmd = 1;
506
0
  return start_command(fastexport);
507
0
}
508
509
static int fetch_with_import(struct transport *transport,
510
           int nr_heads, struct ref **to_fetch)
511
0
{
512
0
  struct child_process fastimport;
513
0
  struct helper_data *data = transport->data;
514
0
  int i;
515
0
  struct ref *posn;
516
0
  struct strbuf buf = STRBUF_INIT;
517
518
0
  get_helper(transport);
519
520
0
  if (get_importer(transport, &fastimport))
521
0
    die(_("couldn't run fast-import"));
522
523
0
  for (i = 0; i < nr_heads; i++) {
524
0
    posn = to_fetch[i];
525
0
    if (posn->status & REF_STATUS_UPTODATE)
526
0
      continue;
527
528
0
    strbuf_addf(&buf, "import %s\n",
529
0
          posn->symref ? posn->symref : posn->name);
530
0
    sendline(data, &buf);
531
0
    strbuf_reset(&buf);
532
0
  }
533
534
0
  write_constant(data->helper->in, "\n");
535
  /*
536
   * remote-helpers that advertise the bidi-import capability are required to
537
   * buffer the complete batch of import commands until this newline before
538
   * sending data to fast-import.
539
   * These helpers read back data from fast-import on their stdin, which could
540
   * be mixed with import commands, otherwise.
541
   */
542
543
0
  if (finish_command(&fastimport))
544
0
    die(_("error while running fast-import"));
545
546
  /*
547
   * The fast-import stream of a remote helper that advertises
548
   * the "refspec" capability writes to the refs named after the
549
   * right hand side of the first refspec matching each ref we
550
   * were fetching.
551
   *
552
   * (If no "refspec" capability was specified, for historical
553
   * reasons we default to the equivalent of *:*.)
554
   *
555
   * Store the result in to_fetch[i].old_sha1.  Callers such
556
   * as "git fetch" can use the value to write feedback to the
557
   * terminal, populate FETCH_HEAD, and determine what new value
558
   * should be written to peer_ref if the update is a
559
   * fast-forward or this is a forced update.
560
   */
561
0
  for (i = 0; i < nr_heads; i++) {
562
0
    char *private, *name;
563
0
    posn = to_fetch[i];
564
0
    if (posn->status & REF_STATUS_UPTODATE)
565
0
      continue;
566
0
    name = posn->symref ? posn->symref : posn->name;
567
0
    if (data->rs.nr)
568
0
      private = apply_refspecs(&data->rs, name);
569
0
    else
570
0
      private = xstrdup(name);
571
0
    if (private) {
572
0
      if (refs_read_ref(get_main_ref_store(the_repository), private, &posn->old_oid) < 0)
573
0
        die(_("could not read ref %s"), private);
574
0
      free(private);
575
0
    }
576
0
  }
577
0
  strbuf_release(&buf);
578
0
  return 0;
579
0
}
580
581
static int run_connect(struct transport *transport, struct strbuf *cmdbuf)
582
0
{
583
0
  struct helper_data *data = transport->data;
584
0
  int ret = 0;
585
0
  int duped;
586
0
  FILE *input;
587
0
  struct child_process *helper;
588
589
0
  helper = get_helper(transport);
590
591
  /*
592
   * Yes, dup the pipe another time, as we need unbuffered version
593
   * of input pipe as FILE*. fclose() closes the underlying fd and
594
   * stream buffering only can be changed before first I/O operation
595
   * on it.
596
   */
597
0
  duped = dup(helper->out);
598
0
  if (duped < 0)
599
0
    die_errno(_("can't dup helper output fd"));
600
0
  input = xfdopen(duped, "r");
601
0
  setvbuf(input, NULL, _IONBF, 0);
602
603
0
  sendline(data, cmdbuf);
604
0
  if (recvline_fh(input, cmdbuf))
605
0
    exit(128);
606
607
0
  if (!strcmp(cmdbuf->buf, "")) {
608
0
    data->no_disconnect_req = 1;
609
0
    if (debug)
610
0
      fprintf(stderr, "Debug: Smart transport connection "
611
0
        "ready.\n");
612
0
    ret = 1;
613
0
  } else if (!strcmp(cmdbuf->buf, "fallback")) {
614
0
    if (debug)
615
0
      fprintf(stderr, "Debug: Falling back to dumb "
616
0
        "transport.\n");
617
0
  } else {
618
0
    die(_("unknown response to connect: %s"),
619
0
        cmdbuf->buf);
620
0
  }
621
622
0
  fclose(input);
623
0
  return ret;
624
0
}
625
626
static const char *connect_service_cmd(enum git_connect_service service)
627
0
{
628
0
  switch (service) {
629
0
  case GIT_CONNECT_UPLOAD_PACK:
630
0
    return "git-upload-pack";
631
0
  case GIT_CONNECT_RECEIVE_PACK:
632
0
    return "git-receive-pack";
633
0
  case GIT_CONNECT_UPLOAD_ARCHIVE:
634
0
    return "git-upload-archive";
635
0
  }
636
0
  BUG("unknown git_connect_service: %d", service);
637
0
}
638
639
static int process_connect_service(struct transport *transport,
640
           enum git_connect_service service,
641
           const char *exec)
642
0
{
643
0
  struct helper_data *data = transport->data;
644
0
  struct strbuf cmdbuf = STRBUF_INIT;
645
0
  int ret = 0;
646
647
  /*
648
   * Handle --upload-pack and friends. This is fire and forget...
649
   * just warn if it fails.
650
   */
651
0
  if (strcmp(connect_service_cmd(service), exec)) {
652
0
    int r = set_helper_option(transport, "servpath", exec);
653
0
    if (r > 0)
654
0
      warning(_("setting remote service path not supported by protocol"));
655
0
    else if (r < 0)
656
0
      warning(_("invalid remote service path"));
657
0
  }
658
659
0
  if (data->connect) {
660
0
    strbuf_addf(&cmdbuf, "connect %s\n",
661
0
          connect_service_cmd(service));
662
0
    ret = run_connect(transport, &cmdbuf);
663
0
  } else if (data->stateless_connect &&
664
0
       (get_protocol_version_config() == protocol_v2) &&
665
0
       (service == GIT_CONNECT_UPLOAD_PACK ||
666
0
        service == GIT_CONNECT_UPLOAD_ARCHIVE)) {
667
0
    strbuf_addf(&cmdbuf, "stateless-connect %s\n",
668
0
          connect_service_cmd(service));
669
0
    ret = run_connect(transport, &cmdbuf);
670
0
    if (ret)
671
0
      transport->stateless_rpc = 1;
672
0
  }
673
674
0
  strbuf_release(&cmdbuf);
675
0
  return ret;
676
0
}
677
678
static int process_connect(struct transport *transport,
679
             int for_push)
680
0
{
681
0
  struct helper_data *data = transport->data;
682
0
  enum git_connect_service service;
683
0
  const char *exec;
684
0
  int ret;
685
686
0
  service = for_push ? GIT_CONNECT_RECEIVE_PACK : GIT_CONNECT_UPLOAD_PACK;
687
0
  if (for_push)
688
0
    exec = data->transport_options.receivepack;
689
0
  else
690
0
    exec = data->transport_options.uploadpack;
691
692
0
  ret = process_connect_service(transport, service, exec);
693
0
  if (ret)
694
0
    do_take_over(transport);
695
0
  return ret;
696
0
}
697
698
static int connect_helper(struct transport *transport, enum git_connect_service service,
699
        const char *exec, int fd[2])
700
0
{
701
0
  struct helper_data *data = transport->data;
702
703
  /* Get_helper so connect is inited. */
704
0
  get_helper(transport);
705
706
0
  if (!process_connect_service(transport, service, exec))
707
0
    die(_("can't connect to subservice %s"),
708
0
        connect_service_cmd(service));
709
710
0
  fd[0] = data->helper->out;
711
0
  fd[1] = data->helper->in;
712
713
0
  do_take_over(transport);
714
0
  return 0;
715
0
}
716
717
static struct ref *get_refs_list_using_list(struct transport *transport,
718
              int for_push);
719
720
static int fetch_refs(struct transport *transport,
721
          int nr_heads, struct ref **to_fetch)
722
0
{
723
0
  struct helper_data *data = transport->data;
724
0
  int i, count;
725
726
0
  get_helper(transport);
727
728
0
  if (process_connect(transport, 0))
729
0
    return transport->vtable->fetch_refs(transport, nr_heads, to_fetch);
730
731
  /*
732
   * If we reach here, then the server, the client, and/or the transport
733
   * helper does not support protocol v2. --negotiate-only requires
734
   * protocol v2.
735
   */
736
0
  if (data->transport_options.acked_commits) {
737
0
    warning(_("--negotiate-only requires protocol v2"));
738
0
    return -1;
739
0
  }
740
741
0
  if (!data->get_refs_list_called) {
742
    /*
743
     * We do not care about the list of refs returned, but only
744
     * that the "list" command was sent.
745
     */
746
0
    struct ref *dummy = get_refs_list_using_list(transport, 0);
747
0
    free_refs(dummy);
748
0
  }
749
750
0
  count = 0;
751
0
  for (i = 0; i < nr_heads; i++)
752
0
    if (!(to_fetch[i]->status & REF_STATUS_UPTODATE))
753
0
      count++;
754
755
0
  if (!count)
756
0
    return 0;
757
758
0
  if (data->check_connectivity &&
759
0
      data->transport_options.check_self_contained_and_connected)
760
0
    set_helper_option(transport, "check-connectivity", "true");
761
762
0
  if (transport->cloning)
763
0
    set_helper_option(transport, "cloning", "true");
764
765
0
  if (data->transport_options.update_shallow)
766
0
    set_helper_option(transport, "update-shallow", "true");
767
768
0
  if (data->transport_options.refetch)
769
0
    set_helper_option(transport, "refetch", "true");
770
771
0
  if (data->transport_options.filter_options.choice) {
772
0
    const char *spec = expand_list_objects_filter_spec(
773
0
      &data->transport_options.filter_options);
774
0
    set_helper_option(transport, "filter", spec);
775
0
  }
776
777
0
  if (data->transport_options.negotiation_restrict_tips)
778
0
    warning(_("ignoring %s because the protocol does not support it."),
779
0
      "--negotiation-restrict");
780
781
0
  if (data->fetch)
782
0
    return fetch_with_fetch(transport, nr_heads, to_fetch);
783
784
0
  if (data->import)
785
0
    return fetch_with_import(transport, nr_heads, to_fetch);
786
787
0
  return -1;
788
0
}
789
790
static int fetch_object_info_helper(struct transport *transport,
791
            const struct oid_array *oids,
792
            struct fetch_object_info_results *results)
793
0
{
794
0
  get_helper(transport);
795
0
  if (process_connect(transport, 0))
796
0
    return transport->vtable->fetch_object_info(transport, oids,
797
0
                  results);
798
799
0
  die(_("object-info requires protocol v2"));
800
0
}
801
802
struct push_update_ref_state {
803
  struct ref *hint;
804
  struct ref_push_report *report;
805
  int new_report;
806
};
807
808
static int push_update_ref_status(struct strbuf *buf,
809
           struct push_update_ref_state *state,
810
           struct ref *remote_refs)
811
0
{
812
0
  char *refname, *msg;
813
0
  int status, forced = 0;
814
815
0
  if (starts_with(buf->buf, "option ")) {
816
0
    struct object_id old_oid, new_oid;
817
0
    char *key;
818
0
    const char *val;
819
0
    char *p;
820
821
0
    if (!state->hint || !(state->report || state->new_report))
822
0
      die(_("'option' without a matching 'ok/error' directive"));
823
0
    if (state->new_report) {
824
0
      if (!state->hint->report) {
825
0
        CALLOC_ARRAY(state->hint->report, 1);
826
0
        state->report = state->hint->report;
827
0
      } else {
828
0
        state->report = state->hint->report;
829
0
        while (state->report->next)
830
0
          state->report = state->report->next;
831
0
        CALLOC_ARRAY(state->report->next, 1);
832
0
        state->report = state->report->next;
833
0
      }
834
0
      state->new_report = 0;
835
0
    }
836
0
    key = buf->buf + 7;
837
0
    p = strchr(key, ' ');
838
0
    if (p)
839
0
      *p++ = '\0';
840
0
    val = p;
841
0
    if (!strcmp(key, "refname"))
842
0
      state->report->ref_name = xstrdup_or_null(val);
843
0
    else if (!strcmp(key, "old-oid") && val &&
844
0
       !parse_oid_hex(val, &old_oid, &val))
845
0
      state->report->old_oid = oiddup(&old_oid);
846
0
    else if (!strcmp(key, "new-oid") && val &&
847
0
       !parse_oid_hex(val, &new_oid, &val))
848
0
      state->report->new_oid = oiddup(&new_oid);
849
0
    else if (!strcmp(key, "forced-update"))
850
0
      state->report->forced_update = 1;
851
    /* Not update remote namespace again. */
852
0
    return 1;
853
0
  }
854
855
0
  state->report = NULL;
856
0
  state->new_report = 0;
857
858
0
  if (starts_with(buf->buf, "ok ")) {
859
0
    status = REF_STATUS_OK;
860
0
    refname = buf->buf + 3;
861
0
  } else if (starts_with(buf->buf, "error ")) {
862
0
    status = REF_STATUS_REMOTE_REJECT;
863
0
    refname = buf->buf + 6;
864
0
  } else
865
0
    die(_("expected ok/error, helper said '%s'"), buf->buf);
866
867
0
  msg = strchr(refname, ' ');
868
0
  if (msg) {
869
0
    struct strbuf msg_buf = STRBUF_INIT;
870
0
    const char *end;
871
872
0
    *msg++ = '\0';
873
0
    if (!unquote_c_style(&msg_buf, msg, &end))
874
0
      msg = strbuf_detach(&msg_buf, NULL);
875
0
    else
876
0
      msg = xstrdup(msg);
877
0
    strbuf_release(&msg_buf);
878
879
0
    if (!strcmp(msg, "no match")) {
880
0
      status = REF_STATUS_NONE;
881
0
      FREE_AND_NULL(msg);
882
0
    }
883
0
    else if (!strcmp(msg, "up to date")) {
884
0
      status = REF_STATUS_UPTODATE;
885
0
      FREE_AND_NULL(msg);
886
0
    }
887
0
    else if (!strcmp(msg, "non-fast forward")) {
888
0
      status = REF_STATUS_REJECT_NONFASTFORWARD;
889
0
      FREE_AND_NULL(msg);
890
0
    }
891
0
    else if (!strcmp(msg, "already exists")) {
892
0
      status = REF_STATUS_REJECT_ALREADY_EXISTS;
893
0
      FREE_AND_NULL(msg);
894
0
    }
895
0
    else if (!strcmp(msg, "fetch first")) {
896
0
      status = REF_STATUS_REJECT_FETCH_FIRST;
897
0
      FREE_AND_NULL(msg);
898
0
    }
899
0
    else if (!strcmp(msg, "needs force")) {
900
0
      status = REF_STATUS_REJECT_NEEDS_FORCE;
901
0
      FREE_AND_NULL(msg);
902
0
    }
903
0
    else if (!strcmp(msg, "stale info")) {
904
0
      status = REF_STATUS_REJECT_STALE;
905
0
      FREE_AND_NULL(msg);
906
0
    }
907
0
    else if (!strcmp(msg, "remote ref updated since checkout")) {
908
0
      status = REF_STATUS_REJECT_REMOTE_UPDATED;
909
0
      FREE_AND_NULL(msg);
910
0
    }
911
0
    else if (!strcmp(msg, "forced update")) {
912
0
      forced = 1;
913
0
      FREE_AND_NULL(msg);
914
0
    }
915
0
    else if (!strcmp(msg, "expecting report")) {
916
0
      status = REF_STATUS_EXPECTING_REPORT;
917
0
      FREE_AND_NULL(msg);
918
0
    }
919
0
  }
920
921
0
  if (state->hint)
922
0
    state->hint = find_ref_by_name(state->hint, refname);
923
0
  if (!state->hint)
924
0
    state->hint = find_ref_by_name(remote_refs, refname);
925
0
  if (!state->hint) {
926
0
    warning(_("helper reported unexpected status of %s"), refname);
927
0
    return 1;
928
0
  }
929
930
0
  if (state->hint->status != REF_STATUS_NONE) {
931
    /*
932
     * Earlier, the ref was marked not to be pushed, so ignore the ref
933
     * status reported by the remote helper if the latter is 'no match'.
934
     */
935
0
    if (status == REF_STATUS_NONE)
936
0
      return 1;
937
0
  }
938
939
0
  if (status == REF_STATUS_OK)
940
0
    state->new_report = 1;
941
0
  state->hint->status = status;
942
0
  state->hint->forced_update |= forced;
943
0
  state->hint->remote_status = msg;
944
0
  return !(status == REF_STATUS_OK);
945
0
}
946
947
static int push_update_refs_status(struct helper_data *data,
948
            struct ref *remote_refs,
949
            int flags)
950
0
{
951
0
  struct ref *ref;
952
0
  struct ref_push_report *report;
953
0
  struct strbuf buf = STRBUF_INIT;
954
0
  struct push_update_ref_state state = { remote_refs, NULL, 0 };
955
956
0
  for (;;) {
957
0
    if (recvline(data, &buf)) {
958
0
      strbuf_release(&buf);
959
0
      return 1;
960
0
    }
961
0
    if (!buf.len)
962
0
      break;
963
0
    push_update_ref_status(&buf, &state, remote_refs);
964
0
  }
965
0
  strbuf_release(&buf);
966
967
0
  if (flags & TRANSPORT_PUSH_DRY_RUN || !data->rs.nr || data->no_private_update)
968
0
    return 0;
969
970
  /* propagate back the update to the remote namespace */
971
0
  for (ref = remote_refs; ref; ref = ref->next) {
972
0
    char *private;
973
974
0
    if (ref->status != REF_STATUS_OK)
975
0
      continue;
976
977
0
    if (!ref->report) {
978
0
      private = apply_refspecs(&data->rs, ref->name);
979
0
      if (!private)
980
0
        continue;
981
0
      refs_update_ref(get_main_ref_store(the_repository),
982
0
          "update by helper", private,
983
0
          &(ref->new_oid),
984
0
          NULL, 0, 0);
985
0
      free(private);
986
0
    } else {
987
0
      for (report = ref->report; report; report = report->next) {
988
0
        private = apply_refspecs(&data->rs,
989
0
               report->ref_name
990
0
               ? report->ref_name
991
0
               : ref->name);
992
0
        if (!private)
993
0
          continue;
994
0
        refs_update_ref(get_main_ref_store(the_repository),
995
0
            "update by helper", private,
996
0
            report->new_oid
997
0
            ? report->new_oid
998
0
            : &(ref->new_oid),
999
0
            NULL, 0, 0);
1000
0
        free(private);
1001
0
      }
1002
0
    }
1003
0
  }
1004
0
  return 0;
1005
0
}
1006
1007
static void set_common_push_options(struct transport *transport,
1008
           const char *name, int flags)
1009
0
{
1010
0
  if (flags & TRANSPORT_PUSH_DRY_RUN) {
1011
0
    if (set_helper_option(transport, "dry-run", "true") != 0)
1012
0
      die(_("helper %s does not support dry-run"), name);
1013
0
  } else if (flags & TRANSPORT_PUSH_CERT_ALWAYS) {
1014
0
    if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "true") != 0)
1015
0
      die(_("helper %s does not support --signed"), name);
1016
0
  } else if (flags & TRANSPORT_PUSH_CERT_IF_ASKED) {
1017
0
    if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "if-asked") != 0)
1018
0
      die(_("helper %s does not support --signed=if-asked"), name);
1019
0
  }
1020
1021
0
  if (flags & TRANSPORT_PUSH_ATOMIC)
1022
0
    if (set_helper_option(transport, TRANS_OPT_ATOMIC, "true") != 0)
1023
0
      die(_("helper %s does not support --atomic"), name);
1024
1025
0
  if (flags & TRANSPORT_PUSH_FORCE_IF_INCLUDES)
1026
0
    if (set_helper_option(transport, TRANS_OPT_FORCE_IF_INCLUDES, "true") != 0)
1027
0
      die(_("helper %s does not support --%s"),
1028
0
          name, TRANS_OPT_FORCE_IF_INCLUDES);
1029
1030
0
  if (flags & TRANSPORT_PUSH_OPTIONS) {
1031
0
    struct string_list_item *item;
1032
0
    for_each_string_list_item(item, transport->push_options)
1033
0
      if (set_helper_option(transport, "push-option", item->string) != 0)
1034
0
        die(_("helper %s does not support 'push-option'"), name);
1035
0
  }
1036
0
}
1037
1038
static int push_refs_with_push(struct transport *transport,
1039
             struct ref *remote_refs, int flags)
1040
0
{
1041
0
  int force_all = flags & TRANSPORT_PUSH_FORCE;
1042
0
  int mirror = flags & TRANSPORT_PUSH_MIRROR;
1043
0
  int atomic = flags & TRANSPORT_PUSH_ATOMIC;
1044
0
  struct helper_data *data = transport->data;
1045
0
  struct strbuf buf = STRBUF_INIT;
1046
0
  struct ref *ref;
1047
0
  struct string_list cas_options = STRING_LIST_INIT_DUP;
1048
0
  struct string_list_item *cas_option;
1049
1050
0
  get_helper(transport);
1051
0
  if (!data->push)
1052
0
    return 1;
1053
1054
0
  for (ref = remote_refs; ref; ref = ref->next) {
1055
0
    if (!ref->peer_ref && !mirror)
1056
0
      continue;
1057
1058
    /* Check for statuses set by set_ref_status_for_push() */
1059
0
    switch (ref->status) {
1060
0
    case REF_STATUS_REJECT_NONFASTFORWARD:
1061
0
    case REF_STATUS_REJECT_STALE:
1062
0
    case REF_STATUS_REJECT_ALREADY_EXISTS:
1063
0
    case REF_STATUS_REJECT_REMOTE_UPDATED:
1064
0
      if (atomic) {
1065
0
        reject_atomic_push(remote_refs, mirror);
1066
0
        string_list_clear(&cas_options, 0);
1067
0
        strbuf_release(&buf);
1068
0
        return 0;
1069
0
      } else
1070
0
        continue;
1071
0
    case REF_STATUS_UPTODATE:
1072
0
      continue;
1073
0
    default:
1074
0
      ; /* do nothing */
1075
0
    }
1076
1077
0
    if (force_all)
1078
0
      ref->force = 1;
1079
1080
0
    strbuf_addstr(&buf, "push ");
1081
0
    if (!ref->deletion) {
1082
0
      if (ref->force)
1083
0
        strbuf_addch(&buf, '+');
1084
0
      if (ref->peer_ref)
1085
0
        strbuf_addstr(&buf, ref->peer_ref->name);
1086
0
      else
1087
0
        strbuf_add_oid_hex(&buf, &ref->new_oid);
1088
0
    }
1089
0
    strbuf_addch(&buf, ':');
1090
0
    strbuf_addstr(&buf, ref->name);
1091
0
    strbuf_addch(&buf, '\n');
1092
1093
    /*
1094
     * The "--force-with-lease" options without explicit
1095
     * values to expect have already been expanded into
1096
     * the ref->old_oid_expect[] field; we can ignore
1097
     * transport->smart_options->cas altogether and instead
1098
     * can enumerate them from the refs.
1099
     */
1100
0
    if (ref->expect_old_sha1) {
1101
0
      struct strbuf cas = STRBUF_INIT;
1102
0
      strbuf_addf(&cas, "%s:%s",
1103
0
            ref->name, oid_to_hex(&ref->old_oid_expect));
1104
0
      string_list_append_nodup(&cas_options,
1105
0
             strbuf_detach(&cas, NULL));
1106
0
    }
1107
0
  }
1108
0
  if (buf.len == 0) {
1109
0
    string_list_clear(&cas_options, 0);
1110
0
    return 0;
1111
0
  }
1112
1113
0
  for_each_string_list_item(cas_option, &cas_options)
1114
0
    set_helper_option(transport, "cas", cas_option->string);
1115
0
  set_common_push_options(transport, data->name, flags);
1116
1117
0
  strbuf_addch(&buf, '\n');
1118
0
  sendline(data, &buf);
1119
0
  strbuf_release(&buf);
1120
0
  string_list_clear(&cas_options, 0);
1121
1122
0
  return push_update_refs_status(data, remote_refs, flags);
1123
0
}
1124
1125
static int push_refs_with_export(struct transport *transport,
1126
    struct ref *remote_refs, int flags)
1127
0
{
1128
0
  struct ref *ref;
1129
0
  struct child_process *helper, exporter;
1130
0
  struct helper_data *data = transport->data;
1131
0
  struct string_list revlist_args = STRING_LIST_INIT_DUP;
1132
0
  struct strbuf buf = STRBUF_INIT;
1133
1134
0
  if (!data->rs.nr)
1135
0
    die(_("remote-helper doesn't support push; refspec needed"));
1136
1137
0
  set_common_push_options(transport, data->name, flags);
1138
0
  if (flags & TRANSPORT_PUSH_FORCE) {
1139
0
    if (set_helper_option(transport, "force", "true") != 0)
1140
0
      warning(_("helper %s does not support '--force'"), data->name);
1141
0
  }
1142
1143
0
  helper = get_helper(transport);
1144
1145
0
  write_constant(helper->in, "export\n");
1146
1147
0
  for (ref = remote_refs; ref; ref = ref->next) {
1148
0
    char *private;
1149
0
    struct object_id oid;
1150
1151
0
    private = apply_refspecs(&data->rs, ref->name);
1152
0
    if (private && !repo_get_oid(the_repository, private, &oid)) {
1153
0
      strbuf_addf(&buf, "^%s", private);
1154
0
      string_list_append_nodup(&revlist_args,
1155
0
             strbuf_detach(&buf, NULL));
1156
0
      oidcpy(&ref->old_oid, &oid);
1157
0
    }
1158
0
    free(private);
1159
1160
0
    if (ref->peer_ref) {
1161
0
      if (strcmp(ref->name, ref->peer_ref->name)) {
1162
0
        if (!ref->deletion) {
1163
0
          const char *name;
1164
0
          int flag;
1165
1166
          /* Follow symbolic refs (mainly for HEAD). */
1167
0
          name = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
1168
0
                       ref->peer_ref->name,
1169
0
                       RESOLVE_REF_READING,
1170
0
                       &oid,
1171
0
                       &flag);
1172
0
          if (!name || !(flag & REF_ISSYMREF))
1173
0
            name = ref->peer_ref->name;
1174
1175
0
          strbuf_addf(&buf, "%s:%s", name, ref->name);
1176
0
        } else
1177
0
          strbuf_addf(&buf, ":%s", ref->name);
1178
1179
0
        string_list_append(&revlist_args, "--refspec");
1180
0
        string_list_append(&revlist_args, buf.buf);
1181
0
        strbuf_release(&buf);
1182
0
      }
1183
0
      if (!ref->deletion)
1184
0
        string_list_append(&revlist_args, ref->peer_ref->name);
1185
0
    }
1186
0
  }
1187
1188
0
  if (get_exporter(transport, &exporter, &revlist_args))
1189
0
    die(_("couldn't run fast-export"));
1190
1191
0
  string_list_clear(&revlist_args, 1);
1192
1193
0
  if (finish_command(&exporter))
1194
0
    die(_("error while running fast-export"));
1195
0
  if (push_update_refs_status(data, remote_refs, flags))
1196
0
    return 1;
1197
1198
0
  if (data->export_marks) {
1199
0
    strbuf_addf(&buf, "%s.tmp", data->export_marks);
1200
0
    if (rename(buf.buf, data->export_marks))
1201
0
      warning_errno(_("could not rename '%s' to '%s'"),
1202
0
              buf.buf, data->export_marks);
1203
0
    strbuf_release(&buf);
1204
0
  }
1205
1206
0
  return 0;
1207
0
}
1208
1209
static int push_refs(struct transport *transport,
1210
    struct ref *remote_refs, int flags)
1211
0
{
1212
0
  struct helper_data *data = transport->data;
1213
1214
0
  if (process_connect(transport, 1))
1215
0
    return transport->vtable->push_refs(transport, remote_refs, flags);
1216
1217
0
  if (!remote_refs) {
1218
0
    fprintf(stderr,
1219
0
      _("No refs in common and none specified; doing nothing.\n"
1220
0
        "Perhaps you should specify a branch.\n"));
1221
0
    return 0;
1222
0
  }
1223
1224
0
  if (data->push)
1225
0
    return push_refs_with_push(transport, remote_refs, flags);
1226
1227
0
  if (data->export)
1228
0
    return push_refs_with_export(transport, remote_refs, flags);
1229
1230
0
  return -1;
1231
0
}
1232
1233
1234
static int has_attribute(const char *attrs, const char *attr)
1235
0
{
1236
0
  int len;
1237
0
  if (!attrs)
1238
0
    return 0;
1239
1240
0
  len = strlen(attr);
1241
0
  for (;;) {
1242
0
    const char *space = strchrnul(attrs, ' ');
1243
0
    if (len == space - attrs && !strncmp(attrs, attr, len))
1244
0
      return 1;
1245
0
    if (!*space)
1246
0
      return 0;
1247
0
    attrs = space + 1;
1248
0
  }
1249
0
}
1250
1251
static struct ref *get_refs_list(struct transport *transport, int for_push,
1252
         struct transport_ls_refs_options *transport_options)
1253
0
{
1254
0
  get_helper(transport);
1255
1256
0
  if (process_connect(transport, for_push))
1257
0
    return transport->vtable->get_refs_list(transport, for_push,
1258
0
              transport_options);
1259
1260
0
  return get_refs_list_using_list(transport, for_push);
1261
0
}
1262
1263
static struct ref *get_refs_list_using_list(struct transport *transport,
1264
              int for_push)
1265
0
{
1266
0
  struct helper_data *data = transport->data;
1267
0
  struct child_process *helper;
1268
0
  struct ref *ret = NULL;
1269
0
  struct ref **tail = &ret;
1270
0
  struct ref *posn;
1271
0
  struct strbuf buf = STRBUF_INIT;
1272
1273
0
  data->get_refs_list_called = 1;
1274
0
  helper = get_helper(transport);
1275
1276
0
  if (data->object_format)
1277
0
    set_helper_option(transport, "object-format", "true");
1278
1279
0
  if (data->push && for_push)
1280
0
    write_constant(helper->in, "list for-push\n");
1281
0
  else
1282
0
    write_constant(helper->in, "list\n");
1283
1284
0
  while (1) {
1285
0
    char *eov, *eon;
1286
0
    if (recvline(data, &buf))
1287
0
      exit(128);
1288
1289
0
    if (!*buf.buf)
1290
0
      break;
1291
0
    else if (buf.buf[0] == ':') {
1292
0
      const char *value;
1293
0
      if (skip_prefix(buf.buf, ":object-format ", &value)) {
1294
0
        int algo = hash_algo_by_name(value);
1295
0
        if (algo == GIT_HASH_UNKNOWN)
1296
0
          die(_("unsupported object format '%s'"),
1297
0
              value);
1298
0
        transport->hash_algo = &hash_algos[algo];
1299
0
      }
1300
0
      continue;
1301
0
    }
1302
1303
0
    eov = strchr(buf.buf, ' ');
1304
0
    if (!eov)
1305
0
      die(_("malformed response in ref list: %s"), buf.buf);
1306
0
    eon = strchr(eov + 1, ' ');
1307
0
    *eov = '\0';
1308
0
    if (eon)
1309
0
      *eon = '\0';
1310
0
    *tail = alloc_ref(eov + 1);
1311
0
    if (buf.buf[0] == '@')
1312
0
      (*tail)->symref = xstrdup(buf.buf + 1);
1313
0
    else if (buf.buf[0] != '?')
1314
0
      get_oid_hex_algop(buf.buf, &(*tail)->old_oid, transport->hash_algo);
1315
0
    if (eon) {
1316
0
      if (has_attribute(eon + 1, "unchanged")) {
1317
0
        (*tail)->status |= REF_STATUS_UPTODATE;
1318
0
        if (refs_read_ref(get_main_ref_store(the_repository), (*tail)->name, &(*tail)->old_oid) < 0)
1319
0
          die(_("could not read ref %s"),
1320
0
              (*tail)->name);
1321
0
      }
1322
0
    }
1323
0
    tail = &((*tail)->next);
1324
0
  }
1325
0
  if (debug)
1326
0
    fprintf(stderr, "Debug: Read ref listing.\n");
1327
0
  strbuf_release(&buf);
1328
1329
0
  for (posn = ret; posn; posn = posn->next)
1330
0
    resolve_remote_symref(posn, ret);
1331
1332
0
  return ret;
1333
0
}
1334
1335
static int get_bundle_uri(struct transport *transport)
1336
0
{
1337
0
  get_helper(transport);
1338
1339
0
  if (process_connect(transport, 0))
1340
0
    return transport->vtable->get_bundle_uri(transport);
1341
1342
0
  return -1;
1343
0
}
1344
1345
static struct transport_vtable vtable = {
1346
  .set_option = set_helper_option,
1347
  .get_refs_list  = get_refs_list,
1348
  .get_bundle_uri = get_bundle_uri,
1349
  .fetch_refs = fetch_refs,
1350
  .fetch_object_info = fetch_object_info_helper,
1351
  .push_refs  = push_refs,
1352
  .connect  = connect_helper,
1353
  .disconnect = release_helper
1354
};
1355
1356
int transport_helper_init(struct transport *transport, const char *name)
1357
0
{
1358
0
  struct helper_data *data = xcalloc(1, sizeof(*data));
1359
0
  data->name = xstrdup(name);
1360
1361
0
  transport_check_allowed(name);
1362
1363
0
  if (getenv("GIT_TRANSPORT_HELPER_DEBUG"))
1364
0
    debug = 1;
1365
1366
0
  list_objects_filter_init(&data->transport_options.filter_options);
1367
1368
0
  transport->data = data;
1369
0
  transport->vtable = &vtable;
1370
0
  transport->smart_options = &(data->transport_options);
1371
0
  return 0;
1372
0
}
1373
1374
/*
1375
 * Linux pipes can buffer 65536 bytes at once (and most platforms can
1376
 * buffer less), so attempt reads and writes with up to that size.
1377
 */
1378
0
#define BUFFERSIZE 65536
1379
/* This should be enough to hold debugging message. */
1380
0
#define PBUFFERSIZE 8192
1381
1382
static int transfer_debug_enabled = -1;
1383
1384
/* Print bidirectional transfer loop debug message. */
1385
__attribute__((format (printf, 1, 2)))
1386
static void transfer_debug(const char *fmt, ...)
1387
0
{
1388
0
  va_list args;
1389
0
  char msgbuf[PBUFFERSIZE];
1390
1391
0
  if (transfer_debug_enabled < 0)
1392
0
    BUG("somebody forgot to check GIT_TRANSLOOP_DEBUG!");
1393
0
  if (!transfer_debug_enabled)
1394
0
    return;
1395
1396
0
  va_start(args, fmt);
1397
0
  vsnprintf(msgbuf, PBUFFERSIZE, fmt, args);
1398
0
  va_end(args);
1399
0
  fprintf(stderr, "Transfer loop debugging: %s\n", msgbuf);
1400
0
}
1401
1402
/* Stream state: More data may be coming in this direction. */
1403
0
#define SSTATE_TRANSFERRING 0
1404
/*
1405
 * Stream state: No more data coming in this direction, flushing rest of
1406
 * data.
1407
 */
1408
0
#define SSTATE_FLUSHING 1
1409
/* Stream state: Transfer in this direction finished. */
1410
0
#define SSTATE_FINISHED 2
1411
1412
0
#define STATE_NEEDS_READING(state) ((state) <= SSTATE_TRANSFERRING)
1413
0
#define STATE_NEEDS_WRITING(state) ((state) <= SSTATE_FLUSHING)
1414
0
#define STATE_NEEDS_CLOSING(state) ((state) == SSTATE_FLUSHING)
1415
1416
/* Unidirectional transfer. */
1417
struct unidirectional_transfer {
1418
  /* Source */
1419
  int src;
1420
  /* Destination */
1421
  int dest;
1422
  /* Is source socket? */
1423
  int src_is_sock;
1424
  /* Is destination socket? */
1425
  int dest_is_sock;
1426
  /* Transfer state (TRANSFERRING/FLUSHING/FINISHED) */
1427
  int state;
1428
  /* Buffer. */
1429
  char buf[BUFFERSIZE];
1430
  /* Buffer used. */
1431
  size_t bufuse;
1432
  /* Name of source. */
1433
  const char *src_name;
1434
  /* Name of destination. */
1435
  const char *dest_name;
1436
};
1437
1438
/* Closes the target (for writing) if transfer has finished. */
1439
static void udt_close_if_finished(struct unidirectional_transfer *t)
1440
0
{
1441
0
  if (STATE_NEEDS_CLOSING(t->state) && !t->bufuse) {
1442
0
    t->state = SSTATE_FINISHED;
1443
0
    if (t->dest_is_sock)
1444
0
      shutdown(t->dest, SHUT_WR);
1445
0
    else
1446
0
      close(t->dest);
1447
0
    transfer_debug("Closed %s.", t->dest_name);
1448
0
  }
1449
0
}
1450
1451
/*
1452
 * Tries to read data from source into buffer. If buffer is full,
1453
 * no data is read. Returns 0 on success, -1 on error.
1454
 */
1455
static int udt_do_read(struct unidirectional_transfer *t)
1456
0
{
1457
0
  ssize_t bytes;
1458
1459
0
  if (t->bufuse == BUFFERSIZE)
1460
0
    return 0; /* No space for more. */
1461
1462
0
  transfer_debug("%s is readable", t->src_name);
1463
0
  bytes = xread(t->src, t->buf + t->bufuse, BUFFERSIZE - t->bufuse);
1464
0
  if (bytes < 0) {
1465
0
    error_errno(_("read(%s) failed"), t->src_name);
1466
0
    return -1;
1467
0
  } else if (bytes == 0) {
1468
0
    transfer_debug("%s EOF (with %i bytes in buffer)",
1469
0
      t->src_name, (int)t->bufuse);
1470
0
    t->state = SSTATE_FLUSHING;
1471
0
  } else {
1472
0
    t->bufuse += bytes;
1473
0
    transfer_debug("Read %i bytes from %s (buffer now at %i)",
1474
0
      (int)bytes, t->src_name, (int)t->bufuse);
1475
0
  }
1476
0
  return 0;
1477
0
}
1478
1479
/* Tries to write data from buffer into destination. If buffer is empty,
1480
 * no data is written. Returns 0 on success, -1 on error.
1481
 */
1482
static int udt_do_write(struct unidirectional_transfer *t)
1483
0
{
1484
0
  ssize_t bytes;
1485
1486
0
  if (t->bufuse == 0)
1487
0
    return 0; /* Nothing to write. */
1488
1489
0
  transfer_debug("%s is writable", t->dest_name);
1490
0
  bytes = xwrite(t->dest, t->buf, t->bufuse);
1491
0
  if (bytes < 0) {
1492
0
    error_errno(_("write(%s) failed"), t->dest_name);
1493
0
    return -1;
1494
0
  } else if (bytes > 0) {
1495
0
    t->bufuse -= bytes;
1496
0
    if (t->bufuse)
1497
0
      memmove(t->buf, t->buf + bytes, t->bufuse);
1498
0
    transfer_debug("Wrote %i bytes to %s (buffer now at %i)",
1499
0
      (int)bytes, t->dest_name, (int)t->bufuse);
1500
0
  }
1501
0
  return 0;
1502
0
}
1503
1504
1505
/* State of bidirectional transfer loop. */
1506
struct bidirectional_transfer_state {
1507
  /* Direction from program to git. */
1508
  struct unidirectional_transfer ptg;
1509
  /* Direction from git to program. */
1510
  struct unidirectional_transfer gtp;
1511
};
1512
1513
static void *udt_copy_task_routine(void *udt)
1514
0
{
1515
0
  struct unidirectional_transfer *t = (struct unidirectional_transfer *)udt;
1516
0
  while (t->state != SSTATE_FINISHED) {
1517
0
    if (STATE_NEEDS_READING(t->state))
1518
0
      if (udt_do_read(t))
1519
0
        return NULL;
1520
0
    if (STATE_NEEDS_WRITING(t->state))
1521
0
      if (udt_do_write(t))
1522
0
        return NULL;
1523
0
    if (STATE_NEEDS_CLOSING(t->state))
1524
0
      udt_close_if_finished(t);
1525
0
  }
1526
0
  return udt; /* Just some non-NULL value. */
1527
0
}
1528
1529
#ifndef NO_PTHREADS
1530
1531
/*
1532
 * Join thread, with appropriate errors on failure. Name is name for the
1533
 * thread (for error messages). Returns 0 on success, 1 on failure.
1534
 */
1535
static int tloop_join(pthread_t thread, const char *name)
1536
0
{
1537
0
  int err;
1538
0
  void *tret;
1539
0
  err = pthread_join(thread, &tret);
1540
0
  if (!tret) {
1541
0
    error(_("%s thread failed"), name);
1542
0
    return 1;
1543
0
  }
1544
0
  if (err) {
1545
0
    error(_("%s thread failed to join: %s"), name, strerror(err));
1546
0
    return 1;
1547
0
  }
1548
0
  return 0;
1549
0
}
1550
1551
/*
1552
 * Spawn the transfer tasks and then wait for them. Returns 0 on success,
1553
 * -1 on failure.
1554
 */
1555
static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s)
1556
0
{
1557
0
  pthread_t gtp_thread;
1558
0
  pthread_t ptg_thread;
1559
0
  int err;
1560
0
  int ret = 0;
1561
0
  err = pthread_create(&gtp_thread, NULL, udt_copy_task_routine,
1562
0
    &s->gtp);
1563
0
  if (err)
1564
0
    die(_("can't start thread for copying data: %s"), strerror(err));
1565
0
  err = pthread_create(&ptg_thread, NULL, udt_copy_task_routine,
1566
0
    &s->ptg);
1567
0
  if (err)
1568
0
    die(_("can't start thread for copying data: %s"), strerror(err));
1569
1570
0
  ret |= tloop_join(gtp_thread, "Git to program copy");
1571
0
  ret |= tloop_join(ptg_thread, "Program to git copy");
1572
0
  return ret;
1573
0
}
1574
#else
1575
1576
/* Close the source and target (for writing) for transfer. */
1577
static void udt_kill_transfer(struct unidirectional_transfer *t)
1578
{
1579
  t->state = SSTATE_FINISHED;
1580
  /*
1581
   * Socket read end left open isn't a disaster if nobody
1582
   * attempts to read from it (mingw compat headers do not
1583
   * have SHUT_RD)...
1584
   *
1585
   * We can't fully close the socket since otherwise gtp
1586
   * task would first close the socket it sends data to
1587
   * while closing the ptg file descriptors.
1588
   */
1589
  if (!t->src_is_sock)
1590
    close(t->src);
1591
  if (t->dest_is_sock)
1592
    shutdown(t->dest, SHUT_WR);
1593
  else
1594
    close(t->dest);
1595
}
1596
1597
/*
1598
 * Join process, with appropriate errors on failure. Name is name for the
1599
 * process (for error messages). Returns 0 on success, 1 on failure.
1600
 */
1601
static int tloop_join(pid_t pid, const char *name)
1602
{
1603
  int tret;
1604
  if (waitpid(pid, &tret, 0) < 0) {
1605
    error_errno(_("%s process failed to wait"), name);
1606
    return 1;
1607
  }
1608
  if (!WIFEXITED(tret) || WEXITSTATUS(tret)) {
1609
    error(_("%s process failed"), name);
1610
    return 1;
1611
  }
1612
  return 0;
1613
}
1614
1615
/*
1616
 * Spawn the transfer tasks and then wait for them. Returns 0 on success,
1617
 * -1 on failure.
1618
 */
1619
static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s)
1620
{
1621
  pid_t pid1, pid2;
1622
  int ret = 0;
1623
1624
  /* Fork thread #1: git to program. */
1625
  pid1 = fork();
1626
  if (pid1 < 0)
1627
    die_errno(_("can't start thread for copying data"));
1628
  else if (pid1 == 0) {
1629
    udt_kill_transfer(&s->ptg);
1630
    exit(udt_copy_task_routine(&s->gtp) ? 0 : 1);
1631
  }
1632
1633
  /* Fork thread #2: program to git. */
1634
  pid2 = fork();
1635
  if (pid2 < 0)
1636
    die_errno(_("can't start thread for copying data"));
1637
  else if (pid2 == 0) {
1638
    udt_kill_transfer(&s->gtp);
1639
    exit(udt_copy_task_routine(&s->ptg) ? 0 : 1);
1640
  }
1641
1642
  /*
1643
   * Close both streams in parent as to not interfere with
1644
   * end of file detection and wait for both tasks to finish.
1645
   */
1646
  udt_kill_transfer(&s->gtp);
1647
  udt_kill_transfer(&s->ptg);
1648
  ret |= tloop_join(pid1, "Git to program copy");
1649
  ret |= tloop_join(pid2, "Program to git copy");
1650
  return ret;
1651
}
1652
#endif
1653
1654
/*
1655
 * Copies data from stdin to output and from input to stdout simultaneously.
1656
 * Additionally filtering through given filter. If filter is NULL, uses
1657
 * identity filter.
1658
 */
1659
int bidirectional_transfer_loop(int input, int output)
1660
0
{
1661
0
  struct bidirectional_transfer_state state;
1662
1663
0
  if (transfer_debug_enabled < 0)
1664
0
    transfer_debug_enabled = getenv("GIT_TRANSLOOP_DEBUG") ? 1 : 0;
1665
1666
  /* Fill the state fields. */
1667
0
  state.ptg.src = input;
1668
0
  state.ptg.dest = 1;
1669
0
  state.ptg.src_is_sock = (input == output);
1670
0
  state.ptg.dest_is_sock = 0;
1671
0
  state.ptg.state = SSTATE_TRANSFERRING;
1672
0
  state.ptg.bufuse = 0;
1673
0
  state.ptg.src_name = "remote input";
1674
0
  state.ptg.dest_name = "stdout";
1675
1676
0
  state.gtp.src = 0;
1677
0
  state.gtp.dest = output;
1678
0
  state.gtp.src_is_sock = 0;
1679
0
  state.gtp.dest_is_sock = (input == output);
1680
0
  state.gtp.state = SSTATE_TRANSFERRING;
1681
0
  state.gtp.bufuse = 0;
1682
0
  state.gtp.src_name = "stdin";
1683
0
  state.gtp.dest_name = "remote output";
1684
1685
0
  return tloop_spawnwait_tasks(&state);
1686
0
}
1687
1688
void reject_atomic_push(struct ref *remote_refs, int mirror_mode)
1689
0
{
1690
0
  struct ref *ref;
1691
1692
  /* Mark other refs as failed */
1693
0
  for (ref = remote_refs; ref; ref = ref->next) {
1694
0
    if (!ref->peer_ref && !mirror_mode)
1695
0
      continue;
1696
1697
0
    switch (ref->status) {
1698
0
    case REF_STATUS_NONE:
1699
0
    case REF_STATUS_OK:
1700
0
    case REF_STATUS_EXPECTING_REPORT:
1701
0
      ref->status = REF_STATUS_ATOMIC_PUSH_FAILED;
1702
0
      continue;
1703
0
    default:
1704
0
      break; /* do nothing */
1705
0
    }
1706
0
  }
1707
0
  return;
1708
0
}