dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** Copyright (c) 2007 D. Richard Hipp dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This program is free software; you can redistribute it and/or dbda8d6ce9 2007-07-21 drh: ** modify it under the terms of the GNU General Public dbda8d6ce9 2007-07-21 drh: ** License version 2 as published by the Free Software Foundation. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This program is distributed in the hope that it will be useful, dbda8d6ce9 2007-07-21 drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of dbda8d6ce9 2007-07-21 drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dbda8d6ce9 2007-07-21 drh: ** General Public License for more details. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** You should have received a copy of the GNU General Public dbda8d6ce9 2007-07-21 drh: ** License along with this library; if not, write to the dbda8d6ce9 2007-07-21 drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, dbda8d6ce9 2007-07-21 drh: ** Boston, MA 02111-1307, USA. dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** Author contact information: dbda8d6ce9 2007-07-21 drh: ** drh@hwaci.com dbda8d6ce9 2007-07-21 drh: ** http://www.hwaci.com/drh/ dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ******************************************************************************* dbda8d6ce9 2007-07-21 drh: ** dbda8d6ce9 2007-07-21 drh: ** This file contains code used to implement the "diff" command dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: #include "config.h" dbda8d6ce9 2007-07-21 drh: #include "diffcmd.h" dbda8d6ce9 2007-07-21 drh: #include <assert.h> dbda8d6ce9 2007-07-21 drh: dbda8d6ce9 2007-07-21 drh: /* dbda8d6ce9 2007-07-21 drh: ** Shell-escape the given string. Append the result to a blob. dbda8d6ce9 2007-07-21 drh: */ dbda8d6ce9 2007-07-21 drh: static void shell_escape(Blob *pBlob, const char *zIn){ dbda8d6ce9 2007-07-21 drh: int n = blob_size(pBlob); dbda8d6ce9 2007-07-21 drh: int k = strlen(zIn); c863ec1a98 2008-10-21 drh: int i, c; dbda8d6ce9 2007-07-21 drh: char *z; c863ec1a98 2008-10-21 drh: for(i=0; (c = zIn[i])!=0; i++){ c863ec1a98 2008-10-21 drh: if( isspace(c) || c=='"' || (c=='\\' && zIn[i+1]!=0) ){ c863ec1a98 2008-10-21 drh: blob_appendf(pBlob, "\"%s\"", zIn); c863ec1a98 2008-10-21 drh: z = blob_buffer(pBlob); c863ec1a98 2008-10-21 drh: for(i=n+1; i<=n+k; i++){ c863ec1a98 2008-10-21 drh: if( z[i]=='"' ) z[i] = '_'; dbda8d6ce9 2007-07-21 drh: } c863ec1a98 2008-10-21 drh: return; dbda8d6ce9 2007-07-21 drh: } dbda8d6ce9 2007-07-21 drh: } c863ec1a98 2008-10-21 drh: blob_append(pBlob, zIn, -1); c863ec1a98 2008-10-21 drh: } c863ec1a98 2008-10-21 drh: c863ec1a98 2008-10-21 drh: /* 0eb08b860c 2009-09-16 drh: ** This function implements a cross-platform "system()" interface. 0eb08b860c 2009-09-16 drh: */ 0eb08b860c 2009-09-16 drh: int portable_system(char *zOrigCmd){ 0eb08b860c 2009-09-16 drh: int rc; 0eb08b860c 2009-09-16 drh: #ifdef __MINGW32__ 0eb08b860c 2009-09-16 drh: /* On windows, we have to put double-quotes around the entire command. 0eb08b860c 2009-09-16 drh: ** Who knows why - this is just the way windows works. 0eb08b860c 2009-09-16 drh: */ 0eb08b860c 2009-09-16 drh: char *zNewCmd = mprintf("\"%s\"", zOrigCmd); 0eb08b860c 2009-09-16 drh: rc = system(zNewCmd); 0eb08b860c 2009-09-16 drh: free(zNewCmd); 0eb08b860c 2009-09-16 drh: #else 0eb08b860c 2009-09-16 drh: /* On unix, evaluate the command directly. 0eb08b860c 2009-09-16 drh: */ 0eb08b860c 2009-09-16 drh: rc = system(zOrigCmd); 0eb08b860c 2009-09-16 drh: #endif 0eb08b860c 2009-09-16 drh: return rc; c82fb61775 2007-09-24 jnc: } c82fb61775 2007-09-24 jnc: c82fb61775 2007-09-24 jnc: /* a51808c0a5 2009-11-06 drh: ** Show the difference between two files, one in memory and one on disk. c82fb61775 2007-09-24 jnc: ** a51808c0a5 2009-11-06 drh: ** The difference is the set of edits needed to transform pFile1 into a51808c0a5 2009-11-06 drh: ** zFile2. The content of pFile1 is in memory. zFile2 exists on disk. c82fb61775 2007-09-24 jnc: ** a51808c0a5 2009-11-06 drh: ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the a51808c0a5 2009-11-06 drh: ** command zDiffCmd to do the diffing. c82fb61775 2007-09-24 jnc: */ a51808c0a5 2009-11-06 drh: static void diff_file( a51808c0a5 2009-11-06 drh: Blob *pFile1, /* In memory content to compare from */ a51808c0a5 2009-11-06 drh: const char *zFile2, /* On disk content to compare to */ a51808c0a5 2009-11-06 drh: const char *zName, /* Display name of the file */ a51808c0a5 2009-11-06 drh: const char *zDiffCmd /* Command for comparison */ a51808c0a5 2009-11-06 drh: ){ a51808c0a5 2009-11-06 drh: if( zDiffCmd==0 ){ a51808c0a5 2009-11-06 drh: Blob out; /* Diff output text */ a51808c0a5 2009-11-06 drh: Blob file2; /* Content of zFile2 */ a51808c0a5 2009-11-06 drh: a51808c0a5 2009-11-06 drh: /* Read content of zFile2 into memory */ a51808c0a5 2009-11-06 drh: blob_zero(&file2); a51808c0a5 2009-11-06 drh: blob_read_from_file(&file2, zFile2); a51808c0a5 2009-11-06 drh: a51808c0a5 2009-11-06 drh: /* Compute and output the differences */ a51808c0a5 2009-11-06 drh: blob_zero(&out); a51808c0a5 2009-11-06 drh: text_diff(pFile1, &file2, &out, 5); a51808c0a5 2009-11-06 drh: printf("--- %s\n+++ %s\n", zName, zName); a51808c0a5 2009-11-06 drh: printf("%s\n", blob_str(&out)); a51808c0a5 2009-11-06 drh: a51808c0a5 2009-11-06 drh: /* Release memory resources */ a51808c0a5 2009-11-06 drh: blob_reset(&file2); a51808c0a5 2009-11-06 drh: blob_reset(&out); a51808c0a5 2009-11-06 drh: }else{ dbda8d6ce9 2007-07-21 drh: int cnt = 0; a51808c0a5 2009-11-06 drh: Blob nameFile1; /* Name of temporary file to old pFile1 content */ a51808c0a5 2009-11-06 drh: Blob cmd; /* Text of command to run */ a51808c0a5 2009-11-06 drh: a51808c0a5 2009-11-06 drh: /* Construct a temporary file to hold pFile1 based on the name of a51808c0a5 2009-11-06 drh: ** zFile2 */ a51808c0a5 2009-11-06 drh: blob_zero(&nameFile1); dbda8d6ce9 2007-07-21 drh: do{ a51808c0a5 2009-11-06 drh: blob_reset(&nameFile1); a51808c0a5 2009-11-06 drh: blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++); a51808c0a5 2009-11-06 drh: }while( access(blob_str(&nameFile1),0)==0 ); a51808c0a5 2009-11-06 drh: blob_write_to_file(pFile1, blob_str(&nameFile1)); a51808c0a5 2009-11-06 drh: a51808c0a5 2009-11-06 drh: /* Construct the external diff command */ 574763bab9 2007-09-26 jnc: blob_zero(&cmd); a51808c0a5 2009-11-06 drh: blob_appendf(&cmd, "%s ", zDiffCmd); a51808c0a5 2009-11-06 drh: shell_escape(&cmd, blob_str(&nameFile1)); a51808c0a5 2009-11-06 drh: blob_append(&cmd, " ", 1); a51808c0a5 2009-11-06 drh: shell_escape(&cmd, zFile2); a51808c0a5 2009-11-06 drh: a51808c0a5 2009-11-06 drh: /* Run the external diff command */ a51808c0a5 2009-11-06 drh: portable_system(blob_str(&cmd)); a51808c0a5 2009-11-06 drh: a51808c0a5 2009-11-06 drh: /* Delete the temporary file and clean up memory used */ a51808c0a5 2009-11-06 drh: unlink(blob_str(&nameFile1)); a51808c0a5 2009-11-06 drh: blob_reset(&nameFile1); a51808c0a5 2009-11-06 drh: blob_reset(&cmd); 574763bab9 2007-09-26 jnc: } a51808c0a5 2009-11-06 drh: } a51808c0a5 2009-11-06 drh: a51808c0a5 2009-11-06 drh: /* fe8bb01d38 2009-11-06 drh: ** Show the difference between two files, both in memory. fe8bb01d38 2009-11-06 drh: ** fe8bb01d38 2009-11-06 drh: ** The difference is the set of edits needed to transform pFile1 into fe8bb01d38 2009-11-06 drh: ** pFile2. fe8bb01d38 2009-11-06 drh: ** fe8bb01d38 2009-11-06 drh: ** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the fe8bb01d38 2009-11-06 drh: ** command zDiffCmd to do the diffing. fe8bb01d38 2009-11-06 drh: */ fe8bb01d38 2009-11-06 drh: static void diff_file_mem( fe8bb01d38 2009-11-06 drh: Blob *pFile1, /* In memory content to compare from */ fe8bb01d38 2009-11-06 drh: Blob *pFile2, /* In memory content to compare to */ fe8bb01d38 2009-11-06 drh: const char *zName, /* Display name of the file */ fe8bb01d38 2009-11-06 drh: const char *zDiffCmd /* Command for comparison */ fe8bb01d38 2009-11-06 drh: ){ fe8bb01d38 2009-11-06 drh: if( zDiffCmd==0 ){ fe8bb01d38 2009-11-06 drh: Blob out; /* Diff output text */ fe8bb01d38 2009-11-06 drh: 574763bab9 2007-09-26 jnc: blob_zero(&out); fe8bb01d38 2009-11-06 drh: text_diff(pFile1, pFile2, &out, 5); fe8bb01d38 2009-11-06 drh: printf("--- %s\n+++ %s\n", zName, zName); 574763bab9 2007-09-26 jnc: printf("%s\n", blob_str(&out)); fe8bb01d38 2009-11-06 drh: fe8bb01d38 2009-11-06 drh: /* Release memory resources */ 574763bab9 2007-09-26 jnc: blob_reset(&out); 574763bab9 2007-09-26 jnc: }else{ fe8bb01d38 2009-11-06 drh: Blob cmd; fe8bb01d38 2009-11-06 drh: char zTemp1[300]; fe8bb01d38 2009-11-06 drh: char zTemp2[300]; fe8bb01d38 2009-11-06 drh: fe8bb01d38 2009-11-06 drh: /* Construct a temporary file names */ fe8bb01d38 2009-11-06 drh: file_tempname(sizeof(zTemp1), zTemp1); fe8bb01d38 2009-11-06 drh: file_tempname(sizeof(zTemp2), zTemp2); fe8bb01d38 2009-11-06 drh: blob_write_to_file(pFile1, zTemp1); fe8bb01d38 2009-11-06 drh: blob_write_to_file(pFile2, zTemp2); fe8bb01d38 2009-11-06 drh: fe8bb01d38 2009-11-06 drh: /* Construct the external diff command */ fe8bb01d38 2009-11-06 drh: blob_zero(&cmd); fe8bb01d38 2009-11-06 drh: blob_appendf(&cmd, "%s ", zDiffCmd); fe8bb01d38 2009-11-06 drh: shell_escape(&cmd, zTemp1); c863ec1a98 2008-10-21 drh: blob_append(&cmd, " ", 1); fe8bb01d38 2009-11-06 drh: shell_escape(&cmd, zTemp2); fe8bb01d38 2009-11-06 drh: fe8bb01d38 2009-11-06 drh: /* Run the external diff command */ fe8bb01d38 2009-11-06 drh: portable_system(blob_str(&cmd)); fe8bb01d38 2009-11-06 drh: fe8bb01d38 2009-11-06 drh: /* Delete the temporary file and clean up memory used */ fe8bb01d38 2009-11-06 drh: unlink(zTemp1); fe8bb01d38 2009-11-06 drh: unlink(zTemp2); dbda8d6ce9 2007-07-21 drh: blob_reset(&cmd); 574763bab9 2007-09-26 jnc: } fe8bb01d38 2009-11-06 drh: } fe8bb01d38 2009-11-06 drh: fe8bb01d38 2009-11-06 drh: /* a51808c0a5 2009-11-06 drh: ** Do a diff against a single file named in g.argv[2] from version zFrom a51808c0a5 2009-11-06 drh: ** against the same file on disk. a51808c0a5 2009-11-06 drh: */ a51808c0a5 2009-11-06 drh: static void diff_one_against_disk(const char *zFrom, const char *zDiffCmd){ a51808c0a5 2009-11-06 drh: Blob fname; a51808c0a5 2009-11-06 drh: Blob content; a51808c0a5 2009-11-06 drh: file_tree_name(g.argv[2], &fname, 1); 7b82a73bd3 2009-12-17 drh: historical_version_of_file(zFrom, blob_str(&fname), &content, 0); a51808c0a5 2009-11-06 drh: diff_file(&content, g.argv[2], g.argv[2], zDiffCmd); a51808c0a5 2009-11-06 drh: blob_reset(&content); a51808c0a5 2009-11-06 drh: blob_reset(&fname); a51808c0a5 2009-11-06 drh: } a51808c0a5 2009-11-06 drh: a51808c0a5 2009-11-06 drh: /* a51808c0a5 2009-11-06 drh: ** Run a diff between the version zFrom and files on disk. zFrom might a51808c0a5 2009-11-06 drh: ** be NULL which means to simply show the difference between the edited a51808c0a5 2009-11-06 drh: ** files on disk and the check-out on which they are based. a51808c0a5 2009-11-06 drh: */ a51808c0a5 2009-11-06 drh: static void diff_all_against_disk(const char *zFrom, const char *zDiffCmd){ a51808c0a5 2009-11-06 drh: int vid; a51808c0a5 2009-11-06 drh: Blob sql; a51808c0a5 2009-11-06 drh: Stmt q; c863ec1a98 2008-10-21 drh: a51808c0a5 2009-11-06 drh: vid = db_lget_int("checkout", 0); 76f169fca6 2009-12-18 drh: vfile_check_signature(vid, 1); a51808c0a5 2009-11-06 drh: blob_zero(&sql); a51808c0a5 2009-11-06 drh: db_begin_transaction(); a51808c0a5 2009-11-06 drh: if( zFrom ){ a51808c0a5 2009-11-06 drh: int rid = name_to_rid(zFrom); a51808c0a5 2009-11-06 drh: if( !is_a_version(rid) ){ a51808c0a5 2009-11-06 drh: fossil_fatal("no such check-in: %s", zFrom); c82fb61775 2007-09-24 jnc: } a51808c0a5 2009-11-06 drh: load_vfile_from_rid(rid); a51808c0a5 2009-11-06 drh: blob_appendf(&sql, a51808c0a5 2009-11-06 drh: "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid" a51808c0a5 2009-11-06 drh: " FROM vfile v1, vfile v2 " a51808c0a5 2009-11-06 drh: " WHERE v1.pathname=v2.pathname AND v1.vid=%d AND v2.vid=%d" db608ee72f 2009-11-06 drh: " AND (v2.deleted OR v2.chnged OR v1.rid!=v2.rid)" a51808c0a5 2009-11-06 drh: "UNION " a51808c0a5 2009-11-06 drh: "SELECT pathname, 1, 0, 0, 0" a51808c0a5 2009-11-06 drh: " FROM vfile v1" a51808c0a5 2009-11-06 drh: " WHERE v1.vid=%d" a51808c0a5 2009-11-06 drh: " AND NOT EXISTS(SELECT 1 FROM vfile v2" a51808c0a5 2009-11-06 drh: " WHERE v2.vid=%d AND v2.pathname=v1.pathname)" a51808c0a5 2009-11-06 drh: "UNION " a51808c0a5 2009-11-06 drh: "SELECT pathname, 0, 0, 1, 0" a51808c0a5 2009-11-06 drh: " FROM vfile v2" a51808c0a5 2009-11-06 drh: " WHERE v2.vid=%d" a51808c0a5 2009-11-06 drh: " AND NOT EXISTS(SELECT 1 FROM vfile v1" a51808c0a5 2009-11-06 drh: " WHERE v1.vid=%d AND v1.pathname=v2.pathname)" a51808c0a5 2009-11-06 drh: " ORDER BY 1", a51808c0a5 2009-11-06 drh: rid, vid, rid, vid, vid, rid a51808c0a5 2009-11-06 drh: ); dbda8d6ce9 2007-07-21 drh: }else{ a51808c0a5 2009-11-06 drh: blob_appendf(&sql, a51808c0a5 2009-11-06 drh: "SELECT pathname, deleted, chnged , rid==0, rid" a51808c0a5 2009-11-06 drh: " FROM vfile" a51808c0a5 2009-11-06 drh: " WHERE vid=%d" a51808c0a5 2009-11-06 drh: " AND (deleted OR chnged OR rid==0)" a51808c0a5 2009-11-06 drh: " ORDER BY pathname", a51808c0a5 2009-11-06 drh: vid a51808c0a5 2009-11-06 drh: ); a51808c0a5 2009-11-06 drh: } a51808c0a5 2009-11-06 drh: db_prepare(&q, blob_str(&sql)); c863ec1a98 2008-10-21 drh: while( db_step(&q)==SQLITE_ROW ){ c863ec1a98 2008-10-21 drh: const char *zPathname = db_column_text(&q,0); c863ec1a98 2008-10-21 drh: int isDeleted = db_column_int(&q, 1); c863ec1a98 2008-10-21 drh: int isChnged = db_column_int(&q,2); a51808c0a5 2009-11-06 drh: int isNew = db_column_int(&q,3); a51808c0a5 2009-11-06 drh: char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); c863ec1a98 2008-10-21 drh: if( isDeleted ){ c863ec1a98 2008-10-21 drh: printf("DELETED %s\n", zPathname); c863ec1a98 2008-10-21 drh: }else if( access(zFullName, 0) ){ c863ec1a98 2008-10-21 drh: printf("MISSING %s\n", zPathname); c863ec1a98 2008-10-21 drh: }else if( isNew ){ c863ec1a98 2008-10-21 drh: printf("ADDED %s\n", zPathname); c863ec1a98 2008-10-21 drh: }else if( isDeleted ){ c863ec1a98 2008-10-21 drh: printf("DELETED %s\n", zPathname); c863ec1a98 2008-10-21 drh: }else if( isChnged==3 ){ c863ec1a98 2008-10-21 drh: printf("ADDED_BY_MERGE %s\n", zPathname); c863ec1a98 2008-10-21 drh: }else{ a51808c0a5 2009-11-06 drh: int srcid = db_column_int(&q, 4); a51808c0a5 2009-11-06 drh: Blob content; a51808c0a5 2009-11-06 drh: content_get(srcid, &content); 85670cfcc8 2008-10-24 drh: printf("Index: %s\n=======================================" 85670cfcc8 2008-10-24 drh: "============================\n", 85670cfcc8 2008-10-24 drh: zPathname 85670cfcc8 2008-10-24 drh: ); a51808c0a5 2009-11-06 drh: diff_file(&content, zFullName, zPathname, zDiffCmd); a51808c0a5 2009-11-06 drh: blob_reset(&content); c863ec1a98 2008-10-21 drh: } c863ec1a98 2008-10-21 drh: free(zFullName); dbda8d6ce9 2007-07-21 drh: } c863ec1a98 2008-10-21 drh: db_finalize(&q); a51808c0a5 2009-11-06 drh: db_end_transaction(1); a51808c0a5 2009-11-06 drh: } a51808c0a5 2009-11-06 drh: fe8bb01d38 2009-11-06 drh: /* fe8bb01d38 2009-11-06 drh: ** Output the differences between two versions of a single file. fe8bb01d38 2009-11-06 drh: ** zFrom and zTo are the check-ins containing the two file versions. fe8bb01d38 2009-11-06 drh: ** The filename is contained in g.argv[2]. fe8bb01d38 2009-11-06 drh: */ fe8bb01d38 2009-11-06 drh: static void diff_one_two_versions( fe8bb01d38 2009-11-06 drh: const char *zFrom, fe8bb01d38 2009-11-06 drh: const char *zTo, fe8bb01d38 2009-11-06 drh: const char *zDiffCmd fe8bb01d38 2009-11-06 drh: ){ fe8bb01d38 2009-11-06 drh: char *zName; fe8bb01d38 2009-11-06 drh: Blob fname; fe8bb01d38 2009-11-06 drh: Blob v1, v2; fe8bb01d38 2009-11-06 drh: file_tree_name(g.argv[2], &fname, 1); fe8bb01d38 2009-11-06 drh: zName = blob_str(&fname); 7b82a73bd3 2009-12-17 drh: historical_version_of_file(zFrom, zName, &v1, 0); 7b82a73bd3 2009-12-17 drh: historical_version_of_file(zTo, zName, &v2, 0); fe8bb01d38 2009-11-06 drh: diff_file_mem(&v1, &v2, zName, zDiffCmd); fe8bb01d38 2009-11-06 drh: blob_reset(&v1); fe8bb01d38 2009-11-06 drh: blob_reset(&v2); dbda8d6ce9 2007-07-21 drh: blob_reset(&fname); fe8bb01d38 2009-11-06 drh: } a51808c0a5 2009-11-06 drh: fe8bb01d38 2009-11-06 drh: /* fe8bb01d38 2009-11-06 drh: ** Output the differences between two check-ins. fe8bb01d38 2009-11-06 drh: */ fe8bb01d38 2009-11-06 drh: static void diff_all_two_versions( fe8bb01d38 2009-11-06 drh: const char *zFrom, fe8bb01d38 2009-11-06 drh: const char *zTo, fe8bb01d38 2009-11-06 drh: const char *zDiffCmd fe8bb01d38 2009-11-06 drh: ){ c863ec1a98 2008-10-21 drh: } c863ec1a98 2008-10-21 drh: c863ec1a98 2008-10-21 drh: /* c863ec1a98 2008-10-21 drh: ** COMMAND: diff c863ec1a98 2008-10-21 drh: ** COMMAND: gdiff c863ec1a98 2008-10-21 drh: ** a51808c0a5 2009-11-06 drh: ** Usage: %fossil diff|gdiff ?options? ?FILE? c863ec1a98 2008-10-21 drh: ** a51808c0a5 2009-11-06 drh: ** Show the difference between the current version of FILE (as it a51808c0a5 2009-11-06 drh: ** exists on disk) and that same file as it was checked out. Or a51808c0a5 2009-11-06 drh: ** if the FILE argument is omitted, show the unsaved changed currently a51808c0a5 2009-11-06 drh: ** in the working check-out. c863ec1a98 2008-10-21 drh: ** a51808c0a5 2009-11-06 drh: ** If the "--from VERSION" or "-r VERSION" option is used it specifies a51808c0a5 2009-11-06 drh: ** the source check-in for the diff operation. If not specified, the a51808c0a5 2009-11-06 drh: ** source check-in is the base check-in for the current check-out. c863ec1a98 2008-10-21 drh: ** a51808c0a5 2009-11-06 drh: ** If the "--to VERSION" option appears, it specifies the check-in from a51808c0a5 2009-11-06 drh: ** which the second version of the file or files is taken. If there is a51808c0a5 2009-11-06 drh: ** no "--to" option then the (possibly edited) files in the current check-out a51808c0a5 2009-11-06 drh: ** are used. c863ec1a98 2008-10-21 drh: ** a51808c0a5 2009-11-06 drh: ** The "-i" command-line option forces the use of the internal diff logic a51808c0a5 2009-11-06 drh: ** rather than any external diff program that might be configured using a51808c0a5 2009-11-06 drh: ** the "setting" command. If no external diff program is configured, then a51808c0a5 2009-11-06 drh: ** the "-i" option is a no-op. The "-i" option converts "gdiff" into "diff". c863ec1a98 2008-10-21 drh: */ c863ec1a98 2008-10-21 drh: void diff_cmd(void){ 85670cfcc8 2008-10-24 drh: int isGDiff; /* True for gdiff. False for normal diff */ a51808c0a5 2009-11-06 drh: int isInternDiff; /* True for internal diff */ a51808c0a5 2009-11-06 drh: const char *zFrom; /* Source version number */ a51808c0a5 2009-11-06 drh: const char *zTo; /* Target version number */ a51808c0a5 2009-11-06 drh: const char *zDiffCmd = 0; /* External diff command. NULL for internal diff */ c863ec1a98 2008-10-21 drh: 85670cfcc8 2008-10-24 drh: isGDiff = g.argv[1][0]=='g'; a51808c0a5 2009-11-06 drh: isInternDiff = find_option("internal","i",0)!=0; a51808c0a5 2009-11-06 drh: zFrom = find_option("from", "r", 1); a51808c0a5 2009-11-06 drh: zTo = find_option("to", 0, 1); c863ec1a98 2008-10-21 drh: a51808c0a5 2009-11-06 drh: if( zTo==0 ){ a51808c0a5 2009-11-06 drh: db_must_be_within_tree(); db608ee72f 2009-11-06 drh: verify_all_options(); db608ee72f 2009-11-06 drh: if( !isInternDiff && g.argc==3 ){ a51808c0a5 2009-11-06 drh: zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0); a51808c0a5 2009-11-06 drh: } a51808c0a5 2009-11-06 drh: if( g.argc==3 ){ a51808c0a5 2009-11-06 drh: diff_one_against_disk(zFrom, zDiffCmd); 85670cfcc8 2008-10-24 drh: }else{ a51808c0a5 2009-11-06 drh: diff_all_against_disk(zFrom, zDiffCmd); a51808c0a5 2009-11-06 drh: } a51808c0a5 2009-11-06 drh: }else if( zFrom==0 ){ a51808c0a5 2009-11-06 drh: fossil_fatal("must use --from if --to is present"); a51808c0a5 2009-11-06 drh: }else{ a51808c0a5 2009-11-06 drh: db_find_and_open_repository(1); db608ee72f 2009-11-06 drh: verify_all_options(); db608ee72f 2009-11-06 drh: if( !isInternDiff && g.argc==3 ){ a51808c0a5 2009-11-06 drh: zDiffCmd = db_get(isGDiff ? "gdiff-command" : "diff-command", 0); 85670cfcc8 2008-10-24 drh: } a51808c0a5 2009-11-06 drh: if( g.argc==3 ){ a51808c0a5 2009-11-06 drh: diff_one_two_versions(zFrom, zTo, zDiffCmd); c863ec1a98 2008-10-21 drh: }else{ fe8bb01d38 2009-11-06 drh: fossil_fatal("--to on complete check-ins not yet implemented"); a51808c0a5 2009-11-06 drh: diff_all_two_versions(zFrom, zTo, zDiffCmd); c863ec1a98 2008-10-21 drh: } 129edda98e 2009-09-11 drh: } dbda8d6ce9 2007-07-21 drh: }