Coverage Report

Created: 2026-10-17 07:15

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