{"thread":{"id":"2792","subject":"[PATCH] Allow updating the index from a pipe","startedAt":"2005-12-10T06:57:05Z","lastAt":"2005-12-10T07:12:05Z","messageCount":3,"participants":["Daniel Barkalow","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"13429","messageId":"Pine.LNX.4.64.0512100145500.25300@iabervon.org","threadId":"2792","inReplyTo":null,"subject":"[PATCH] Allow updating the index from a pipe","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-12-10T06:57:05Z","receivedAt":"2005-12-10T06:57:05Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"In order to allow the index to be modified in simple ways without\nhaving a working tree, this adds an option to git-update-index which\nupdates a single path with a mode of 100644 and reads the content from\nstdin. Somebody should probably give the option a better name.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n\n---\n\nThis is for a git-backed wiki I'm writing, which doesn't want to use a \nworking tree when preparing changes, but wants to work entirely with pipes \nand index files.\n\n Documentation/git-update-index.txt |    7 ++++++\n cache.h                            |    1 +\n sha1_file.c                        |   27 ++++++++++++++++++++++++\n update-index.c                     |   40 +++++++++++++++++++++++++++++++++++-\n 4 files changed, 74 insertions(+), 1 deletions(-)\n\n7883add98deb548c7c10681ae3d71b7a7d949a9a\ndiff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt\nindex e4678cd..d35340a 100644\n--- a/Documentation/git-update-index.txt\n+++ b/Documentation/git-update-index.txt\n@@ -14,6 +14,7 @@ SYNOPSIS\n \t     [--cacheinfo <mode> <object> <file>]\\*\n \t     [--chmod=(+|-)x]\n \t     [--info-only] [--index-info]\n+\t     [--name=<file>]\n \t     [-z] [--stdin]\n \t     [--verbose]\n \t     [--] [<file>]\\*\n@@ -87,6 +88,12 @@ OPTIONS\n \tread list of paths from the standard input.  Paths are\n \tseparated by LF (i.e. one path per line) by default.\n \n+--name=<file>:: \n+\tInstead of taking a list of paths, only operate on a single\n+\tpath, and get the content from the standard input instead of\n+\tfrom the file system.  The mode for the file will be 100644\n+\t(regular non-executable file).\n+\n --verbose::\n         Report what is being added and removed from index.\n \ndiff --git a/cache.h b/cache.h\nindex 86fc250..1b30f44 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -144,6 +144,7 @@ extern int ce_match_stat(struct cache_en\n extern int ce_modified(struct cache_entry *ce, struct stat *st);\n extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);\n extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, const char *type);\n+extern int index_pipe(unsigned char *sha1, int fd, const char *type);\n extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);\n extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);\n \ndiff --git a/sha1_file.c b/sha1_file.c\nindex 111a71d..0073187 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1528,6 +1528,33 @@ int has_sha1_file(const unsigned char *s\n \treturn find_sha1_file(sha1, &st) ? 1 : 0;\n }\n \n+int index_pipe(unsigned char *sha1, int fd, const char *type)\n+{\n+\tunsigned long size = 4096;\n+\tchar *buf = malloc(size);\n+\tint iret, ret;\n+\tunsigned long off = 0;\n+\tdo {\n+\t\tiret = read(fd, buf + off, size - off);\n+\t\tif (iret > 0) {\n+\t\t\toff += iret;\n+\t\t\tif (off == size) {\n+\t\t\t\tsize *= 2;\n+\t\t\t\tbuf = realloc(buf, size);\n+\t\t\t}\n+\t\t}\n+\t} while (iret > 0);\n+\tif (iret < 0) {\n+\t\tfree(buf);\n+\t\treturn -1;\n+\t}\n+\tif (!type)\n+\t\ttype = \"blob\";\n+\tret = write_sha1_file(buf, off, type, sha1);\n+\tfree(buf);\n+\treturn ret;\n+}\n+\n int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, const char *type)\n {\n \tunsigned long size = st->st_size;\ndiff --git a/update-index.c b/update-index.c\nindex 11b7f6a..f3d79af 100644\n--- a/update-index.c\n+++ b/update-index.c\n@@ -24,6 +24,8 @@ static int info_only;\n static int force_remove;\n static int verbose;\n \n+static char *single_name = NULL;\n+\n /* Three functions to allow overloaded pointer return; see linux/err.h */\n static inline void *ERR_PTR(long error)\n {\n@@ -117,6 +119,33 @@ static int add_file_to_cache(const char \n \treturn 0;\n }\n \n+\n+static int add_stdin_to_cache(const char *path)\n+{\n+\tint size, namelen, option;\n+\tstruct cache_entry *ce;\n+\tstruct stat st;\n+\n+\tnamelen = strlen(path);\n+\tsize = cache_entry_size(namelen);\n+\tce = xmalloc(size);\n+\tmemset(ce, 0, size);\n+\tmemcpy(ce->name, path, namelen);\n+\tce->ce_mode = create_ce_mode(0100644);\n+\tce->ce_flags = create_ce_flags(namelen, 0);\n+\n+\tst.st_size = 0;\n+\t\n+\tif (index_pipe(ce->sha1, 0, NULL))\n+\t\treturn -1;\n+\toption = allow_add ? ADD_CACHE_OK_TO_ADD : 0;\n+\toption |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;\n+\tif (add_cache_entry(ce, option))\n+\t\treturn error(\"%s: cannot add to the index - missing --add option?\",\n+\t\t\t     path);\n+\treturn 0;\n+}\n+\n /*\n  * \"refresh\" does not calculate a new sha1 file or bring the\n  * cache up-to-date for mode/content changes. But what it\n@@ -396,7 +425,7 @@ static void read_index_info(int line_ter\n }\n \n static const char update_index_usage[] =\n-\"git-update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--cacheinfo] [--chmod=(+|-)x] [--info-only] [--force-remove] [--stdin] [--index-info] [--ignore-missing] [-z] [--verbose] [--] <file>...\";\n+\"git-update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--cacheinfo] [--chmod=(+|-)x] [--info-only] [--force-remove] [--stdin] [--index-info] [--ignore-missing] [--name=<file>] [-z] [--verbose] [--] <file>...\";\n \n int main(int argc, const char **argv)\n {\n@@ -464,6 +493,10 @@ int main(int argc, const char **argv)\n \t\t\t\t\tdie(\"git-update-index: %s cannot chmod %s\", path, argv[i]);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!strncmp(path, \"--name=\", strlen(\"--name=\"))) {\n+\t\t\t\tsingle_name = strdup(path + strlen(\"--name=\"));\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(path, \"--info-only\")) {\n \t\t\t\tinfo_only = 1;\n \t\t\t\tcontinue;\n@@ -499,6 +532,8 @@ int main(int argc, const char **argv)\n \t\t\t\tusage(update_index_usage);\n \t\t\tdie(\"unknown option %s\", path);\n \t\t}\n+\t\tif (single_name)\n+\t\t\tdie(\"--name=<file> is incompatible with filenames\");\n \t\tupdate_one(path, prefix, prefix_length);\n \t}\n \tif (read_from_stdin) {\n@@ -511,6 +546,9 @@ int main(int argc, const char **argv)\n \t\t\tupdate_one(buf.buf, prefix, prefix_length);\n \t\t}\n \t}\n+\tif (single_name) {\n+\t\tadd_stdin_to_cache(single_name);\n+\t}\n \tif (active_cache_changed) {\n \t\tif (write_cache(newfd, active_cache, active_nr) ||\n \t\t    commit_index_file(&cache_file))\n-- \n0.99.9.GIT\n"},{"id":"13430","messageId":"7vbqzpxwg2.fsf@assigned-by-dhcp.cox.net","threadId":"2792","inReplyTo":"Pine.LNX.4.64.0512100145500.25300@iabervon.org","subject":"Re: [PATCH] Allow updating the index from a pipe","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-12-10T07:06:37Z","receivedAt":"2005-12-10T07:06:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> In order to allow the index to be modified in simple ways without\n> having a working tree, this adds an option to git-update-index which\n> updates a single path with a mode of 100644 and reads the content from\n> stdin.\n\nI wonder ...\n\nCould you do this with existing hash-object with update-index\n--cache-info (or --index-info) please?  If you do not want a\ntemporary file and prefer piping contents into a command,\nextending hash-object would be preferable.\n"},{"id":"13431","messageId":"Pine.LNX.4.64.0512100210090.25300@iabervon.org","threadId":"2792","inReplyTo":"7vbqzpxwg2.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Allow updating the index from a pipe","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-12-10T07:12:05Z","receivedAt":"2005-12-10T07:12:05Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Fri, 9 Dec 2005, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > In order to allow the index to be modified in simple ways without\n> > having a working tree, this adds an option to git-update-index which\n> > updates a single path with a mode of 100644 and reads the content from\n> > stdin.\n> \n> I wonder ...\n> \n> Could you do this with existing hash-object with update-index\n> --cache-info (or --index-info) please?  If you do not want a\n> temporary file and prefer piping contents into a command,\n> extending hash-object would be preferable.\n\nSure; I lost track of what hash-object was called at some point and \nthought it had been removed. I'll do a patch to extend that to take stdin \nwhen I get a chance.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"}]}