Coverage Report

Created: 2025-12-31 07:01

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);
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->name);
270
0
    FREE_AND_NULL(data->helper);
271
0
  }
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
  res = disconnect_helper(transport);
405
0
  free(transport->data);
406
0
  return res;
407
0
}
408
409
static int fetch_with_fetch(struct transport *transport,
410
          int nr_heads, struct ref **to_fetch)
411
0
{
412
0
  struct helper_data *data = transport->data;
413
0
  int i;
414
0
  struct strbuf buf = STRBUF_INIT;
415
416
0
  for (i = 0; i < nr_heads; i++) {
417
0
    const struct ref *posn = to_fetch[i];
418
0
    if (posn->status & REF_STATUS_UPTODATE)
419
0
      continue;
420
421
0
    strbuf_addf(&buf, "fetch %s %s\n",
422
0
          oid_to_hex(&posn->old_oid),
423
0
          posn->symref ? posn->symref : posn->name);
424
0
  }
425
426
0
  strbuf_addch(&buf, '\n');
427
0
  sendline(data, &buf);
428
429
0
  while (1) {
430
0
    const char *name;
431
432
0
    if (recvline(data, &buf))
433
0
      exit(128);
434
435
0
    if (skip_prefix(buf.buf, "lock ", &name)) {
436
0
      if (transport->pack_lockfiles.nr)
437
0
        warning(_("%s also locked %s"), data->name, name);
438
0
      else
439
0
        string_list_append(&transport->pack_lockfiles,
440
0
               name);
441
0
    }
442
0
    else if (data->check_connectivity &&
443
0
       data->transport_options.check_self_contained_and_connected &&
444
0
       !strcmp(buf.buf, "connectivity-ok"))
445
0
      data->transport_options.self_contained_and_connected = 1;
446
0
    else if (!buf.len)
447
0
      break;
448
0
    else
449
0
      warning(_("%s unexpectedly said: '%s'"), data->name, buf.buf);
450
0
  }
451
0
  strbuf_release(&buf);
452
453
0
  odb_reprepare(the_repository->objects);
454
0
  return 0;
455
0
}
456
457
static int get_importer(struct transport *transport, struct child_process *fastimport)
458
0
{
459
0
  struct child_process *helper = get_helper(transport);
460
0
  struct helper_data *data = transport->data;
461
0
  int cat_blob_fd, code;
462
0
  child_process_init(fastimport);
463
0
  fastimport->in = xdup(helper->out);
464
0
  strvec_push(&fastimport->args, "fast-import");
465
0
  strvec_push(&fastimport->args, "--allow-unsafe-features");
466
0
  strvec_push(&fastimport->args, debug ? "--stats" : "--quiet");
467
468
0
  if (data->bidi_import) {
469
0
    cat_blob_fd = xdup(helper->in);
470
0
    strvec_pushf(&fastimport->args, "--cat-blob-fd=%d", cat_blob_fd);
471
0
  }
472
0
  fastimport->git_cmd = 1;
473
474
0
  code = start_command(fastimport);
475
0
  return code;
476
0
}
477
478
static int get_exporter(struct transport *transport,
479
      struct child_process *fastexport,
480
      struct string_list *revlist_args)
481
0
{
482
0
  struct helper_data *data = transport->data;
483
0
  struct child_process *helper = get_helper(transport);
484
485
0
  child_process_init(fastexport);
486
487
  /* we need to duplicate helper->in because we want to use it after
488
   * fastexport is done with it. */
489
0
  fastexport->out = dup(helper->in);
490
0
  strvec_push(&fastexport->args, "fast-export");
491
0
  strvec_push(&fastexport->args, "--use-done-feature");
492
0
  strvec_push(&fastexport->args, data->signed_tags ?
493
0
    "--signed-tags=verbatim" : "--signed-tags=warn-strip");
494
0
  if (data->export_marks)
495
0
    strvec_pushf(&fastexport->args, "--export-marks=%s.tmp", data->export_marks);
496
0
  if (data->import_marks)
497
0
    strvec_pushf(&fastexport->args, "--import-marks=%s", data->import_marks);
498
499
0
  for (size_t i = 0; i < revlist_args->nr; i++)
500
0
    strvec_push(&fastexport->args, revlist_args->items[i].string);
501
502
0
  fastexport->git_cmd = 1;
503
0
  return start_command(fastexport);
504
0
}
505
506
static int fetch_with_import(struct transport *transport,
507
           int nr_heads, struct ref **to_fetch)
