From: Abdullah Date: Thu, 18 Dec 2025 05:02:32 GMT Subject: changes for adding new features --snapshot, Message-ID: --- builtin/commit.c | 2 + snapshot.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++ snapshot.h | 13 ++++++ 3 files changed, 123 insertions(+) create mode 100644 snapshot.c create mode 100644 snapshot.h diff --git a/builtin/commit.c b/builtin/commit.c index 0243f17d53..e880409be7 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -43,6 +43,7 @@ #include "commit-graph.h" #include "pretty.h" #include "trailer.h" +#include "snapshot.c" static const char * const builtin_commit_usage[] = { N_("git commit [-a | --interactive | --patch] [-s] [-v] [-u[]] [--amend]\n" @@ -1545,6 +1546,7 @@ struct repository *repo UNUSED) int fd; struct object_id oid; static struct option builtin_status_options[] = { + OPT_BOOLEAN(0, "snapshot", &opts.snapshot, "Create snapshot of staged files") OPT__VERBOSE(&verbose, N_("be verbose")), OPT_SET_INT('s', "short", &status_format, N_("show status concisely"), STATUS_FORMAT_SHORT), diff --git a/snapshot.c b/snapshot.c new file mode 100644 index 0000000000..8c117a7314 --- /dev/null +++ b/snapshot.c @@ -0,0 +1,108 @@ +#include "snapshot.h" +#include "run-command.h" +#include "strbuf.h" +#include "utf8.h" +#include +#include +#include +#include +#include +#include + +#define DEFAULT_SNAPSHOT_DIR ".git/snapshots" +/* +## Idea +The `--snapshot` flag would create a copy of all staged files in a timestamped folder before the commit is made. Users could configure the snapshot folder, defaulting to `.git/snapshots`. + +## Example Usage + +# Enable snapshot feature +git config snapshot.enable true + +# Optional: configure snapshot folder +git config snapshot.folder "../snapshots" + +# Stage files and commit with snapshot +git add . +git commit -m "Initial commit" --snapshot + +# Example snapshot folder created: +# ../snapshots/2025-12-17_14-30-00_Initial_commit/ + +# Notes: +these codes are never tested, I send it just to know if it fits to your development +*/ + +// Get snapshot folder from config, or fallback to default +static char *get_snapshot_dir(void) { + const char *cfg_dir = git_config_get_string("snapshot.folder"); + if (cfg_dir && *cfg_dir) + return strdup(cfg_dir); + return strdup(DEFAULT_SNAPSHOT_DIR); +} + +// Check if snapshot is enabled +int snapshot_enabled(void) { + const char *val = git_config_get_string("snapshot.enable"); + return val && strcmp(val, "true") == 0; +} + +// Get current timestamp for folder name +static void get_timestamp(char *buffer, size_t size) { + time_t now = time(NULL); + struct tm *tm_info = localtime(&now); + strftime(buffer, size, "%Y-%m-%d_%H-%M-%S", tm_info); +} + +// Create snapshot of staged files +int create_snapshot(const char *message) { + char timestamp[64]; + char snapshot_path[1024]; + + char *snapshot_dir = get_snapshot_dir(); + if (!snapshot_dir) { + fprintf(stderr, "Failed to get snapshot directory\n"); + return -1; + } + + // Ensure base folder exists + if (mkdir(snapshot_dir, 0755) != 0 && errno != EEXIST) { + perror("mkdir snapshot_dir"); + free(snapshot_dir); + return -1; + } + + get_timestamp(timestamp, sizeof(timestamp)); + + // Sanitize commit message + char sanitized_msg[512]; + snprintf(sanitized_msg, sizeof(sanitized_msg), "%s", message); + for (char *p = sanitized_msg; *p; p++) + if (*p == ' ') *p = '_'; + + // Create snapshot folder path + snprintf(snapshot_path, sizeof(snapshot_path), "%s/%s_%s", snapshot_dir, timestamp, sanitized_msg); + + if (mkdir(snapshot_path, 0755) != 0) { + perror("mkdir snapshot_path"); + free(snapshot_dir); + return -1; + } + + // Copy staged files + char cmd[2048]; + snprintf(cmd, sizeof(cmd), + "git diff --name-only --cached | xargs -I{} cp --parents {} \"%s\"", + snapshot_path); + + int ret = system(cmd); + if (ret != 0) { + fprintf(stderr, "Failed to copy staged files\n"); + free(snapshot_dir); + return -1; + } + + printf("Snapshot created at %s\n", snapshot_path); + free(snapshot_dir); + return 0; +} diff --git a/snapshot.h b/snapshot.h new file mode 100644 index 0000000000..7542538f1f --- /dev/null +++ b/snapshot.h @@ -0,0 +1,13 @@ +#ifndef SNAPSHOT_H +#define SNAPSHOT_H + +#include "cache.h" +#include "dir.h" + +// Check if snapshot feature is enabled +int snapshot_enabled(void); + +// Create snapshot of staged files with commit message +int create_snapshot(const char *message); + +#endif // SNAPSHOT_H -- 2.34.1