15
#include "dir.h"
16
#include "refs.h"
17
18
+enum rebase_type {
19
+ REBASE_INVALID = -1,
20
+ REBASE_FALSE = 0,
21
+ REBASE_TRUE,
22
+ REBASE_PRESERVE
23
+};
24
+
25
+/**
26
+ * Parses the value of --rebase. If value is a false value, returns
27
+ * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is
28
+ * "preserve", returns REBASE_PRESERVE. If value is a invalid value, dies with
29
+ * a fatal error if fatal is true, otherwise returns REBASE_INVALID.
30
+ */
31
+static enum rebase_type parse_config_rebase(const char *key, const char *value,
32
+ int fatal)
33
+{
34
+ int v = git_config_maybe_bool("pull.rebase", value);
35
+
36
+ if (!v)
37
+ return REBASE_FALSE;
38
+ else if (v > 0)
39
+ return REBASE_TRUE;
40
+ else if (!strcmp(value, "preserve"))
41
+ return REBASE_PRESERVE;
42
+
43
+ if (fatal)
44
+ die(_("Invalid value for %s: %s"), key, value);
45
+ else
46
+ error(_("Invalid value for %s: %s"), key, value);
47
+
48
+ return REBASE_INVALID;
49
+}
50
+
51
+/**
52
+ * Callback for --rebase, which parses arg with parse_config_rebase().
53
+ */
54
+static int parse_opt_rebase(const struct option *opt, const char *arg, int unset)
55
+{
56
+ enum rebase_type *value = opt->value;
57
+
58
+ if (arg)
59
+ *value = parse_config_rebase("--rebase", arg, 0);
60
+ else
61
+ *value = unset ? REBASE_FALSE : REBASE_TRUE;
62
+ return *value == REBASE_INVALID ? -1 : 0;
63
+}
64
+
65
static const char * const pull_usage[] = {
66
N_("git pull [options] [<repository> [<refspec>...]]"),
67
NULL
71
static int opt_verbosity;
72
static char *opt_progress;
73
27
-/* Options passed to git-merge */
74
+/* Options passed to git-merge or git-rebase */
75
+static enum rebase_type opt_rebase;
76
static char *opt_diffstat;
77
static char *opt_log;
78
static char *opt_squash;
106
N_("force progress reporting"),
107
PARSE_OPT_NOARG),
108
61
- /* Options passed to git-merge */
109
+ /* Options passed to git-merge or git-rebase */
110
OPT_GROUP(N_("Options related to merging")),
111
+ { OPTION_CALLBACK, 'r', "rebase", &opt_rebase,
112
+ N_("false|true|preserve"),
113
+ N_("incorporate changes by rebasing rather than merging"),
114
+ PARSE_OPT_OPTARG, parse_opt_rebase },
115
OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
116
N_("do not show a diffstat at the end of the merge"),
117
PARSE_OPT_NOARG | PARSE_OPT_NONEG),
501
return ret;
502
}
503
504
+/**
505
+ * Returns remote's upstream branch for the current branch. If remote is NULL,
506
+ * the current branch's configured default remote is used. Returns NULL if
507
+ * `remote` does not name a valid remote, HEAD does not point to a branch,
508
+ * remote is not the branch's configured remote or the branch does not have any
509
+ * configured upstream branch.
510
+ */
511
+static const char *get_upstream_branch(const char *remote)
512
+{
513
+ struct remote *rm;
514
+ struct branch *curr_branch;
515
+ const char *curr_branch_remote;
516
+
517
+ rm = remote_get(remote);
518
+ if (!rm)
519
+ return NULL;
520
+
521
+ curr_branch = branch_get("HEAD");
522
+ if (!curr_branch)
523
+ return NULL;
524
+
525
+ curr_branch_remote = remote_for_branch(curr_branch, NULL);
526
+ assert(curr_branch_remote);
527
+
528
+ if (strcmp(curr_branch_remote, rm->name))
529
+ return NULL;
530
+
531
+ return branch_get_upstream(curr_branch, NULL);
532
+}
533
+
534
+/**
535
+ * Derives the remote tracking branch from the remote and refspec.
536
+ *
537
+ * FIXME: The current implementation assumes the default mapping of
538
+ * refs/heads/<branch_name> to refs/remotes/<remote_name>/<branch_name>.
539
+ */
540
+static const char *get_tracking_branch(const char *remote, const char *refspec)
541
+{
542
+ struct refspec *spec;
543
+ const char *spec_src;
544
+ const char *merge_branch;
545
+
546
+ spec = parse_fetch_refspec(1, &refspec);
547
+ spec_src = spec->src;
548
+ if (!*spec_src || !strcmp(spec_src, "HEAD"))
549
+ spec_src = "HEAD";
550
+ else if (skip_prefix(spec_src, "heads/", &spec_src))
551
+ ;
552
+ else if (skip_prefix(spec_src, "refs/heads/", &spec_src))
553
+ ;
554
+ else if (starts_with(spec_src, "refs/") ||
555
+ starts_with(spec_src, "tags/") ||
556
+ starts_with(spec_src, "remotes/"))
557
+ spec_src = "";
558
+
559
+ if (*spec_src) {
560
+ if (!strcmp(remote, "."))
561
+ merge_branch = mkpath("refs/heads/%s", spec_src);
562
+ else
563
+ merge_branch = mkpath("refs/remotes/%s/%s", remote, spec_src);
564
+ } else
565
+ merge_branch = NULL;
566
+
567
+ free_refspec(1, spec);
568
+ return merge_branch;
569
+}
570
+
571
+/**
572
+ * Given the repo and refspecs, sets fork_point to the point at which the
573
+ * current branch forked from its remote tracking branch. Returns 0 on success,
574
+ * -1 on failure.
575
+ */
576
+static int get_rebase_fork_point(unsigned char *fork_point, const char *repo,
577
+ const char *refspec)
578
+{
579
+ int ret;
580
+ struct branch *curr_branch;
581
+ const char *remote_branch;
582
+ struct child_process cp = CHILD_PROCESS_INIT;
583
+ struct strbuf sb = STRBUF_INIT;
584
+
585
+ curr_branch = branch_get("HEAD");
586
+ if (!curr_branch)
587
+ return -1;
588
+
589
+ if (refspec)
590
+ remote_branch = get_tracking_branch(repo, refspec);
591
+ else
592
+ remote_branch = get_upstream_branch(repo);
593
+
594
+ if (!remote_branch)
595
+ return -1;
596
+
597
+ argv_array_pushl(&cp.args, "merge-base", "--fork-point",
598
+ remote_branch, curr_branch->name, NULL);
599
+ cp.no_stdin = 1;
600
+ cp.no_stderr = 1;
601
+ cp.git_cmd = 1;
602
+
603
+ ret = capture_command(&cp, &sb, GIT_SHA1_HEXSZ);
604
+ if (ret)
605
+ goto cleanup;
606
+
607
+ ret = get_sha1_hex(sb.buf, fork_point);
608
+ if (ret)
609
+ goto cleanup;
610
+
611
+cleanup:
612
+ strbuf_release(&sb);
613
+ return ret ? -1 : 0;
614
+}
615
+
616
+/**
617
+ * Sets merge_base to the octopus merge base of curr_head, merge_head and
618
+ * fork_point. Returns 0 if a merge base is found, 1 otherwise.
619
+ */
620
+static int get_octopus_merge_base(unsigned char *merge_base,
621
+ const unsigned char *curr_head,
622
+ const unsigned char *merge_head,
623
+ const unsigned char *fork_point)
624
+{
625
+ struct commit_list *revs = NULL, *result;
626
+
627
+ commit_list_insert(lookup_commit_reference(curr_head), &revs);
628
+ commit_list_insert(lookup_commit_reference(merge_head), &revs);
629
+ if (!is_null_sha1(fork_point))
630
+ commit_list_insert(lookup_commit_reference(fork_point), &revs);
631
+
632
+ result = reduce_heads(get_octopus_merge_bases(revs));
633
+ free_commit_list(revs);
634
+ if (!result)
635
+ return 1;
636
+
637
+ hashcpy(merge_base, result->item->object.sha1);
638
+ return 0;
639
+}
640
+
641
+/**
642
+ * Given the current HEAD SHA1, the merge head returned from git-fetch and the
643
+ * fork point calculated by get_rebase_fork_point(), runs git-rebase with the
644
+ * appropriate arguments and returns its exit status.
645
+ */
646
+static int run_rebase(const unsigned char *curr_head,
647
+ const unsigned char *merge_head,
648
+ const unsigned char *fork_point)
649
+{
650
+ int ret;
651
+ unsigned char oct_merge_base[GIT_SHA1_RAWSZ];
652
+ struct argv_array args = ARGV_ARRAY_INIT;
653
+
654
+ if (!get_octopus_merge_base(oct_merge_base, curr_head, merge_head, fork_point))
655
+ if (!is_null_sha1(fork_point) && !hashcmp(oct_merge_base, fork_point))
656
+ fork_point = NULL;
657
+
658
+ argv_array_push(&args, "rebase");
659
+
660
+ /* Shared options */
661
+ argv_push_verbosity(&args);
662
+
663
+ /* Options passed to git-rebase */
664
+ if (opt_rebase == REBASE_PRESERVE)
665
+ argv_array_push(&args, "--preserve-merges");
666
+ if (opt_diffstat)
667
+ argv_array_push(&args, opt_diffstat);
668
+ argv_array_pushv(&args, opt_strategies.argv);
669
+ argv_array_pushv(&args, opt_strategy_opts.argv);
670
+ if (opt_gpg_sign)
671
+ argv_array_push(&args, opt_gpg_sign);
672
+
673
+ argv_array_push(&args, "--onto");
674
+ argv_array_push(&args, sha1_to_hex(merge_head));
675
+
676
+ if (fork_point && !is_null_sha1(fork_point))
677
+ argv_array_push(&args, sha1_to_hex(fork_point));
678
+ else
679
+ argv_array_push(&args, sha1_to_hex(merge_head));
680
+
681
+ ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
682
+ argv_array_clear(&args);
683
+ return ret;
684
+}
685
+
686
int cmd_pull(int argc, const char **argv, const char *prefix)
687
{
688
const char *repo, **refspecs;
689
struct sha1_array merge_heads = SHA1_ARRAY_INIT;
690
unsigned char orig_head[GIT_SHA1_RAWSZ], curr_head[GIT_SHA1_RAWSZ];
691
+ unsigned char rebase_fork_point[GIT_SHA1_RAWSZ];
692
693
if (!getenv("_GIT_USE_BUILTIN_PULL")) {
694
const char *path = mkpath("%s/git-pull", git_exec_path());
718
if (get_sha1("HEAD", orig_head))
719
hashclr(orig_head);
720
721
+ if (opt_rebase)
722
+ if (get_rebase_fork_point(rebase_fork_point, repo, *refspecs))
723
+ hashclr(rebase_fork_point);
724
+
725
if (run_fetch(repo, refspecs))
726
return 1;
727
763
if (merge_heads.nr > 1)
764
die(_("Cannot merge multiple branches into empty head."));
765
return pull_into_void(*merge_heads.sha1, curr_head);
766
+ } else if (opt_rebase) {
767
+ if (merge_heads.nr > 1)
768
+ die(_("Cannot rebase onto multiple branches."));
769
+ return run_rebase(curr_head, *merge_heads.sha1, rebase_fork_point);
770
} else
771
return run_merge();
772
}