508
0
{
509
0
  struct child_process fastimport;
510
0
  struct helper_data *data = transport->data;
511
0
  int i;
512
0
  struct ref *posn;
513
0
  struct strbuf buf = STRBUF_INIT;
514
515
0
  get_helper(transport);
516
517
0
  if (get_importer(transport, &fastimport))
518
0
    die(_("couldn't run fast-import"));
519
520
0
  for (i = 0; i < nr_heads; i++) {
521
0
    posn = to_fetch[i];
522
0
    if (posn->status & REF_STATUS_UPTODATE)
523
0
      continue;
524
525
0
    strbuf_addf(&buf, "import %s\n",
526
0
          posn->symref ? posn->symref : posn->name);
527
0
    sendline(data, &buf);
528
0
    strbuf_reset(&buf);
529
0
  }
530
531
0
  write_constant(data->helper->in, "\n");
532
  /*
533
   * remote-helpers that advertise the bidi-import capability are required to
534
   * buffer the complete batch of import commands until this newline before
535
   * sending data to fast-import.
536
   * These helpers read back data from fast-import on their stdin, which could
537
   * be mixed with import commands, otherwise.
538
   */
539
540
0
  if (finish_command(&fastimport))
541
0
    die(_("error while running fast-import"));
542
543
  /*
544
   * The fast-import stream of a remote helper that advertises
545
   * the "refspec" capability writes to the refs named after the
546
   * right hand side of the first refspec matching each ref we
547
   * were fetching.
548
   *
549
   * (If no "refspec" capability was specified, for historical
550
   * reasons we default to the equivalent of *:*.)
551
   *
552
   * Store the result in to_fetch[i].old_sha1.  Callers such
553
   * as "git fetch" can use the value to write feedback to the
554
   * terminal, populate FETCH_HEAD, and determine what new value
555
   * should be written to peer_ref if the update is a
556
   * fast-forward or this is a forced update.
557
   */
558
0
  for (i = 0; i < nr_heads; i++) {
559
0
    char *private, *name;
560
0
    posn = to_fetch[i];
561
0
    if (posn->status & REF_STATUS_UPTODATE)
562
0
      continue;
563
0
    name = posn->symref ? posn->symref : posn->name;
564
0
    if (data->rs.nr)
565
0
      private = apply_refspecs(&data->rs, name);
566
0
    else
567
0
      private = xstrdup(name);
568
0
    if (private) {
569
0
      if (refs_read_ref(get_main_ref_store(the_repository), private, &posn->old_oid) < 0)
570
0
        die(_("could not read ref %s"), private);
571
0
      free(private);
572
0
    }
573
0
  }
574
0
  strbuf_release(&buf);
575
0
  return 0;
576
0
}
577
578
static int run_connect(struct transport *transport, struct strbuf *cmdbuf)
579
0
{
580
0
  struct helper_data *data = transport->data;
581
0
  int ret = 0;
582
0
  int duped;
583
0
  FILE *input;
584
0
  struct child_process *helper;
585
586
0
  helper = get_helper(transport);
587
588
  /*
589
   * Yes, dup the pipe another time, as we need unbuffered version
590
   * of input pipe as FILE*. fclose() closes the underlying fd and
591
   * stream buffering only can be changed before first I/O operation
592
   * on it.
593
   */
594
0
  duped = dup(helper->out);
595
0
  if (duped < 0)
596
0
    die_errno(_("can't dup helper output fd"));
597
0
  input = xfdopen(duped, "r");
598
0
  setvbuf(input, NULL, _IONBF, 0);
599
600
0
  sendline(data, cmdbuf);
601
0
  if (recvline_fh(input, cmdbuf))
602
0
    exit(128);
603
604
0
  if (!strcmp(cmdbuf->buf, "")) {
605
0
    data->no_disconnect_req = 1;
606
0
    if (debug)
607
0
      fprintf(stderr, "Debug: Smart transport connection "
608
0
        "ready.\n");
609
0
    ret = 1;
610
0
  } else if (!strcmp(cmdbuf->buf, "fallback")) {
611
0
    if (debug)
612
0
      fprintf(stderr, "Debug: Falling back to dumb "
613
0
        "transport.\n");
614
0
  } else {
615
0
    die(_("unknown response to connect: %s"),
616
0
        cmdbuf->buf);
617
0
  }
618
619
0
  fclose(input);
620
0
  return ret;
621
0
}
622
623
static int process_connect_service(struct transport *transport,
624
           const char *name, const char *exec)
625
0
{
626
0
  struct helper_data *data = transport->data;
627
0
  struct strbuf cmdbuf = STRBUF_INIT;
628
0
  int ret = 0;
629
630
  /*
631
   * Handle --upload-pack and friends. This is fire and forget...
632
   * just warn if it fails.
633
   */
634
0
  if (strcmp(name, exec)) {
635
0
    int r = set_helper_option(transport, "servpath", exec);
636
0
    if (r > 0)
637
0
      warning(_("setting remote service path not supported by protocol"));
638
0
    else if (r < 0)
639
0
      warning(_("invalid remote service path"));
640
0
  }
641
642
0
  if (data->connect) {
643
0
    strbuf_addf(&cmdbuf, "connect %s\n", name);
644
0
    ret = run_connect(transport, &cmdbuf);
645
0
  } else if (data->stateless_connect &&
646
0
       (get_protocol_version_config() == protocol_v2) &&
647
0
       (!strcmp("git-upload-pack", name) ||
648
0
        !strcmp("git-upload-archive", name))) {
649
0
    strbuf_addf(&cmdbuf, "stateless-connect %s\n", name);
650
0
    ret = run_connect(transport, &cmdbuf);
651
0
    if (ret)
652
0
      transport->stateless_rpc = 1;
653
0
  }
654
655
0
  strbuf_release(&cmdbuf);
656
0
  return ret;
657
0
}
658
659
static int process_connect(struct transport *transport,
660
             int for_push)
661
0
{
662
0
  struct helper_data *data = transport->data;
663
0
  const char *name;
664
0
  const char *exec;
665
0
  int ret;
666
667
0
  name = for_push ? "git-receive-pack" : "git-upload-pack";
668
0
  if (for_push)
669
0
    exec = data->transport_options.receivepack;
670
0
  else
671
0
    exec = data->transport_options.uploadpack;
672
673
0
  ret = process_connect_service(transport, name, exec);
674
0
  if (ret)
675
0
    do_take_over(transport);
676
0
  return ret;
677
0
}
678
679
static int connect_helper(struct transport *transport, const char *name,
680
       const char *exec, int fd[2])
681
0
{
682
0
  struct helper_data *data = transport->data;
683
684
  /* Get_helper so connect is inited. */
685
0
  get_helper(transport);
686
687
0
  if (!process_connect_service(transport, name, exec))
688
0
    die(_("can't connect to subservice %s"), name);
689
690
0
  fd[0] = data->helper->out;
691
0
  fd[1] = data->helper->in;
692
693
0
  do_take_over(transport);
694
0
  return 0;
695
0
}
696
697
static struct ref *get_refs_list_using_list(struct transport *transport,
698
              int for_push);
699
700
static int fetch_refs(struct transport *transport,
701
          int nr_heads, struct ref **to_fetch)
