/* apply-changeset.c:
*
* vim:smartindent ts=8:sts=2:sta:et:ai:shiftwidth=2
****************************************************************
* Copyright (C) 2004 Aaron Bentley
*
* See the file "COPYING" for further information about
* the copyright and warranty status of this work.
*/
#include "hackerlab/arrays/ar.h"
#include "hackerlab/bugs/panic.h"
#include "hackerlab/bugs/exception.h"
#include "hackerlab/os/errno-to-string.h"
#include "hackerlab/os/sys/wait.h"
#include "hackerlab/fmt/cvt.h"
#include "hackerlab/fs/file-names.h"
#include "hackerlab/mem/mem.h"
#include "hackerlab/vu/safe.h"
#include "libfsutils/copy-file.h"
#include "libfsutils/ensure-dir.h"
#include "libfsutils/tmp-files.h"
#include "libfsutils/rmrf.h"
#include "libarch/diffs.h"
#include "libarch/exec.h"
#include "libarch/invent.h"
#include "libarch/chatter.h"
#include "libarch/changelogs.h"
#include "libarch/conflict-handling.h"
#include "libarch/make-changeset.h"
#include "libarch/apply-changeset.h"
#include "libarch/inode-sig.h"
#include "libarch/project-tree.h"
#include "libarch/patch-logs.h"
#include "libarch/proj-tree-lint.h"
#include "merge-three-way.h"
static void
progress_dot_callback (void * vfd, char * fmt, va_list ap);
static void
three_way_callback (void * vfd, char * fmt, va_list ap);
static assoc_table tag_index_to_full_paths (arch_project_tree_t * tree);
/* returns
* 0 on success
* 1 on conflicts
* 2 (or exit :[) on failure
*/
int
arch_merge3(int chatter_fd, arch_project_tree_t * mine_tree, arch_project_tree_t * base_tree, arch_project_tree_t * other_tree, int escape_classes, int show_noops)
{
int dots_for_generation = 1;
struct arch_make_changeset_report make_report = {0, };
struct arch_apply_changeset_report * apply_report;
t_uchar * tmp_dir = talloc_tmp_file_name (talloc_context, mine_tree->root, ",,merge-three-way");
t_uchar * changeset = file_name_in_vicinity (0, tmp_dir, ",,changeset");
assoc_table inode_shortcut = 0;
t_uchar * base_revision = arch_tree_latest_revision (base_tree->root);
assoc_table older_files_table;
assoc_table yours_files_table;
arch_apply_changeset_report_callback apply_callback = NULL;
void * apply_thunk = NULL;
rmrf_file (tmp_dir);
safe_mkdir (tmp_dir, 0777);
if (chatter_fd != -1)
{
if (dots_for_generation)
make_report.callback = progress_dot_callback;
else
make_report.callback = three_way_callback;
make_report.thunk = (void *)(long)chatter_fd;
apply_callback = three_way_callback;
apply_thunk = (void *)(long)chatter_fd;
}
older_files_table = tag_index_to_full_paths (base_tree);
yours_files_table = tag_index_to_full_paths (other_tree);
arch_read_inode_sig_ids (0, &inode_shortcut, base_tree->root, other_tree->root, base_revision);
arch_chatter (chatter_fd, "* Comparing FROM and TO");
if (dots_for_generation)
arch_chatter (chatter_fd, ": ");
else
arch_chatter (chatter_fd, "\n");
arch_make_changeset (&make_report, base_tree, other_tree, changeset, arch_unspecified_id_tagging, arch_inventory_unrecognized, 0, inode_shortcut, 0, escape_classes);
if (dots_for_generation)
arch_chatter (chatter_fd, " done.\n");
arch_chatter (chatter_fd, "* Merging into tree\n");
apply_report = arch_merge_from_changeset (changeset, talloc_context, mine_tree, arch_unspecified_id_tagging, arch_inventory_unrecognized, older_files_table, yours_files_table, escape_classes, show_noops, apply_callback, apply_thunk);
rmrf_file (tmp_dir);
lim_free (0, base_revision);
lim_free (0, changeset);
talloc_free (tmp_dir);
arch_free_make_changeset_report_data (&make_report);
talloc_free (apply_report);
return arch_tree_conflicts_exist (mine_tree);
}
static void
progress_dot_callback (void * vfd, char * fmt, va_list ap)
{
int fd;
fd = (int)(t_ulong)vfd;
if (fd >= 0)
{
safe_printfmt_va_list (fd, ".", ap);
safe_flush (fd);
}
}
static void
three_way_callback (void * vfd, char * fmt, va_list ap)
{
int fd;
fd = (int)(t_ulong)vfd;
if (fd >= 0)
{
safe_printfmt_va_list (fd, fmt, ap);
safe_flush (fd);
}
}
static assoc_table
tag_index_to_full_paths (arch_project_tree_t * tree)
{
rel_table index = 0;
assoc_table answer = 0;
int x;
index = arch_source_inventory (tree, 1, 0, 0);
for (x = 0; x < rel_n_records (index); ++x)
{
t_uchar * relpath = index[x][0];
t_uchar * id = index[x][1];
t_uchar * full_path = file_name_in_vicinity (0, tree->root, relpath);
assoc_set (&answer, id, full_path);
lim_free (0, full_path);
}
rel_free_table (index);
return answer;
}
/* tag: 961f2509-ebf8-43aa-a14d-5b0df3090ec6 */
syntax highlighted by Code2HTML, v. 0.9.1