---
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[<mode>]]
[--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 <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#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