702
0
{
703
0
  struct helper_data *data = transport->data;
704
0
  int i, count;
705
706
0
  get_helper(transport);
707
708
0
  if (process_connect(transport, 0))
709
0
    return transport->vtable->fetch_refs(transport, nr_heads, to_fetch);
710
711
  /*
712
   * If we reach here, then the server, the client, and/or the transport
713
   * helper does not support protocol v2. --negotiate-only requires
714
   * protocol v2.
715
   */
716
0
  if (data->transport_options.acked_commits) {
717
0
    warning(_("--negotiate-only requires protocol v2"));
718
0
    return -1;
719
0
  }
720
721
0
  if (!data->get_refs_list_called) {
722
    /*
723
     * We do not care about the list of refs returned, but only
724
     * that the "list" command was sent.
725
     */
726
0
    struct ref *dummy = get_refs_list_using_list(transport, 0);
727
0
    free_refs(dummy);
728
0
  }
729
730
0
  count = 0;
731
0
  for (i = 0; i < nr_heads; i++)
732
0
    if (!(to_fetch[i]->status & REF_STATUS_UPTODATE))
733
0
      count++;
734
735
0
  if (!count)
736
0
    return 0;
737
738
0
  if (data->check_connectivity &&
739
0
      data->transport_options.check_self_contained_and_connected)
740
0
    set_helper_option(transport, "check-connectivity", "true");
741
742
0
  if (transport->cloning)
743
0
    set_helper_option(transport, "cloning", "true");
744
745
0
  if (data->transport_options.update_shallow)
746
0
    set_helper_option(transport, "update-shallow", "true");
747
748
0
  if (data->transport_options.refetch)
749
0
    set_helper_option(transport, "refetch", "true");
750
751
0
  if (data->transport_options.filter_options.choice) {
752
0
    const char *spec = expand_list_objects_filter_spec(
753
0
      &data->transport_options.filter_options);
754
0
    set_helper_option(transport, "filter", spec);
755
0
  }
756
757
0
  if (data->transport_options.negotiation_tips)
758
0
    warning("Ignoring --negotiation-tip because the protocol does not support it.");
759
760
0
  if (data->fetch)
761
0
    return fetch_with_fetch(transport, nr_heads, to_fetch);
762
763
0
  if (data->import)
764
0
    return fetch_with_import(transport, nr_heads, to_fetch);
765
766
0
  return -1;
767
0
}
768
769
struct push_update_ref_state {
770
  struct ref *hint;
771
  struct ref_push_report *report;
772
  int new_report;
773
};
774
775
static int push_update_ref_status(struct strbuf *buf,
776
           struct push_update_ref_state *state,
777
           struct ref *remote_refs)
778
0
{
779
0
  char *refname, *msg;
780
0
  int status, forced = 0;
781
782
0
  if (starts_with(buf->buf, "option ")) {
783
0
    struct object_id old_oid, new_oid;
784
0
    const char *key, *val;
785
0
    char *p;
786
787
0
    if (!state->hint || !(state->report || state->new_report))
788
0
      die(_("'option' without a matching 'ok/error' directive"));
789
0
    if (state->new_report) {
790
0
      if (!state->hint->report) {
791
0
        CALLOC_ARRAY(state->hint->report, 1);
792
0
        state->report = state->hint->report;
793
0
      } else {
794
0
        state->report = state->hint->report;
795
0
        while (state->report->next)
796
0
          state->report = state->report->next;
797
0
        CALLOC_ARRAY(state->report->next, 1);
798
0
        state->report = state->report->next;
799
0
      }
800
0
      state->new_report = 0;
801
0
    }
802
0
    key = buf->buf + 7;
803
0
    p = strchr(key, ' ');
804
0
    if (p)
805
0
      *p++ = '\0';
806
0
    val = p;
807
0
    if (!strcmp(key, "refname"))
808
0
      state->report->ref_name = xstrdup_or_null(val);
809
0
    else if (!strcmp(key, "old-oid") && val &&
810
0
       !parse_oid_hex(val, &old_oid, &val))
811
0
      state->report->old_oid = oiddup(&old_oid);
812
0
    else if (!strcmp(key, "new-oid") && val &&
813
0
       !parse_oid_hex(val, &new_oid, &val))
814
0
      state->report->new_oid = oiddup(&new_oid);
815
0
    else if (!strcmp(key, "forced-update"))
816
0
      state->report->forced_update = 1;
817
    /* Not update remote namespace again. */
818
0
    return 1;
819
0
  }
820
821
0
  state->report = NULL;
822
0
  state->new_report = 0;
823
824
0
  if (starts_with(buf->buf, "ok ")) {
825
0
    status = REF_STATUS_OK;
826
0
    refname = buf->buf + 3;
827
0
  } else if (starts_with(buf->buf, "error ")) {
828
0
    status = REF_STATUS_REMOTE_REJECT;
829
0
    refname = buf->buf + 6;
830
0
  } else
831
0
    die(_("expected ok/error, helper said '%s'"), buf->buf);
832
833
0
  msg = strchr(refname, ' ');
834
0
  if (msg) {
835
0
    struct strbuf msg_buf = STRBUF_INIT;
836
0
    const char *end;
837
838
0
    *msg++ = '\0';
839
0
    if (!unquote_c_style(&msg_buf, msg, &end))
840
0
      msg = strbuf_detach(&msg_buf, NULL);
841
0
    else
842
0
      msg = xstrdup(msg);
843
0
    strbuf_release(&msg_buf);
844
845
0
    if (!strcmp(msg, "no match")) {
846
0
      status = REF_STATUS_NONE;
847
0
      FREE_AND_NULL(msg);
848
0
    }
849
0
    else if (!strcmp(msg, "up to date")) {
850
0
      status = REF_STATUS_UPTODATE;
851
0
      FREE_AND_NULL(msg);
852
0
    }
853
0
    else if (!strcmp(msg, "non-fast forward")) {
854
0
      status = REF_STATUS_REJECT_NONFASTFORWARD;
855
0
      FREE_AND_NULL(msg);
856
0
    }
857
0
    else if (!strcmp(msg, "already exists")) {
858
0
      status = REF_STATUS_REJECT_ALREADY_EXISTS;
859
0
      FREE_AND_NULL(msg);
860
0
    }
861
0
    else if (!strcmp(msg, "fetch first")) {
862
0
      status = REF_STATUS_REJECT_FETCH_FIRST;
863
0
      FREE_AND_NULL(msg);
864
0
    }
865
0
    else if (!strcmp(msg, "needs force")) {
866
0
      status = REF_STATUS_REJECT_NEEDS_FORCE;
867
0
      FREE_AND_NULL(msg);
868
0
    }
869
0
    else if (!strcmp(msg, "stale info")) {
870
0
      status = REF_STATUS_REJECT_STALE;
871
0
      FREE_AND_NULL(msg);
872
0
    }
873
0
    else if (!strcmp(msg, "remote ref updated since checkout")) {
874
0
      status = REF_STATUS_REJECT_REMOTE_UPDATED;
875
0
      FREE_AND_NULL(msg);
876
0
    }
877
0
    else if (!strcmp(msg, "forced update")) {
878
0
      forced = 1;
879
0
      FREE_AND_NULL(msg);
880
0
    }
881
0
    else if (!strcmp(msg, "expecting report")) {
882
0
      status = REF_STATUS_EXPECTING_REPORT;
883
0
      FREE_AND_NULL(msg);
884
0
    }
885
0
  }
886
887
0
  if (state->hint)
888
0
    state->hint = find_ref_by_name(state->hint, refname);
889
0
  if (!state->hint)
890
0
    state->hint = find_ref_by_name(remote_refs, refname);
891
0
  if (!state->hint) {
892
0
    warning(_("helper reported unexpected status of %s"), refname);
893
0
    return 1;
894
0
  }
895
896
0
  if (state->hint->status != REF_STATUS_NONE) {
897
    /*
898
     * Earlier, the ref was marked not to be pushed, so ignore the ref
899
     * status reported by the remote helper if the latter is 'no match'.
900
     */
901
0
    if (status == REF_STATUS_NONE)
902
0
      return 1;
903
0
  }
904
905
0
  if (status == REF_STATUS_OK)
906
0
    state->new_report = 1;
907
0
  state->hint->status = status;
908
0
  state->hint->forced_update |= forced;
909
0
  state->hint->remote_status = msg;
910
0
  return !(status == REF_STATUS_OK);
911
0
}
912
913
static int push_update_refs_status(struct helper_data *data,
914
            struct ref *remote_refs,
915
            int flags)
