Skip to content

Commit

Permalink
Move try_merge_command and checkout_fast_forward to libgit.a
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
pclouds authored and peff committed Oct 29, 2012
1 parent 2cfceef commit db699a8
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 112 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@ LIB_OBJS += lockfile.o
LIB_OBJS += log-tree.o
LIB_OBJS += mailmap.o
LIB_OBJS += match-trees.o
LIB_OBJS += merge.o
LIB_OBJS += merge-file.o
LIB_OBJS += merge-recursive.o
LIB_OBJS += mergesort.o
Expand Down
106 changes: 2 additions & 104 deletions builtin/merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,59 +628,6 @@ static void write_tree_trivial(unsigned char *sha1)
die(_("git write-tree failed to write a tree"));
}

static const char *merge_argument(struct commit *commit)
{
if (commit)
return sha1_to_hex(commit->object.sha1);
else
return EMPTY_TREE_SHA1_HEX;
}

int try_merge_command(const char *strategy, size_t xopts_nr,
const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes)
{
const char **args;
int i = 0, x = 0, ret;
struct commit_list *j;
struct strbuf buf = STRBUF_INIT;

args = xmalloc((4 + xopts_nr + commit_list_count(common) +
commit_list_count(remotes)) * sizeof(char *));
strbuf_addf(&buf, "merge-%s", strategy);
args[i++] = buf.buf;
for (x = 0; x < xopts_nr; x++) {
char *s = xmalloc(strlen(xopts[x])+2+1);
strcpy(s, "--");
strcpy(s+2, xopts[x]);
args[i++] = s;
}
for (j = common; j; j = j->next)
args[i++] = xstrdup(merge_argument(j->item));
args[i++] = "--";
args[i++] = head_arg;
for (j = remotes; j; j = j->next)
args[i++] = xstrdup(merge_argument(j->item));
args[i] = NULL;
ret = run_command_v_opt(args, RUN_GIT_CMD);
strbuf_release(&buf);
i = 1;
for (x = 0; x < xopts_nr; x++)
free((void *)args[i++]);
for (j = common; j; j = j->next)
free((void *)args[i++]);
i += 2;
for (j = remotes; j; j = j->next)
free((void *)args[i++]);
free(args);
discard_cache();
if (read_cache() < 0)
die(_("failed to read the cache"));
resolve_undo_clear();

return ret;
}

static int try_merge_strategy(const char *strategy, struct commit_list *common,
struct commit_list *remoteheads,
struct commit *head, const char *head_arg)
Expand Down Expand Up @@ -762,56 +709,6 @@ static int count_unmerged_entries(void)
return ret;
}

int checkout_fast_forward(const unsigned char *head, const unsigned char *remote)
{
struct tree *trees[MAX_UNPACK_TREES];
struct unpack_trees_options opts;
struct tree_desc t[MAX_UNPACK_TREES];
int i, fd, nr_trees = 0;
struct dir_struct dir;
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));

refresh_cache(REFRESH_QUIET);

fd = hold_locked_index(lock_file, 1);

memset(&trees, 0, sizeof(trees));
memset(&opts, 0, sizeof(opts));
memset(&t, 0, sizeof(t));
if (overwrite_ignore) {
memset(&dir, 0, sizeof(dir));
dir.flags |= DIR_SHOW_IGNORED;
setup_standard_excludes(&dir);
opts.dir = &dir;
}

opts.head_idx = 1;
opts.src_index = &the_index;
opts.dst_index = &the_index;
opts.update = 1;
opts.verbose_update = 1;
opts.merge = 1;
opts.fn = twoway_merge;
setup_unpack_trees_porcelain(&opts, "merge");

trees[nr_trees] = parse_tree_indirect(head);
if (!trees[nr_trees++])
return -1;
trees[nr_trees] = parse_tree_indirect(remote);
if (!trees[nr_trees++])
return -1;
for (i = 0; i < nr_trees; i++) {
parse_tree(trees[i]);
init_tree_desc(t+i, trees[i]->buffer, trees[i]->size);
}
if (unpack_trees(nr_trees, t, &opts))
return -1;
if (write_cache(fd, active_cache, active_nr) ||
commit_locked_index(lock_file))
die(_("unable to write new index file"));
return 0;
}

static void split_merge_strategies(const char *string, struct strategy **list,
int *nr, int *alloc)
{
Expand Down Expand Up @@ -1424,7 +1321,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
}

if (checkout_fast_forward(head_commit->object.sha1,
commit->object.sha1)) {
commit->object.sha1,
overwrite_ignore)) {
ret = 1;
goto done;
}
Expand Down
11 changes: 9 additions & 2 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1265,8 +1265,15 @@ struct startup_info {
};
extern struct startup_info *startup_info;

