Move try_merge_command and checkout_fast_forward to libgit.a

These functions are called in sequencer.c, which is part of libgit.a. This makes libgit.a potentially require builtin/merge.c for external git commands. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Jeff King <peff@peff.net>

Nguyễn Thái Ngọc Duy committed Oct 26, 2012 at 22:53 UTC db699a8a1f2c8063620efae41e66786c11a31d8f
6 files changed +125 -112
Makefile
+1
@@ -763,6 +763,7 @@ LIB_OBJS += lockfile.o
763 LIB_OBJS += log-tree.o
764 LIB_OBJS += mailmap.o
765 LIB_OBJS += match-trees.o
766 +LIB_OBJS += merge.o
767 LIB_OBJS += merge-file.o
768 LIB_OBJS += merge-recursive.o
769 LIB_OBJS += mergesort.o
builtin/merge.c
+2 -104
@@ -628,59 +628,6 @@ static void write_tree_trivial(unsigned char *sha1)
628 die(_("git write-tree failed to write a tree"));
629 }
630
631 -static const char *merge_argument(struct commit *commit)
632 -{
633 - if (commit)
634 - return sha1_to_hex(commit->object.sha1);
635 - else
636 - return EMPTY_TREE_SHA1_HEX;
637 -}
638 -
639 -int try_merge_command(const char *strategy, size_t xopts_nr,
640 - const char **xopts, struct commit_list *common,
641 - const char *head_arg, struct commit_list *remotes)
642 -{
643 - const char **args;
644 - int i = 0, x = 0, ret;
645 - struct commit_list *j;
646 - struct strbuf buf = STRBUF_INIT;
647 -
648 - args = xmalloc((4 + xopts_nr + commit_list_count(common) +
649 - commit_list_count(remotes)) * sizeof(char *));
650 - strbuf_addf(&buf, "merge-%s", strategy);
651 - args[i++] = buf.buf;
652 - for (x = 0; x < xopts_nr; x++) {
653 - char *s = xmalloc(strlen(xopts[x])+2+1);
654 - strcpy(s, "--");
655 - strcpy(s+2, xopts[x]);
656 - args[i++] = s;
657 - }
658 - for (j = common; j; j = j->next)
659 - args[i++] = xstrdup(merge_argument(j->item));
660 - args[i++] = "--";
661 - args[i++] = head_arg;
662 - for (j = remotes; j; j = j->next)
663 - args[i++] = xstrdup(merge_argument(j->item));
664 - args[i] = NULL;
665 - ret = run_command_v_opt(args, RUN_GIT_CMD);
666 - strbuf_release(&buf);
667 - i = 1;
668 - for (x = 0; x < xopts_nr; x++)
669 - free((void *)args[i++]);
670 - for (j = common; j; j = j->next)
671 - free((void *)args[i++]);
672 - i += 2;
673 - for (j = remotes; j; j = j->next)
674 - free((void *)args[i++]);
675 - free(args);
676 - discard_cache();
677 - if (read_cache() < 0)
678 - die(_("failed to read the cache"));
679 - resolve_undo_clear();
680 -
681 - return ret;
682 -}
683 -
631 static int try_merge_strategy(const char *strategy, struct commit_list *common,
632 struct commit_list *remoteheads,
633 struct commit *head, const char *head_arg)
@@ -762,56 +709,6 @@ static int count_unmerged_entries(void)
709 return ret;
710 }
711
765 -int checkout_fast_forward(const unsigned char *head, const unsigned char *remote)
766 -{
767 - struct tree *trees[MAX_UNPACK_TREES];
768 - struct unpack_trees_options opts;
769 - struct tree_desc t[MAX_UNPACK_TREES];
770 - int i, fd, nr_trees = 0;
771 - struct dir_struct dir;
772 - struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
773 -
774 - refresh_cache(REFRESH_QUIET);
775 -
776 - fd = hold_locked_index(lock_file, 1);
777 -
778 - memset(&trees, 0, sizeof(trees));
779 - memset(&opts, 0, sizeof(opts));
780 - memset(&t, 0, sizeof(t));
781 - if (overwrite_ignore) {
782 - memset(&dir, 0, sizeof(dir));
783 - dir.flags |= DIR_SHOW_IGNORED;
784 - setup_standard_excludes(&dir);
785 - opts.dir = &dir;
786 - }
787 -
788 - opts.head_idx = 1;
789 - opts.src_index = &the_index;
790 - opts.dst_index = &the_index;
791 - opts.update = 1;
792 - opts.verbose_update = 1;
793 - opts.merge = 1;
794 - opts.fn = twoway_merge;
795 - setup_unpack_trees_porcelain(&opts, "merge");
796 -
797 - trees[nr_trees] = parse_tree_indirect(head);
798 - if (!trees[nr_trees++])
799 - return -1;
800 - trees[nr_trees] = parse_tree_indirect(remote);
801 - if (!trees[nr_trees++])
802 - return -1;
803 - for (i = 0; i < nr_trees; i++) {
804 - parse_tree(trees[i]);
805 - init_tree_desc(t+i, trees[i]->buffer, trees[i]->size);
806 - }
807 - if (unpack_trees(nr_trees, t, &opts))
808 - return -1;
809 - if (write_cache(fd, active_cache, active_nr) ||
810 - commit_locked_index(lock_file))
811 - die(_("unable to write new index file"));
812 - return 0;
813 -}
814 -
712 static void split_merge_strategies(const char *string, struct strategy **list,
713 int *nr, int *alloc)
714 {
@@ -1424,7 +1321,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
1321 }
1322
1323 if (checkout_fast_forward(head_commit->object.sha1,
1427 - commit->object.sha1)) {
1324 + commit->object.sha1,
1325 + overwrite_ignore)) {
1326 ret = 1;
1327 goto done;
1328 }
cache.h
+9 -2
@@ -1265,8 +1265,15 @@ struct startup_info {
1265 };
1266 extern struct startup_info *startup_info;
1267
1268 -/* builtin/merge.c */
1269 -int checkout_fast_forward(const unsigned char *from, const unsigned char *to);
1268 +/* merge.c */
1269 +struct commit_list;
1270 +int try_merge_command(const char *strategy, size_t xopts_nr,
1271 + const char **xopts, struct commit_list *common,
1272 + const char *head_arg, struct commit_list *remotes);
1273 +int checkout_fast_forward(const unsigned char *from,
1274 + const unsigned char *to,
1275 + int overwrite_ignore);
1276 +
1277
1278 int sane_execvp(const char *file, char *const argv[]);
1279
merge-recursive.h
-5
@@ -59,9 +59,4 @@ struct tree *write_tree_from_memory(struct merge_options *o);
59
60 int parse_merge_opt(struct merge_options *out, const char *s);
61
62 -/* builtin/merge.c */
63 -int try_merge_command(const char *strategy, size_t xopts_nr,
64 - const char **xopts, struct commit_list *common,
65 - const char *head_arg, struct commit_list *remotes);
66 -
62 #endif
merge.c new
+112
@@ -0,0 +1,112 @@
1 +#include "cache.h"
2 +#include "commit.h"
3 +#include "run-command.h"
4 +#include "resolve-undo.h"
5 +#include "tree-walk.h"
6 +#include "unpack-trees.h"
7 +#include "dir.h"
8 +
9 +static const char *merge_argument(struct commit *commit)
10 +{
11 + if (commit)
12 + return sha1_to_hex(commit->object.sha1);
13 + else
14 + return EMPTY_TREE_SHA1_HEX;
15 +}
16 +
17 +int try_merge_command(const char *strategy, size_t xopts_nr,
18 + const char **xopts, struct commit_list *common,
19 + const char *head_arg, struct commit_list *remotes)
20 +{
21 + const char **args;
22 + int i = 0, x = 0, ret;
23 + struct commit_list *j;
24 + struct strbuf buf = STRBUF_INIT;
25 +
26 + args = xmalloc((4 + xopts_nr + commit_list_count(common) +
27 + commit_list_count(remotes)) * sizeof(char *));
28 + strbuf_addf(&buf, "merge-%s", strategy);
29 + args[i++] = buf.buf;
30 + for (x = 0; x < xopts_nr; x++) {
31 + char *s = xmalloc(strlen(xopts[x])+2+1);
32 + strcpy(s, "--");
33 + strcpy(s+2, xopts[x]);
34 + args[i++] = s;
35 + }
36 + for (j = common; j; j = j->next)
37 + args[i++] = xstrdup(merge_argument(j->item));
38 + args[i++] = "--";
39 + args[i++] = head_arg;
40 + for (j = remotes; j; j = j->next)
41 + args[i++] = xstrdup(merge_argument(j->item));
42 + args[i] = NULL;
43 + ret = run_command_v_opt(args, RUN_GIT_CMD);
44 + strbuf_release(&buf);
45 + i = 1;
46 + for (x = 0; x < xopts_nr; x++)
47 + free((void *)args[i++]);
48 + for (j = common; j; j = j->next)
49 + free((void *)args[i++]);
50 + i += 2;
51 + for (j = remotes; j; j = j->next)
52 + free((void *)args[i++]);
53 + free(args);
54 + discard_cache();
55 + if (read_cache() < 0)
56 + die(_("failed to read the cache"));
57 + resolve_undo_clear();
58 +
59 + return ret;
60 +}
61 +
62 +int checkout_fast_forward(const unsigned char *head,
63 + const unsigned char *remote,
64 + int overwrite_ignore)
65 +{
66 + struct tree *trees[MAX_UNPACK_TREES];
67 + struct unpack_trees_options opts;
68 + struct tree_desc t[MAX_UNPACK_TREES];
69 + int i, fd, nr_trees = 0;
70 + struct dir_struct dir;
71 + struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
72 +
73 + refresh_cache(REFRESH_QUIET);
74 +
75 + fd = hold_locked_index(lock_file, 1);
76 +
77 + memset(&trees, 0, sizeof(trees));
78 + memset(&opts, 0, sizeof(opts));
79 + memset(&t, 0, sizeof(t));
80 + if (overwrite_ignore) {
81 + memset(&dir, 0, sizeof(dir));
82 + dir.flags |= DIR_SHOW_IGNORED;
83 + setup_standard_excludes(&dir);
84 + opts.dir = &dir;
85 + }
86 +
87 + opts.head_idx = 1;
88 + opts.src_index = &the_index;
89 + opts.dst_index = &the_index;
90 + opts.update = 1;
91 + opts.verbose_update = 1;
92 + opts.merge = 1;
93 + opts.fn = twoway_merge;
94 + setup_unpack_trees_porcelain(&opts, "merge");
95 +
96 + trees[nr_trees] = parse_tree_indirect(head);
97 + if (!trees[nr_trees++])
98 + return -1;
99 + trees[nr_trees] = parse_tree_indirect(remote);
100 + if (!trees[nr_trees++])
101 + return -1;
102 + for (i = 0; i < nr_trees; i++) {
103 + parse_tree(trees[i]);
104 + init_tree_desc(t+i, trees[i]->buffer, trees[i]->size);
105 + }
106 + if (unpack_trees(nr_trees, t, &opts))
107 + return -1;
108 + if (write_cache(fd, active_cache, active_nr) ||
109 + commit_locked_index(lock_file))
110 + die(_("unable to write new index file"));
111 + return 0;
112 +}
sequencer.c
+1 -1
@@ -191,7 +191,7 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from)
191 struct ref_lock *ref_lock;
192
193 read_cache();
194 - if (checkout_fast_forward(from, to))
194 + if (checkout_fast_forward(from, to, 1))
195 exit(1); /* the callee should have complained already */
196 ref_lock = lock_any_ref_for_update("HEAD", from, 0);
197 return write_ref_sha1(ref_lock, to, "cherry-pick");