916
0
{
917
0
  struct ref *ref;
918
0
  struct ref_push_report *report;
919
0
  struct strbuf buf = STRBUF_INIT;
920
0
  struct push_update_ref_state state = { remote_refs, NULL, 0 };
921
922
0
  for (;;) {
923
0
    if (recvline(data, &buf)) {
924
0
      strbuf_release(&buf);
925
0
      return 1;
926
0
    }
927
0
    if (!buf.len)
928
0
      break;
929
0
    push_update_ref_status(&buf, &state, remote_refs);
930
0
  }
931
0
  strbuf_release(&buf);
932
933
0
  if (flags & TRANSPORT_PUSH_DRY_RUN || !data->rs.nr || data->no_private_update)
934
0
    return 0;
935
936
  /* propagate back the update to the remote namespace */
937
0
  for (ref = remote_refs; ref; ref = ref->next) {
938
0
    char *private;
939
940
0
    if (ref->status != REF_STATUS_OK)
941
0
      continue;
942
943
0
    if (!ref->report) {
944
0
      private = apply_refspecs(&data->rs, ref->name);
945
0
      if (!private)
946
0
        continue;
947
0
      refs_update_ref(get_main_ref_store(the_repository),
948
0
          "update by helper", private,
949
0
          &(ref->new_oid),
950
0
          NULL, 0, 0);
951
0
      free(private);
952
0
    } else {
953
0
      for (report = ref->report; report; report = report->next) {
954
0
        private = apply_refspecs(&data->rs,
955
0
               report->ref_name
956
0
               ? report->ref_name
957
0
               : ref->name);
958
0
        if (!private)
959
0
          continue;
960
0
        refs_update_ref(get_main_ref_store(the_repository),
961
0
            "update by helper", private,
962
0
            report->new_oid
963
0
            ? report->new_oid
964
0
            : &(ref->new_oid),
965
0
            NULL, 0, 0);
966
0
        free(private);
967
0
      }
968
0
    }
969
0
  }
970
0
  return 0;
971
0
}
972
973
static void set_common_push_options(struct transport *transport,
974
           const char *name, int flags)
975
0
{
976
0
  if (flags & TRANSPORT_PUSH_DRY_RUN) {
977
0
    if (set_helper_option(transport, "dry-run", "true") != 0)
978
0
      die(_("helper %s does not support dry-run"), name);
979
0
  } else if (flags & TRANSPORT_PUSH_CERT_ALWAYS) {
980
0
    if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "true") != 0)
981
0
      die(_("helper %s does not support --signed"), name);
982
0
  } else if (flags & TRANSPORT_PUSH_CERT_IF_ASKED) {
983
0
    if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "if-asked") != 0)
984
0
      die(_("helper %s does not support --signed=if-asked"), name);
985
0
  }
986
987
0
  if (flags & TRANSPORT_PUSH_ATOMIC)
988
0
    if (set_helper_option(transport, TRANS_OPT_ATOMIC, "true") != 0)
989
0
      die(_("helper %s does not support --atomic"), name);
990
991
0
  if (flags & TRANSPORT_PUSH_FORCE_IF_INCLUDES)
992
0
    if (set_helper_option(transport, TRANS_OPT_FORCE_IF_INCLUDES, "true") != 0)
993
0
      die(_("helper %s does not support --%s"),
994
0
          name, TRANS_OPT_FORCE_IF_INCLUDES);
995
996
0
  if (flags & TRANSPORT_PUSH_OPTIONS) {
997
0
    struct string_list_item *item;
998
0
    for_each_string_list_item(item, transport->push_options)
999
0
      if (set_helper_option(transport, "push-option", item->string) != 0)
1000
0
        die(_("helper %s does not support 'push-option'"), name);
1001
0
  }
1002
0
}
1003
1004
static int push_refs_with_push(struct transport *transport,
1005
             struct ref *remote_refs, int flags)
