From: Junio C Hamano Date: Sun, 26 Mar 2006 01:44:01 +0000 (-0800) Subject: Merge branch 'lt/diffgen' into next X-Git-Tag: v1.3.0-rc1~7 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/9acf322d69f54ff5bf9de8b2d6f9cd1dccf523a3?ds=inline;hp=-c Merge branch 'lt/diffgen' into next * lt/diffgen: built-in diff: minimum tweaks builtin-diff: \No newline at end of file. Use a *real* built-in diff generator --- 9acf322d69f54ff5bf9de8b2d6f9cd1dccf523a3 diff --combined Makefile index 236bac1f25,0f565eb4d3..663a803dd8 --- a/Makefile +++ b/Makefile @@@ -188,9 -188,10 +188,10 @@@ PYMODULES = gitMergeCommon.py LIB_FILE=libgit.a + XDIFF_LIB=xdiff/lib.a LIB_H = \ - blob.h cache.h commit.h count-delta.h csum-file.h delta.h \ + blob.h cache.h commit.h csum-file.h delta.h \ diff.h object.h pack.h pkt-line.h quote.h refs.h \ run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h @@@ -200,7 -201,7 +201,7 @@@ DIFF_OBJS = diffcore-delta.o LIB_OBJS = \ - blob.o commit.o connect.o count-delta.o csum-file.o \ + blob.o commit.o connect.o csum-file.o \ date.o diff-delta.o entry.o exec_cmd.o ident.o index.o \ object.o pack-check.o patch-delta.o path.o pkt-line.o \ quote.o read-cache.o refs.o run-command.o \ @@@ -209,7 -210,7 +210,7 @@@ fetch-clone.o revision.o pager.o \ $(DIFF_OBJS) - LIBS = $(LIB_FILE) + LIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS += -lz # @@@ -544,12 -545,18 +545,18 @@@ init-db.o: init-db. -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $*.c $(LIB_OBJS): $(LIB_H) - $(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) + $(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIBS) $(DIFF_OBJS): diffcore.h $(LIB_FILE): $(LIB_OBJS) $(AR) rcs $@ $(LIB_OBJS) + XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o + + $(XDIFF_LIB): $(XDIFF_OBJS) + $(AR) rcs $@ $(XDIFF_OBJS) + + doc: $(MAKE) -C Documentation all diff --combined diff.c index c73a40b9ab,cd2ce0fdf5..4440465b47 --- a/diff.c +++ b/diff.c @@@ -8,6 -8,7 +8,7 @@@ #include "quote.h" #include "diff.h" #include "diffcore.h" + #include "xdiff/xdiff.h" static const char *diff_opts = "-pu"; @@@ -178,6 -179,70 +179,70 @@@ static void emit_rewrite_diff(const cha copy_file('+', temp[1].name); } + static int fill_mmfile(mmfile_t *mf, const char *file) + { + int fd = open(file, O_RDONLY); + struct stat st; + char *buf; + unsigned long size; + + mf->ptr = NULL; + mf->size = 0; + if (fd < 0) + return 0; + fstat(fd, &st); + size = st.st_size; + buf = xmalloc(size); + mf->ptr = buf; + mf->size = size; + while (size) { + int retval = read(fd, buf, size); + if (retval < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + break; + } + if (!retval) + break; + buf += retval; + size -= retval; + } + mf->size -= size; + close(fd); + return 0; + } + + struct emit_callback { + const char **label_path; + }; + + static int fn_out(void *priv, mmbuffer_t *mb, int nbuf) + { + int i; + struct emit_callback *ecbdata = priv; + + if (ecbdata->label_path[0]) { + printf("--- %s\n", ecbdata->label_path[0]); + printf("+++ %s\n", ecbdata->label_path[1]); + ecbdata->label_path[0] = ecbdata->label_path[1] = NULL; + } + for (i = 0; i < nbuf; i++) + if (!fwrite(mb[i].ptr, mb[i].size, 1, stdout)) + return -1; + return 0; + } + + #define FIRST_FEW_BYTES 8000 + static int mmfile_is_binary(mmfile_t *mf) + { + long sz = mf->size; + if (FIRST_FEW_BYTES < sz) + sz = FIRST_FEW_BYTES; + if (memchr(mf->ptr, 0, sz)) + return 1; + return 0; + } + static const char *builtin_diff(const char *name_a, const char *name_b, struct diff_tempfile *temp, @@@ -186,6 -251,7 +251,7 @@@ const char **args) { int i, next_at, cmd_size; + mmfile_t mf1, mf2; const char *const diff_cmd = "diff -L%s -L%s"; const char *const diff_arg = "-- %s %s||:"; /* "||:" is to return 0 */ const char *input_name_sq[2]; @@@ -255,12 -321,44 +321,44 @@@ } } - /* This is disgusting */ - *args++ = "sh"; - *args++ = "-c"; - *args++ = cmd; - *args = NULL; - return "/bin/sh"; + /* Un-quote the paths */ + if (label_path[0][0] != '/') + label_path[0] = quote_two("a/", name_a); + if (label_path[1][0] != '/') + label_path[1] = quote_two("b/", name_b); + + if (fill_mmfile(&mf1, temp[0].name) < 0 || + fill_mmfile(&mf2, temp[1].name) < 0) + die("unable to read files to diff"); + + if (mmfile_is_binary(&mf1) || mmfile_is_binary(&mf2)) + printf("Binary files %s and %s differ\n", + label_path[0], label_path[1]); + else { + /* Crazy xdl interfaces.. */ + const char *diffopts = getenv("GIT_DIFF_OPTS"); + xpparam_t xpp; + xdemitconf_t xecfg; + xdemitcb_t ecb; + struct emit_callback ecbdata; + + ecbdata.label_path = label_path; + xpp.flags = XDF_NEED_MINIMAL; + xecfg.ctxlen = 3; + if (!diffopts) + ; + else if (!strncmp(diffopts, "--unified=", 10)) + xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10); + else if (!strncmp(diffopts, "-u", 2)) + xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10); + ecb.outf = fn_out; + ecb.priv = &ecbdata; + xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb); + } + + free(mf1.ptr); + free(mf2.ptr); + return NULL; } struct diff_filespec *alloc_filespec(const char *path) @@@ -463,8 -561,6 +561,8 @@@ void diff_free_filespec_data(struct dif munmap(s->data, s->size); s->should_free = s->should_munmap = 0; s->data = NULL; + free(s->cnt_data); + s->cnt_data = NULL; } static void prep_temp_blob(struct diff_tempfile *temp,