Skip to content

Commit

Permalink
attach: introduce new built-in cmd git-attach
Browse files Browse the repository at this point in the history
The `git attach` built-in command is used to create, update, delete,
view, download attachments related to a commit, etc.

An attachment can be any regular file. The idea comes from that the
emails contain metadata (subject, sender, recipient, body, etc.) and
additional data (attachments), both of which have their own uses, and
sometimes we can write one that contains both. Attachments are usually
relatively larger. Users can whether or not to download and view
attachments by their purpose.

Just like the analogy to the email above, there are similar scenarios in
git, some files we don't want to save directly to the commit itself. In
addition, the mapping between the attachments and the commit is
established by associating a git REF (inspired from `git notes`), so
that the commit itself will not be overwritten if the attachements occur
changes. For those who do not care about attachments, git generates
behaves the same as before. Those who pay attention to the attachment
can manage and maintain it by `git attach` subcommands or new options to
existing commands in the future, for example

         $ git commit --attach foobar.bin

Compared with using the attachment file directly as the BLOB object
referenced by commits, you can clone or pull the code repository more
quickly, whether you pay attention to the attachment or not. If you want
to download/modify/add the attachment on a commit when you need, you can
download the attachements at any time. This has broad significance in
common scenarios, such as AI training codes with large models, tesing
codes with test datasets, front-end codes with design materials, etc.

Another solution we are familiar with is git lfs. By hooking and
rewriting commit (using a pointer file to associate the lfs object), it
can host the lfs object on an file storage service, thereby achieving
excellent large file storage decoupling capabilities. Both git lfs and
git attach can be used as solutions for large file storage, but there
are 3 main differences between them:

    1. The attachment object stored by git attach is still stored in the
    git repository, just another reference. If the user does not want to
    clone and fetch these attachments, they do not need to download
    these references, so the efficiency in pull speed is the same as git
    lfs is similar.

    2. Another difference is that git lfs needs to be installed on the
    first step, while git attach is designed as one of the native git
    commands. It does not rely on external file storage services and
    uses the existing objects and reference mechanisms within git core.

    3. Another is that git lfs is designed as a solution for storing
    large files. The effective file range is defined through git
    attributes, while git attach is designed to store any file, large or
    small, of any type. The concern is whether you want to store the
    files separately from the code, not just the file size.

Signed-off-by: Teng Long <[email protected]>
  • Loading branch information
dyrone committed Nov 14, 2023
1 parent e0939be commit ea33355
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
/git-apply
/git-archimport
/git-archive
/git-attach
/git-bisect
/git-blame
/git-branch
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,7 @@ BUILTIN_OBJS += builtin/am.o
BUILTIN_OBJS += builtin/annotate.o
BUILTIN_OBJS += builtin/apply.o
BUILTIN_OBJS += builtin/archive.o
BUILTIN_OBJS += builtin/attach.o
BUILTIN_OBJS += builtin/bisect.o
BUILTIN_OBJS += builtin/blame.o
BUILTIN_OBJS += builtin/branch.o
Expand Down
1 change: 1 addition & 0 deletions builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ int cmd_am(int argc, const char **argv, const char *prefix);
int cmd_annotate(int argc, const char **argv, const char *prefix);
int cmd_apply(int argc, const char **argv, const char *prefix);
int cmd_archive(int argc, const char **argv, const char *prefix);
int cmd_attach(int argc, const char **argv, const char *prefix);
int cmd_bisect(int argc, const char **argv, const char *prefix);
int cmd_blame(int argc, const char **argv, const char *prefix);
int cmd_branch(int argc, const char **argv, const char *prefix);
Expand Down
7 changes: 7 additions & 0 deletions builtin/attach.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "builtin.h"
#include "gettext.h"

int cmd_attach(int argc, const char **argv, const char *prefix)
{
return error(_("subcommand `%s' not implement yet"), argv[0]);
}
1 change: 1 addition & 0 deletions command-list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ git-annotate ancillaryinterrogators
git-apply plumbingmanipulators complete
git-archimport foreignscminterface
git-archive mainporcelain
git-attach mainporcelain
git-bisect mainporcelain info
git-blame ancillaryinterrogators complete
git-branch mainporcelain history
Expand Down
1 change: 1 addition & 0 deletions git.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ static struct cmd_struct commands[] = {
{ "annotate", cmd_annotate, RUN_SETUP },
{ "apply", cmd_apply, RUN_SETUP_GENTLY },
{ "archive", cmd_archive, RUN_SETUP_GENTLY },
{ "attach", cmd_attach, RUN_SETUP },
{ "bisect", cmd_bisect, RUN_SETUP },
{ "blame", cmd_blame, RUN_SETUP },
{ "branch", cmd_branch, RUN_SETUP | DELAY_PAGER_CONFIG },
Expand Down

0 comments on commit ea33355

Please sign in to comment.