1006
0
{
1007
0
  int force_all = flags & TRANSPORT_PUSH_FORCE;
1008
0
  int mirror = flags & TRANSPORT_PUSH_MIRROR;
1009
0
  int atomic = flags & TRANSPORT_PUSH_ATOMIC;
1010
0
  struct helper_data *data = transport->data;
1011
0
  struct strbuf buf = STRBUF_INIT;
1012
0
  struct ref *ref;
1013
0
  struct string_list cas_options = STRING_LIST_INIT_DUP;
1014
0
  struct string_list_item *cas_option;
1015
1016
0
  get_helper(transport);
1017
0
  if (!data->push)
1018
0
    return 1;
1019
1020
0
  for (ref = remote_refs; ref; ref = ref->next) {
1021
0
    if (!ref->peer_ref && !mirror)
1022
0
      continue;
1023
1024
    /* Check for statuses set by set_ref_status_for_push() */
1025
0
    switch (ref->status) {
1026
0
    case REF_STATUS_REJECT_NONFASTFORWARD:
1027
0
    case REF_STATUS_REJECT_STALE:
1028
0
    case REF_STATUS_REJECT_ALREADY_EXISTS:
1029
0
    case REF_STATUS_REJECT_REMOTE_UPDATED:
1030
0
      if (atomic) {
1031
0
        reject_atomic_push(remote_refs, mirror);
1032
0
        string_list_clear(&cas_options, 0);
1033
0
        strbuf_release(&buf);
1034
0
        return 0;
1035
0
      } else
1036
0
        continue;
1037
0
    case REF_STATUS_UPTODATE:
1038
0
      continue;
1039
0
    default:
1040
0
      ; /* do nothing */
1041
0
    }
1042
1043
0
    if (force_all)
1044
0
      ref->force = 1;
1045
1046
0
    strbuf_addstr(&buf, "push ");
1047
0
    if (!ref->deletion) {
1048
0
      if (ref->force)
1049
0
        strbuf_addch(&buf, '+');
1050
0
      if (ref->peer_ref)
1051
0
        strbuf_addstr(&buf, ref->peer_ref->name);
1052
0
      else
1053
0
        strbuf_addstr(&buf, oid_to_hex(&ref->new_oid));
1054
0
    }
1055
0
    strbuf_addch(&buf, ':');
1056
0
    strbuf_addstr(&buf, ref->name);
1057
0
    strbuf_addch(&buf, '\n');
1058
1059
    /*
1060
     * The "--force-with-lease" options without explicit
1061
     * values to expect have already been expanded into
1062
     * the ref->old_oid_expect[] field; we can ignore
1063
     * transport->smart_options->cas altogether and instead
1064
     * can enumerate them from the refs.
1065
     */
1066
0
    if (ref->expect_old_sha1) {
1067
0
      struct strbuf cas = STRBUF_INIT;
1068
0
      strbuf_addf(&cas, "%s:%s",
1069
0
            ref->name, oid_to_hex(&ref->old_oid_expect));
1070
0
      string_list_append_nodup(&cas_options,
1071
0
             strbuf_detach(&cas, NULL));
1072
0
    }
1073
0
  }
1074
0
  if (buf.len == 0) {
1075
0
    string_list_clear(&cas_options, 0);
1076
0
    return 0;
1077
0
  }
1078
1079
0
  for_each_string_list_item(cas_option, &cas_options)
1080
0
    set_helper_option(transport, "cas", cas_option->string);
1081
0
  set_common_push_options(transport, data->name, flags);
1082
1083
0
  strbuf_addch(&buf, '\n');
1084
0
  sendline(data, &buf);
1085
0
  strbuf_release(&buf);
1086
0
  string_list_clear(&cas_options, 0);
1087
1088
0
  return push_update_refs_status(data, remote_refs, flags);
1089
0
}
1090
1091
static int push_refs_with_export(struct transport *transport,
1092
    struct ref *remote_refs, int flags)
1093
0
{
1094
0
  struct ref *ref;
1095
0
  struct child_process *helper, exporter;
1096
0
  struct helper_data *data = transport->data;
1097
0
  struct string_list revlist_args = STRING_LIST_INIT_DUP;
1098
0
  struct strbuf buf = STRBUF_INIT;
1099
1100
0
  if (!data->rs.nr)
1101
0
    die(_("remote-helper doesn't support push; refspec needed"));
1102
1103
0
  set_common_push_options(transport, data->name, flags);
1104
0
  if (flags & TRANSPORT_PUSH_FORCE) {
1105
0
    if (set_helper_option(transport, "force", "true") != 0)
1106
0
      warning(_("helper %s does not support '--force'"), data->name);
1107
0
  }
1108
1109
0
  helper = get_helper(transport);
1110
1111
0
  write_constant(helper->in, "export\n");
1112
1113
0
  for (ref = remote_refs; ref; ref = ref->next) {
1114
0
    char *private;
1115
0
    struct object_id oid;
1116
1117
0
    private = apply_refspecs(&data->rs, ref->name);
1118
0
    if (private && !repo_get_oid(the_repository, private, &oid)) {
1119
0
      strbuf_addf(&buf, "^%s", private);
1120
0
      string_list_append_nodup(&revlist_args,
1121
0
             strbuf_detach(&buf, NULL));
1122
0
      oidcpy(&ref->old_oid, &oid);
1123
0
    }
1124
0
    free(private);
1125
1126
0
    if (ref->peer_ref) {
1127
0
      if (strcmp(ref->name, ref->peer_ref->name)) {
1128
0
        if (!ref->deletion) {
1129
0
          const char *name;
1130
0
          int flag;
1131
1132
          /* Follow symbolic refs (mainly for HEAD). */
1133
0
          name = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
1134
0
                       ref->peer_ref->name,
1135
0
                       RESOLVE_REF_READING,
1136
0
                       &oid,
1137
0
                       &flag);
1138
0
          if (!name || !(flag & REF_ISSYMREF))
1139
0
            name = ref->peer_ref->name;
1140
1141
0
          strbuf_addf(&buf, "%s:%s", name, ref->name);
1142
0
        } else
1143
0
          strbuf_addf(&buf, ":%s", ref->name);
1144
1145
0
        string_list_append(&revlist_args, "--refspec");
1146
0
        string_list_append(&revlist_args, buf.buf);
1147
0
        strbuf_release(&buf);
1148
0
      }
1149
0
      if (!ref->deletion)
1150
0
        string_list_append(&revlist_args, ref->peer_ref->name);
1151
0
    }
1152
0
  }
1153
1154
0
  if (get_exporter(transport, &exporter, &revlist_args))
1155
0
    die(_("couldn't run fast-export"));
1156
1157
0
  string_list_clear(&revlist_args, 1);
1158
1159
0
  if (finish_command(&exporter))
1160
0
    die(_("error while running fast-export"));
1161
0
  if (push_update_refs_status(data, remote_refs, flags))
1162
0
    return 1;
1163
1164
0
  if (data->export_marks) {
1165
0
    strbuf_addf(&buf, "%s.tmp", data->export_marks);
1166
0
    rename(buf.buf, data->export_marks);
1167
0
    strbuf_release(&buf);
1168
0
  }
1169
1170
0
  return 0;
1171
0
}
1172
1173
static int push_refs(struct transport *transport,
1174
    struct ref *remote_refs, int flags)
1175
0
{
1176
0
  struct helper_data *data = transport->data;
1177
1178
0
  if (process_connect(transport, 1))
1179
0
    return transport->vtable->push_refs(transport, remote_refs, flags);
1180
1181
0
  if (!remote_refs) {
1182
0
    fprintf(stderr,
1183
0
      _("No refs in common and none specified; doing nothing.\n"
1184
0
        "Perhaps you should specify a branch.\n"));
1185
0
    return 0;
1186
0
  }
1187
1188
0
  if (data->push)
1189
0
    return push_refs_with_push(transport, remote_refs, flags);
1190
1191
0
  if (data->export)
1192
0
    return push_refs_with_export(transport, remote_refs, flags);
1193
1194
0
  return -1;
1195
0
}
1196
1197
1198
static int has_attribute(const char *attrs, const char *attr)
1199
0
{
1200
0
  int len;
1201
0
  if (!attrs)
1202
0
    return 0;
1203
1204
0
  len = strlen(attr);
1205
0
  for (;;) {
1206
0
    const char *space = strchrnul(attrs, ' ');
1207
0
    if (len == space - attrs && !strncmp(attrs, attr, len))
1208
0
      return 1;
1209
0
    if (!*space)
1210
0
      return 0;
1211
0
    attrs = space + 1;
1212
0
  }
1213
0
}
1214
1215
static struct ref *get_refs_list(struct transport *transport, int for_push,
1216
         struct transport_ls_refs_options *transport_options)
