From: Phillip Wood <phillip.wood123@gmail.com>
To: Abdullah <abdullahindo888@gmail.com>, git@vger.kernel.org
Subject: Re: changes for adding new features --snapshot,
Date: Fri, 19 Dec 2025 10:41:46 +0000 [thread overview]
Message-ID: <03034879-2d8e-4ab1-96ff-ff125e7d059e@gmail.com> (raw)
In-Reply-To: <CAG-pPd-4StfLAsassx-fqzavHJkAmi8P5UkgvqE3Yz-yGJ7GUw@mail.gmail.com>
It would be helpful if there was a commit message explaining what this
new feature is and why it is needed. There are some comments in the code
explaining what it does but not why it is useful. Given that a commit is
a snapshot of the working copy I'm not sure why you'd want to save an
additional copy. As the code comments indicate you have not tested this
code I wonder how you know that what you're proposing is useful.
Thanks
Phillip
On 18/12/2025 05:02, Abdullah wrote:
> ---
> 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
next prev parent reply other threads:[~2025-12-19 10:41 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-18 5:02 changes for adding new features --snapshot, Abdullah
2025-12-19 10:41 ` Phillip Wood [this message]
2025-12-19 11:05 ` Chris Torek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=03034879-2d8e-4ab1-96ff-ff125e7d059e@gmail.com \
--to=phillip.wood123@gmail.com \
--cc=abdullahindo888@gmail.com \
--cc=git@vger.kernel.org \
--cc=phillip.wood@dunelm.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.