/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /* Copyright 2013-2021 The Libfossil Authors, see LICENSES/BSD-2-Clause.txt SPDX-License-Identifier: BSD-2-Clause-FreeBSD SPDX-FileCopyrightText: 2021 The Libfossil Authors SPDX-ArtifactOfProjectName: Libfossil SPDX-FileType: Code Heavily indebted to the Fossil SCM project (https://fossil-scm.org). ***************************************************************************** A simple tool for checking the change status of a checkout. */ #include "libfossil.h" #define MARKER(pfexp) \ do{ printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); \ printf pfexp; \ } while(0) static char const * fsl_ckout_change_label(fsl_ckout_change_e change){ switch(change){ case FSL_CKOUT_CHANGE_NONE: return NULL; case FSL_CKOUT_CHANGE_MOD: return "MODIFIED"; case FSL_CKOUT_CHANGE_MERGE_MOD: return "MERGE-MOD"; case FSL_CKOUT_CHANGE_MERGE_ADD: return "MERGE-ADD"; case FSL_CKOUT_CHANGE_INTEGRATE_MOD: return "INTEGRATE-MOD"; case FSL_CKOUT_CHANGE_INTEGRATE_ADD: return "INTEGRATE-ADD"; case FSL_CKOUT_CHANGE_ADDED: return "ADDED"; case FSL_CKOUT_CHANGE_REMOVED: return "REMOVED"; case FSL_CKOUT_CHANGE_MISSING: return "MISSING"; case FSL_CKOUT_CHANGE_RENAMED: return "RENAMED"; case FSL_CKOUT_CHANGE_IS_EXEC: return "+EXEC"; case FSL_CKOUT_CHANGE_NOT_EXEC: return "-EXEC"; case FSL_CKOUT_CHANGE_BECAME_SYMLINK: return "+SYMLINK"; case FSL_CKOUT_CHANGE_NOT_SYMLINK: return "-SYMLINK"; default: return "?!NO WAY!?"; } } /** A fsl_ckout_changes_f() impl which outputs change status to f_out(). */ static int fsl_ckout_changes_fapp(void * state, fsl_ckout_change_e change, char const * filename, char const * origName){ if(1==++*((int*)state)){ f_out("\nLocal changes compared to this version:\n\n"); } f_out("%-15s", fsl_ckout_change_label(change)); if(FSL_CKOUT_CHANGE_RENAMED==change){ assert(origName && *origName); f_out("%s\n%14s %s\n", origName, "->", filename); }else{ f_out("%s\n", filename); } return 0; } static int fapp_show_local_changes(fsl_cx * f, fsl_id_t vid, bool doScan){ int rc = 0; if(doScan) rc = fsl_ckout_changes_scan(f); if(!rc){ int counter = 0; rc = fsl_ckout_changes_visit(f, vid, 0, fsl_ckout_changes_fapp, &counter); if(!rc){ f_out("%s\n", counter ? "" : "\nNo local changes."); } } return rc; } int main(int argc, char const * const * argv ){ int rc = 0; fsl_cx * f = 0; fsl_db * db = 0; fsl_id_t rid = 0; bool skipFiles = false; bool useUtc = false; const char * zVersion = NULL; fsl_id_t ckoutRid = 0; bool skipVfileReset = false; fcli_cliflag FCliFlags[] = { FCLI_FLAG_BOOL("f","no-files",&skipFiles, "Disables the status check for local files."), FCLI_FLAG_BOOL(0,"utc",&useUtc, "Enables UTC timestamps (default is local time)."), FCLI_FLAG("v","version","version", &zVersion, "Shows info for the given version instead of the checkout."), FCLI_FLAG_BOOL(0,"no-reset", &skipVfileReset, "Is an internal debugging flag which tells this app " "not to re-set the vfile contents to be those of the current checkout. " "For compatibility with fossil(1), do not use it. It is only for testing."), fcli_cliflag_empty_m }; fcli_help_info FCliHelp = { "Outputs status info for the current checkout.", "", NULL }; fcli.cliFlags = FCliFlags; fcli.appHelp = &FCliHelp; rc = fcli_setup(argc, argv); if(rc) goto end; f = fcli_cx(); db = fsl_needs_ckout(f); if(!db){ rc = FSL_RC_NOT_A_CKOUT; goto end; } if(fcli_has_unused_args(false)) goto end; rc = fcli_fingerprint_check(true); if(rc) goto end; if(zVersion){ rc = fsl_sym_to_rid(f, zVersion, FSL_SATYPE_CHECKIN, &rid); if(rc) goto end; } if(!rid){ fsl_ckout_version_info(f, &ckoutRid, NULL); rid = ckoutRid; } if( !fsl_rid_is_a_checkin(f, rid) ) { rc = fcli_err_set(FSL_RC_RANGE, "%s does not refer to a checkin version.", zVersion ? zVersion : "RID"); goto end; } rc = fcli_ckout_show_info(useUtc); if(!rc && !skipFiles){ rc = fapp_show_local_changes(f, rid, !skipVfileReset); } end: return fcli_end_of_main(rc); }