1217
0
{
1218
0
  get_helper(transport);
1219
1220
0
  if (process_connect(transport, for_push))
1221
0
    return transport->vtable->get_refs_list(transport, for_push,
1222
0
              transport_options);
1223
1224
0
  return get_refs_list_using_list(transport, for_push);
1225
0
}
1226
1227
static struct ref *get_refs_list_using_list(struct transport *transport,
1228
              int for_push)
1229
0
{
1230
0
  struct helper_data *data = transport->data;
1231
0
  struct child_process *helper;
1232
0
  struct ref *ret = NULL;
1233
0
  struct ref **tail = &ret;
1234
0
  struct ref *posn;
1235
0
  struct strbuf buf = STRBUF_INIT;
1236
1237
0
  data->get_refs_list_called = 1;
1238
0
  helper = get_helper(transport);
1239
1240
0
  if (data->object_format)
1241
0
    set_helper_option(transport, "object-format", "true");
1242
1243
0
  if (data->push && for_push)
1244
0
    write_constant(helper->in, "list for-push\n");
1245
0
  else
1246
0
    write_constant(helper->in, "list\n");
1247
1248
0
  while (1) {
1249
0
    char *eov, *eon;
1250
0
    if (recvline(data, &buf))
1251
0
      exit(128);
1252
1253
0
    if (!*buf.buf)
1254
0
      break;
1255
0
    else if (buf.buf[0] == ':') {
1256
0
      const char *value;
1257
0
      if (skip_prefix(buf.buf, ":object-format ", &value)) {
1258
0
        int algo = hash_algo_by_name(value);
1259
0
        if (algo == GIT_HASH_UNKNOWN)
1260
0
          die(_("unsupported object format '%s'"),
1261
0
              value);
1262
0
        transport->hash_algo = &hash_algos[algo];
1263
0
      }
1264
0
      continue;
1265
0
    }
1266
1267
0
    eov = strchr(buf.buf, ' ');
1268
0
    if (!eov)
1269
0
      die(_("malformed response in ref list: %s"), buf.buf);
1270
0
    eon = strchr(eov + 1, ' ');
1271
0
    *eov = '\0';
1272
0
    if (eon)
1273
0
      *eon = '\0';
1274
0
    *tail = alloc_ref(eov + 1);
1275
0
    if (buf.buf[0] == '@')
1276
0
      (*tail)->symref = xstrdup(buf.buf + 1);
1277
0
    else if (buf.buf[0] != '?')
1278
0
      get_oid_hex_algop(buf.buf, &(*tail)->old_oid, transport->hash_algo);
1279
0
    if (eon) {
1280
0
      if (has_attribute(eon + 1, "unchanged")) {
1281
0
        (*tail)->status |= REF_STATUS_UPTODATE;
1282
0
        if (refs_read_ref(get_main_ref_store(the_repository), (*tail)->name, &(*tail)->old_oid) < 0)
1283
0
          die(_("could not read ref %s"),
1284
0
              (*tail)->name);
1285
0
      }
1286
0
    }
1287
0
    tail = &((*tail)->next);
1288
0
  }
1289
0
  if (debug)
1290
0
    fprintf(stderr, "Debug: Read ref listing.\n");
1291
0
  strbuf_release(&buf);
1292
1293
0
  for (posn = ret; posn; posn = posn->next)
1294
0
    resolve_remote_symref(posn, ret);
1295
1296
0
  return ret;
1297
0
}
1298
1299
static int get_bundle_uri(struct transport *transport)
1300
0
{
1301
0
  get_helper(transport);
1302
1303
0
  if (process_connect(transport, 0))
1304
0
    return transport->vtable->get_bundle_uri(transport);
1305
1306
0
  return -1;
1307
0
}
1308
1309
static struct transport_vtable vtable = {
1310
  .set_option = set_helper_option,
1311
  .get_refs_list  = get_refs_list,
1312
  .get_bundle_uri = get_bundle_uri,
1313
  .fetch_refs = fetch_refs,
1314
  .push_refs  = push_refs,
1315
  .connect  = connect_helper,
1316
  .disconnect = release_helper
1317
};
1318
1319
int transport_helper_init(struct transport *transport, const char *name)
1320
0
{
1321
0
  struct helper_data *data = xcalloc(1, sizeof(*data));
1322
0
  data->name = xstrdup(name);
1323
1324
0
  transport_check_allowed(name);
1325
1326
0
  if (getenv("GIT_TRANSPORT_HELPER_DEBUG"))
1327
0
    debug = 1;
1328
1329
0
  list_objects_filter_init(&data->transport_options.filter_options);
1330
1331
0
  transport->data = data;
1332
0
  transport->vtable = &vtable;
1333
0
  transport->smart_options = &(data->transport_options);
1334
0
  return 0;
1335
0
}
1336
1337
/*
1338
 * Linux pipes can buffer 65536 bytes at once (and most platforms can
1339
 * buffer less), so attempt reads and writes with up to that size.
1340
 */
1341
0
#define BUFFERSIZE 65536
1342
/* This should be enough to hold debugging message. */
1343
0
#define PBUFFERSIZE 8192
1344
1345
/* Print bidirectional transfer loop debug message. */
1346
__attribute__((format (printf, 1, 2)))
1347
static void transfer_debug(const char *fmt, ...)
1348
0
{
1349
  /*
1350
   * NEEDSWORK: This function is sometimes used from multiple threads, and
1351
   * we end up using debug_enabled racily. That "should not matter" since
1352
   * we always write the same value, but it's still wrong. This function
1353
   * is listed in .tsan-suppressions for the time being.
1354
   */
1355
1356
0
  va_list args;
1357
0
  char msgbuf[PBUFFERSIZE];
1358
0
  static int debug_enabled = -1;
1359
1360
0
  if (debug_enabled < 0)
1361
0
    debug_enabled = getenv("GIT_TRANSLOOP_DEBUG") ? 1 : 0;
1362
0
  if (!debug_enabled)
1363
0
    return;
1364
1365
0
  va_start(args, fmt);
1366
0
  vsnprintf(msgbuf, PBUFFERSIZE, fmt, args);
1367
0
  va_end(args);
1368
0
  fprintf(stderr, "Transfer loop debugging: %s\n", msgbuf);
1369
0
}
1370
1371
/* Stream state: More data may be coming in this direction. */
1372
0
#define SSTATE_TRANSFERRING 0
1373
/*
1374
 * Stream state: No more data coming in this direction, flushing rest of
1375
 * data.
1376
 */