/* builtin/merge.c */
int checkout_fast_forward(const unsigned char *from, const unsigned char *to);
/* merge.c */
struct commit_list;
int try_merge_command(const char *strategy, size_t xopts_nr,
const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes);
int checkout_fast_forward(const unsigned char *from,
const unsigned char *to,
int overwrite_ignore);


int sane_execvp(const char *file, char *const argv[]);

Expand Down
5 changes: 0 additions & 5 deletions merge-recursive.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,4 @@ struct tree *write_tree_from_memory(struct merge_options *o);

int parse_merge_opt(struct merge_options *out, const char *s);

/* builtin/merge.c */
int try_merge_command(const char *strategy, size_t xopts_nr,
const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes);

#endif
112 changes: 112 additions & 0 deletions merge.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#include "cache.h"
#include "commit.h"
#include "run-command.h"
#include "resolve-undo.h"
#include "tree-walk.h"
#include "unpack-trees.h"
#include "dir.h"

static const char *merge_argument(struct commit *commit)
{
if (commit)
return sha1_to_hex(commit->object.sha1);
else
return EMPTY_TREE_SHA1_HEX;
}

int try_merge_command(const char *strategy, size_t xopts_nr,
const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes)
{
const char **args;
int i = 0, x = 0, ret;
struct commit_list *j;
struct strbuf buf = STRBUF_INIT;

args = xmalloc((4 + xopts_nr + commit_list_count(common) +
commit_list_count(remotes)) * sizeof(char *));
strbuf_addf(&buf, "merge-%s", strategy);
args[i++] = buf.buf;
for (x = 0; x < xopts_nr; x++) {
char *s = xmalloc(strlen(xopts[x])+2+1);
strcpy(s, "--");
strcpy(s+2, xopts[x]);
args[i++] = s;
}
for (j = common; j; j = j->next)
args[i++] = xstrdup(merge_argument(j->item));
args[i++] = "--";
args[i++] = head_arg;
for (j = remotes; j; j = j->next)
args[i++] = xstrdup(merge_argument(j->item));
args[i] = NULL;
ret = run_command_v_opt(args, RUN_GIT_CMD);
strbuf_release(&buf);
i = 1;
for (x = 0; x < xopts_nr; x++)
free((void *)args[i++]);
for (j = common; j; j = j->next)
free((void *)args[i++]);
i += 2;
for (j = remotes; j; j = j->next)
free((void *)args[i++]);
free(args);
discard_cache();
if (read_cache() < 0)
die(_("failed to read the cache"));
resolve_undo_clear();

return ret;
}

int checkout_fast_forward(const unsigned char *head,
const unsigned char *remote,
int overwrite_ignore)
{
struct tree *trees[MAX_UNPACK_TREES];
struct unpack_trees_options opts;
struct tree_desc t[MAX_UNPACK_TREES];
int i, fd, nr_trees = 0;
struct dir_struct dir;
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));

refresh_cache(REFRESH_QUIET);

fd = hold_locked_index(lock_file, 1);

memset(&trees, 0, sizeof(trees));
memset(&opts, 0, sizeof(opts));
memset(&t, 0, sizeof(t));
if (overwrite_ignore) {
memset(&dir, 0, sizeof(dir));
dir.flags |= DIR_SHOW_IGNORED;
setup_standard_excludes(&dir);
opts.dir = &dir;
}

opts.head_idx = 1;
opts.src_index = &the_index;
opts.dst_index = &the_index;
opts.update = 1;
opts.verbose_update = 1;
opts.merge = 1;
opts.fn = twoway_merge;
setup_unpack_trees_porcelain(&opts, "merge");

trees[nr_trees] = parse_tree_indirect(head);
if (!trees[nr_trees++])
return -1;
trees[nr_trees] = parse_tree_indirect(remote);
if (!trees[nr_trees++])
return -1;
for (i = 0; i < nr_trees; i++) {
parse_tree(trees[i]);
init_tree_desc(t+i, trees[i]->buffer, trees[i]->size);
}
if (unpack_trees(nr_trees, t, &opts))
return -1;
if (write_cache(fd, active_cache, active_nr) ||
commit_locked_index(lock_file))
die(_("unable to write new index file"));
return 0;
}
2 changes: 1 addition & 1 deletion sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from)
struct ref_lock *ref_lock;

read_cache();
if (checkout_fast_forward(from, to))
if (checkout_fast_forward(from, to, 1))
exit(1); /* the callee should have complained already */
ref_lock = lock_any_ref_for_update("HEAD", from, 0);
return write_ref_sha1(ref_lock, to, "cherry-pick");
Expand Down

0 comments on commit db699a8

Please sign in to comment.