1377
0
#define SSTATE_FLUSHING 1
1378
/* Stream state: Transfer in this direction finished. */
1379
0
#define SSTATE_FINISHED 2
1380
1381
0
#define STATE_NEEDS_READING(state) ((state) <= SSTATE_TRANSFERRING)
1382
0
#define STATE_NEEDS_WRITING(state) ((state) <= SSTATE_FLUSHING)
1383
0
#define STATE_NEEDS_CLOSING(state) ((state) == SSTATE_FLUSHING)
1384
1385
/* Unidirectional transfer. */
1386
struct unidirectional_transfer {
1387
  /* Source */
1388
  int src;
1389
  /* Destination */
1390
  int dest;
1391
  /* Is source socket? */
1392
  int src_is_sock;
1393
  /* Is destination socket? */
1394
  int dest_is_sock;
1395
  /* Transfer state (TRANSFERRING/FLUSHING/FINISHED) */
1396
  int state;
1397
  /* Buffer. */
1398
  char buf[BUFFERSIZE];
1399
  /* Buffer used. */
1400
  size_t bufuse;
1401
  /* Name of source. */
1402
  const char *src_name;
1403
  /* Name of destination. */
1404
  const char *dest_name;
1405
};
1406
1407
/* Closes the target (for writing) if transfer has finished. */
1408
static void udt_close_if_finished(struct unidirectional_transfer *t)
1409
0
{
1410
0
  if (STATE_NEEDS_CLOSING(t->state) && !t->bufuse) {
1411
0
    t->state = SSTATE_FINISHED;
1412
0
    if (t->dest_is_sock)
1413
0
      shutdown(t->dest, SHUT_WR);
1414
0
    else
1415
0
      close(t->dest);
1416
0
    transfer_debug("Closed %s.", t->dest_name);
1417
0
  }
1418
0
}
1419
1420
/*
1421
 * Tries to read data from source into buffer. If buffer is full,
1422
 * no data is read. Returns 0 on success, -1 on error.
1423
 */
1424
static int udt_do_read(struct unidirectional_transfer *t)
1425
0
{
1426
0
  ssize_t bytes;
1427
1428
0
  if (t->bufuse == BUFFERSIZE)
1429
0
    return 0; /* No space for more. */
1430
1431
0
  transfer_debug("%s is readable", t->src_name);
1432
0
  bytes = xread(t->src, t->buf + t->bufuse, BUFFERSIZE - t->bufuse);
1433
0
  if (bytes < 0) {
1434
0
    error_errno(_("read(%s) failed"), t->src_name);
1435
0
    return -1;
1436
0
  } else if (bytes == 0) {
1437
0
    transfer_debug("%s EOF (with %i bytes in buffer)",
1438
0
      t->src_name, (int)t->bufuse);
1439
0
    t->state = SSTATE_FLUSHING;
1440
0
  } else {
1441
0
    t->bufuse += bytes;
1442
0
    transfer_debug("Read %i bytes from %s (buffer now at %i)",
1443
0
      (int)bytes, t->src_name, (int)t->bufuse);
1444
0
  }
1445
0
  return 0;
1446
0
}
1447
1448
/* Tries to write data from buffer into destination. If buffer is empty,
1449
 * no data is written. Returns 0 on success, -1 on error.
1450
 */
1451
static int udt_do_write(struct unidirectional_transfer *t)
1452
0
{
1453
0
  ssize_t bytes;
1454
1455
0
  if (t->bufuse == 0)
1456
0
    return 0; /* Nothing to write. */
1457
1458
0
  transfer_debug("%s is writable", t->dest_name);
1459
0
  bytes = xwrite(t->dest, t->buf, t->bufuse);
1460
0
  if (bytes < 0) {
1461
0
    error_errno(_("write(%s) failed"), t->dest_name);
1462
0
    return -1;
1463
0
  } else if (bytes > 0) {
1464
0
    t->bufuse -= bytes;
1465
0
    if (t->bufuse)
1466
0
      memmove(t->buf, t->buf + bytes, t->bufuse);
1467
0
    transfer_debug("Wrote %i bytes to %s (buffer now at %i)",
1468
0
      (int)bytes, t->dest_name, (int)t->bufuse);
1469
0
  }
1470
0
  return 0;
1471
0
}
1472
1473
1474
/* State of bidirectional transfer loop. */
1475
struct bidirectional_transfer_state {
1476
  /* Direction from program to git. */
1477
  struct unidirectional_transfer ptg;
1478
  /* Direction from git to program. */
1479
  struct unidirectional_transfer gtp;
1480
};
1481
1482
static void *udt_copy_task_routine(void *udt)
1483
0
{
1484
0
  struct unidirectional_transfer *t = (struct unidirectional_transfer *)udt;
1485
0
  while (t->state != SSTATE_FINISHED) {
1486
0
    if (STATE_NEEDS_READING(t->state))
1487
0
      if (udt_do_read(t))
1488
0
        return NULL;
1489
0
    if (STATE_NEEDS_WRITING(t->state))
1490
0
      if (udt_do_write(t))
1491
0
        return NULL;
1492
0
    if (STATE_NEEDS_CLOSING(t->state))
1493
0
      udt_close_if_finished(t);
1494
0
  }
1495
0
  return udt; /* Just some non-NULL value. */
1496
0
}
1497
1498
#ifndef NO_PTHREADS
1499
1500
/*
1501
 * Join thread, with appropriate errors on failure. Name is name for the
1502
 * thread (for error messages). Returns 0 on success, 1 on failure.
1503
 */
1504
static int tloop_join(pthread_t thread, const char *name)
1505
0
{
1506
0
  int err;
1507
0
  void *tret;
1508
0
  err = pthread_join(thread, &tret);
1509
0
  if (!tret) {
1510
0
    error(_("%s thread failed"), name);
1511
0
    return 1;
1512
0
  }
1513
0
  if (err) {
1514
0
    error(_("%s thread failed to join: %s"), name, strerror(err));
1515
0
    return 1;
1516
0
  }
1517
0
  return 0;
1518
0
}
1519
1520
/*
1521
 * Spawn the transfer tasks and then wait for them. Returns 0 on success,
1522
 * -1 on failure.
1523
 */
1524
static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s)
1525
0
{
1526
0
  pthread_t gtp_thread;
1527
0
  pthread_t ptg_thread;
1528
0
  int err;
1529
0
  int ret = 0;
1530
0
  err = pthread_create(&gtp_thread, NULL, udt_copy_task_routine,
1531
0
    &s->gtp);
1532
0
  if (err)
1533
0
    die(_("can't start thread for copying data: %s"), strerror(err));
1534
0
  err = pthread_create(&ptg_thread, NULL, udt_copy_task_routine,
1535
0
    &s->ptg);
1536
0
  if (err)
1537
0
    die(_("can't start thread for copying data: %s"), strerror(err));
1538
1539
0
  ret |= tloop_join(gtp_thread, "Git to program copy");
1540
0
  ret |= tloop_join(ptg_thread, "Program to git copy");
1541
0
  return ret;
1542
0
}
1543
#else
1544
1545
/* Close the source and target (for writing) for transfer. */
1546
static void udt_kill_transfer(struct unidirectional_transfer *t)
1547
{
1548
  t->state = SSTATE_FINISHED;
1549
  /*
1550
   * Socket read end left open isn't a disaster if nobody
1551
   * attempts to read from it (mingw compat headers do not
1552
   * have SHUT_RD)...
1553
   *
1554
   * We can't fully close the socket since otherwise gtp
1555
   * task would first close the socket it sends data to
1556
   * while closing the ptg file descriptors.
1557
   */
1558
  if (!t->src_is_sock)
1559
    close(t->src);
1560
  if (t->dest_is_sock)
1561
    shutdown(t->dest, SHUT_WR);
1562
  else
1563
    close(t->dest);
1564
}
1565
1566
/*
1567
 * Join process, with appropriate errors on failure. Name is name for the
1568
 * process (for error messages). Returns 0 on success, 1 on failure.
1569
 */
1570
static int tloop_join(pid_t pid, const char *name)
1571
{
1572
  int tret;
1573
  if (waitpid(pid, &tret, 0) < 0) {
1574
    error_errno(_("%s process failed to wait"), name);
1575
    return 1;
1576
  }
1577
  if (!WIFEXITED(tret) || WEXITSTATUS(tret)) {
1578
    error(_("%s process failed"), name);
1579
    return 1;
1580
  }
1581
  return 0;
1582
}
1583
1584
/*
1585
 * Spawn the transfer tasks and then wait for them. Returns 0 on success,
1586
 * -1 on failure.
1587
 */
1588
static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s)
1589
{
1590
  pid_t pid1, pid2;
1591
  int ret = 0;
1592
1593
  /* Fork thread #1: git to program. */
1594
  pid1 = fork();
1595
  if (pid1 < 0)
1596
    die_errno(_("can't start thread for copying data"));
1597
  else if (pid1 == 0) {
1598
    udt_kill_transfer(&s->ptg);
1599
    exit(udt_copy_task_routine(&s->gtp) ? 0 : 1);
1600
  }
1601
1602
  /* Fork thread #2: program to git. */
1603
  pid2 = fork();
1604
  if (pid2 < 0)
1605
    die_errno(_("can't start thread for copying data"));
1606
  else if (pid2 == 0) {
1607
    udt_kill_transfer(&s->gtp);
1608
    exit(udt_copy_task_routine(&s->ptg) ? 0 : 1);
1609
  }
1610
1611
  /*
1612
   * Close both streams in parent as to not interfere with
1613
   * end of file detection and wait for both tasks to finish.
1614
   */
1615
  udt_kill_transfer(&s->gtp);
1616
  udt_kill_transfer(&s->ptg);
1617
  ret |= tloop_join(pid1, "Git to program copy");
1618
  ret |= tloop_join(pid2, "Program to git copy");
1619
  return ret;
1620
}
1621
#endif
1622
1623
/*
1624
 * Copies data from stdin to output and from input to stdout simultaneously.
1625
 * Additionally filtering through given filter. If filter is NULL, uses
1626
 * identity filter.
1627
 */
1628
int bidirectional_transfer_loop(int input, int output)
1629
0
{
1630
0
  struct bidirectional_transfer_state state;
1631
1632
  /* Fill the state fields. */
1633
0
  state.ptg.src = input;
1634
0
  state.ptg.dest = 1;
1635
0
  state.ptg.src_is_sock = (input == output);
1636
0
  state.ptg.dest_is_sock = 0;
1637
0
  state.ptg.state = SSTATE_TRANSFERRING;
1638
0
  state.ptg.bufuse = 0;
1639
0
  state.ptg.src_name = "remote input";
1640
0
  state.ptg.dest_name = "stdout";
1641
1642
0
  state.gtp.src = 0;
1643
0
  state.gtp.dest = output;
1644
0
  state.gtp.src_is_sock = 0;
1645
0
  state.gtp.dest_is_sock = (input == output);
1646
0
  state.gtp.state = SSTATE_TRANSFERRING;
1647
0
  state.gtp.bufuse = 0;
1648
0
  state.gtp.src_name = "stdin";
1649
0
  state.gtp.dest_name = "remote output";
1650
1651
0
  return tloop_spawnwait_tasks(&state);
1652
0
}
1653
1654
void reject_atomic_push(struct ref *remote_refs, int mirror_mode)
1655
0
{
1656
0
  struct ref *ref;
1657
1658
  /* Mark other refs as failed */
1659
0
  for (ref = remote_refs; ref; ref = ref->next) {
1660
0
    if (!ref->peer_ref && !mirror_mode)
1661
0
      continue;
1662
1663
0
    switch (ref->status) {
1664
0
    case REF_STATUS_NONE:
1665
0
    case REF_STATUS_OK:
1666
0
    case REF_STATUS_EXPECTING_REPORT:
1667
0
      ref->status = REF_STATUS_ATOMIC_PUSH_FAILED;
1668
0
      continue;
1669
0
    default:
1670
0
      break; /* do nothing */
1671
0
    }
1672
0
  }
1673
0
  return;
1674
0
}