{"thread":{"id":"12408","subject":"How to \"git add .\" when some files are not accessible (permission denied)?","startedAt":"2008-03-01T13:46:28Z","lastAt":"2008-05-13T22:28:02Z","messageCount":32,"participants":["Dirk Süsserott","Jeff King","Alex Riesen","Johannes Schindelin","Junio C Hamano","Joachim B Haga","Daniel Barkalow"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"70532","messageId":"47C95E34.1050306@dirk.my1.cc","threadId":"12408","inReplyTo":null,"subject":"How to \"git add .\" when some files are not accessible (permission denied)?","fromName":"Dirk Süsserott","fromEmail":"newsletter@dirk.my1.cc","sentAt":"2008-03-01T13:46:28Z","receivedAt":"2008-03-01T13:46:28Z","isPatch":false,"sender":{"key":"newsletter@dirk.my1.cc","avatar":null},"body":"Hello --\n\nFirst of all: I'm using Git with Windows. Most of the time it works \n*very* good, but now I've a problem that might appear to Unix users as \nwell. I had the idea to use Git to track changes in my C:\\WINDOWS \ndirectory. I thought the following would work:\n\n$ cd /c/WINDOWS             (1)\n$ git init                  (2)\n$ git add .                 (3)\n$ git commit -m \"Initial\"   (4)\n\nAnd then issue \"git status\" or so to see the differences after \ninstalling or running some software.\n\nHowever, when issueing (3) \"git add .\" it adds hundreds and thousands of\nfiles and then stops with\n\n     error: open(\"foo\"): Permission denied: foo\n     fatal: unable to index file foo\n\nThe file \"foo\" is not accessible for me, even though I'm administrator.\nThis might occur to Windows and Linux persons as well, I guess. The \nadding stops overall.\n\nThe question is: is there a way to tell \"git add .\" to add all files but\nignore those that cannot be added due to lack of authorization?\n\nOr, more generally spoken: can I tell \"git add\" to add only those files \nit can handle and ignore the rest? The \"-f\" switch doesn't work and some\nexclude lists on a per file basis are not applicable for my purpose as I\ndon't know the files in advance.\n\nI'm aware that I could do it with some fancy shell commands, but very \noften I was surprised how many really cool commands Git offers to \"do \nwhat I mean\". Wished other software would be so usable :-).\n\n\nCheers,\n  -- Dirk\n"},{"id":"70569","messageId":"20080302011900.GC22843@coredump.intra.peff.net","threadId":"12408","inReplyTo":"47C95E34.1050306@dirk.my1.cc","subject":"Re: How to \"git add .\" when some files are not accessible (permission denied)?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-03-02T01:19:00Z","receivedAt":"2008-03-02T01:19:00Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Mar 01, 2008 at 02:46:28PM +0100, Dirk Süsserott wrote:\n\n> The question is: is there a way to tell \"git add .\" to add all files but\n> ignore those that cannot be added due to lack of authorization?\n\nNo, there isn't. Under Linux, I would come up with a list of files I was\ninterested in and then pipe it to \"xargs git-add\", which is probably\nunhelpful for Windows.\n\nBut I think more fundamentally, you probably _do_ want to come up with a\nlist of files that you can't access and add them to your .gitignore (or\nyour .git/info/exclude file if they are purely a local matter). That is\nthe official way to tell all git commands \"I really don't care about\nthese files\".  Otherwise they will keep getting brought up when you do,\ne.g., a git-status.\n\n> Or, more generally spoken: can I tell \"git add\" to add only those files  \n> it can handle and ignore the rest? The \"-f\" switch doesn't work and some\n> exclude lists on a per file basis are not applicable for my purpose as I\n> don't know the files in advance.\n\nThe only reason I can think of to not want to generate such an ignore\nlist is if you are frequently and automagically doing a \"git add .\" to\npick up new files. For that reason, a \"try to continue even if we can't\nlook at some files\" option to git add might make some sense.\n\n-Peff\n"},{"id":"70644","messageId":"20080302154154.GC2973@steel.home","threadId":"12408","inReplyTo":"47C95E34.1050306@dirk.my1.cc","subject":"Re: How to \"git add .\" when some files are not accessible (permission denied)?","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-03-02T15:41:54Z","receivedAt":"2008-03-02T15:41:54Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Dirk Süsserott, Sat, Mar 01, 2008 14:46:28 +0100:\n> Or, more generally spoken: can I tell \"git add\" to add only those files it \n> can handle and ignore the rest? The \"-f\" switch doesn't work and some\n> exclude lists on a per file basis are not applicable for my purpose as I\n> don't know the files in advance.\n\nWell, \"-f\" means something else (include the ignored files). It is\nunfortunate, because (I think) your case fits better its traditional\nmeaning...\n\nYou can try the following patches, which add \"--ignore-errors\" to\ngit-add. Maybe it will be enough... It is generally considered\nnot safe to ignore errors.\n\n"},{"id":"70645","messageId":"20080302154238.GD2973@steel.home","threadId":"12408","inReplyTo":"20080302154154.GC2973@steel.home","subject":"[PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-03-02T15:42:38Z","receivedAt":"2008-03-02T15:42:38Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Update the programs which used the function (as add_file_to_cache).\n\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n builtin-add.c    |    6 ++++--\n builtin-commit.c |    7 ++++---\n builtin-mv.c     |    3 ++-\n read-cache.c     |    8 ++++----\n 4 files changed, 14 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin-add.c b/builtin-add.c\nindex 820110e..abfe473 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -94,7 +94,8 @@ static void update_callback(struct diff_queue_struct *q,\n \t\tcase DIFF_STATUS_UNMERGED:\n \t\tcase DIFF_STATUS_MODIFIED:\n \t\tcase DIFF_STATUS_TYPE_CHANGED:\n-\t\t\tadd_file_to_cache(path, verbose);\n+\t\t\tif (add_file_to_cache(path, verbose))\n+\t\t\t\texit(1);\n \t\t\tbreak;\n \t\tcase DIFF_STATUS_DELETED:\n \t\t\tremove_file_from_cache(path);\n@@ -266,7 +267,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t}\n \n \tfor (i = 0; i < dir.nr; i++)\n-\t\tadd_file_to_cache(dir.entries[i]->name, verbose);\n+\t\tif (add_file_to_cache(dir.entries[i]->name, verbose))\n+\t\t\texit(1);\n \n  finish:\n \tif (active_cache_changed) {\ndiff --git a/builtin-commit.c b/builtin-commit.c\nindex f49c22e..fb1e588 100644\n--- a/builtin-commit.c\n+++ b/builtin-commit.c\n@@ -176,9 +176,10 @@ static void add_remove_files(struct path_list *list)\n \tint i;\n \tfor (i = 0; i < list->nr; i++) {\n \t\tstruct path_list_item *p = &(list->items[i]);\n-\t\tif (file_exists(p->path))\n-\t\t\tadd_file_to_cache(p->path, 0);\n-\t\telse\n+\t\tif (file_exists(p->path)) {\n+\t\t\tif (add_file_to_cache(p->path, 0))\n+\t\t\t\texit(1);\n+\t\t} else\n \t\t\tremove_file_from_cache(p->path);\n \t}\n }\ndiff --git a/builtin-mv.c b/builtin-mv.c\nindex 68aa2a6..ec6e09d 100644\n--- a/builtin-mv.c\n+++ b/builtin-mv.c\n@@ -260,7 +260,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \n \t\tfor (i = 0; i < added.nr; i++) {\n \t\t\tconst char *path = added.items[i].path;\n-\t\t\tadd_file_to_cache(path, verbose);\n+\t\t\tif (add_file_to_cache(path, verbose))\n+\t\t\t\texit(1);\n \t\t}\n \n \t\tfor (i = 0; i < deleted.nr; i++)\ndiff --git a/read-cache.c b/read-cache.c\nindex 657f0c5..4a4f511 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -461,10 +461,10 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)\n \tunsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY;\n \n \tif (lstat(path, &st))\n-\t\tdie(\"%s: unable to stat (%s)\", path, strerror(errno));\n+\t\treturn error(\"%s: unable to stat (%s)\", path, strerror(errno));\n \n \tif (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode))\n-\t\tdie(\"%s: can only add regular files, symbolic links or git-directories\", path);\n+\t\treturn error(\"%s: can only add regular files, symbolic links or git-directories\", path);\n \n \tnamelen = strlen(path);\n \tif (S_ISDIR(st.st_mode)) {\n@@ -501,9 +501,9 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)\n \t}\n \n \tif (index_path(ce->sha1, path, &st, 1))\n-\t\tdie(\"unable to index file %s\", path);\n+\t\treturn error(\"unable to index file %s\", path);\n \tif (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))\n-\t\tdie(\"unable to add %s to index\",path);\n+\t\treturn error(\"unable to add %s to index\",path);\n \tif (verbose)\n \t\tprintf(\"add '%s'\\n\", path);\n \treturn 0;\n-- \n1.5.4.3.391.gf5a0c\n\n"},{"id":"70646","messageId":"20080302154321.GE2973@steel.home","threadId":"12408","inReplyTo":"20080302154238.GD2973@steel.home","subject":"[PATCH] Extend interface of add_files_to_cache to allow ignore indexing errors","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-03-02T15:43:21Z","receivedAt":"2008-03-02T15:43:21Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n builtin-add.c      |   37 ++++++++++++++++++++++++++++---------\n builtin-checkout.c |    2 +-\n builtin-commit.c   |    2 +-\n cache.h            |    8 +++++++-\n 4 files changed, 37 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin-add.c b/builtin-add.c\nindex abfe473..bc55a0e 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -79,12 +79,18 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec,\n \t\tprune_directory(dir, pathspec, baselen);\n }\n \n+struct update_callback_data\n+{\n+\tint flags;\n+\tint add_errors;\n+};\n+\n static void update_callback(struct diff_queue_struct *q,\n \t\t\t    struct diff_options *opt, void *cbdata)\n {\n-\tint i, verbose;\n+\tint i;\n+\tstruct update_callback_data *data = cbdata;\n \n-\tverbose = *((int *)cbdata);\n \tfor (i = 0; i < q->nr; i++) {\n \t\tstruct diff_filepair *p = q->queue[i];\n \t\tconst char *path = p->one->path;\n@@ -94,28 +100,35 @@ static void update_callback(struct diff_queue_struct *q,\n \t\tcase DIFF_STATUS_UNMERGED:\n \t\tcase DIFF_STATUS_MODIFIED:\n \t\tcase DIFF_STATUS_TYPE_CHANGED:\n-\t\t\tif (add_file_to_cache(path, verbose))\n-\t\t\t\texit(1);\n+\t\t\tif (add_file_to_cache(path, data->flags & ADD_FILES_VERBOSE)) {\n+\t\t\t\tif (!(data->flags & ADD_FILES_IGNORE_ERRORS))\n+\t\t\t\t\texit(1);\n+\t\t\t\tdata->add_errors++;\n+\t\t\t}\n \t\t\tbreak;\n \t\tcase DIFF_STATUS_DELETED:\n \t\t\tremove_file_from_cache(path);\n-\t\t\tif (verbose)\n+\t\t\tif (data->flags & ADD_FILES_VERBOSE)\n \t\t\t\tprintf(\"remove '%s'\\n\", path);\n \t\t\tbreak;\n \t\t}\n \t}\n }\n \n-void add_files_to_cache(int verbose, const char *prefix, const char **pathspec)\n+int add_files_to_cache(const char *prefix, const char **pathspec, int flags)\n {\n+\tstruct update_callback_data data;\n \tstruct rev_info rev;\n \tinit_revisions(&rev, prefix);\n \tsetup_revisions(0, NULL, &rev, NULL);\n \trev.prune_data = pathspec;\n \trev.diffopt.output_format = DIFF_FORMAT_CALLBACK;\n \trev.diffopt.format_callback = update_callback;\n-\trev.diffopt.format_callback_data = &verbose;\n+\tdata.flags = flags;\n+\tdata.add_errors = 0;\n+\trev.diffopt.format_callback_data = &data;\n \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n+\treturn !!data.add_errors;\n }\n \n static void refresh(int verbose, const char **pathspec)\n@@ -193,6 +206,7 @@ static struct option builtin_add_options[] = {\n \n int cmd_add(int argc, const char **argv, const char *prefix)\n {\n+\tint exit_status = 0;\n \tint i, newfd;\n \tconst char **pathspec;\n \tstruct dir_struct dir;\n@@ -209,11 +223,16 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \tnewfd = hold_locked_index(&lock_file, 1);\n \n \tif (take_worktree_changes) {\n+\t\tint flags = 0;\n \t\tconst char **pathspec;\n \t\tif (read_cache() < 0)\n \t\t\tdie(\"index file corrupt\");\n \t\tpathspec = get_pathspec(prefix, argv);\n-\t\tadd_files_to_cache(verbose, prefix, pathspec);\n+\n+\t\tif (verbose)\n+\t\t\tflags |= ADD_FILES_VERBOSE;\n+\n+\t\texit_status = add_files_to_cache(prefix, pathspec, flags);\n \t\tgoto finish;\n \t}\n \n@@ -277,5 +296,5 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t\tdie(\"Unable to write new index file\");\n \t}\n \n-\treturn 0;\n+\treturn exit_status;\n }\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex b0cd788..2def093 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -273,7 +273,7 @@ static int merge_working_tree(struct checkout_opts *opts,\n \t\t\t * entries in the index.\n \t\t\t */\n \n-\t\t\tadd_files_to_cache(0, NULL, NULL);\n+\t\t\tadd_files_to_cache(NULL, NULL, 0);\n \t\t\twork = write_tree_from_memory();\n \n \t\t\tret = reset_to_new(new->commit->tree, opts->quiet);\ndiff --git a/builtin-commit.c b/builtin-commit.c\nindex fb1e588..d5e8c4c 100644\n--- a/builtin-commit.c\n+++ b/builtin-commit.c\n@@ -242,7 +242,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)\n \t */\n \tif (all || (also && pathspec && *pathspec)) {\n \t\tint fd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(0, also ? prefix : NULL, pathspec);\n+\t\tadd_files_to_cache(also ? prefix : NULL, pathspec, 0);\n \t\trefresh_cache(REFRESH_QUIET);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\n \t\t    close_lock_file(&index_lock))\ndiff --git a/cache.h b/cache.h\nindex f16d341..c6c1659 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -748,7 +748,13 @@ extern int convert_to_git(const char *path, const char *src, size_t len,\n extern int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst);\n \n /* add */\n-void add_files_to_cache(int verbose, const char *prefix, const char **pathspec);\n+#define ADD_FILES_VERBOSE\t01\n+#define ADD_FILES_IGNORE_ERRORS\t02\n+/*\n+ * return 0 if success, 1 - if addition of a file failed and\n+ * ADD_FILES_IGNORE_ERRORS was specified in flags\n+ */\n+int add_files_to_cache(const char *prefix, const char **pathspec, int flags);\n \n /* diff.c */\n extern int diff_auto_refresh_index;\n-- \n1.5.4.3.391.gf5a0c\n\n"},{"id":"70648","messageId":"20080302154400.GF2973@steel.home","threadId":"12408","inReplyTo":"20080302154321.GE2973@steel.home","subject":"[PATCH] Add --ignore-errors to git-add to allow it to skip files with read errors","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-03-02T15:44:00Z","receivedAt":"2008-03-02T15:44:00Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n Documentation/git-add.txt |    7 ++++++-\n builtin-add.c             |   11 +++++++++--\n 2 files changed, 15 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\nindex 4779909..9360a4f 100644\n--- a/Documentation/git-add.txt\n+++ b/Documentation/git-add.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git-add' [-n] [-v] [-f] [--interactive | -i] [--patch | -p] [-u] [--refresh]\n-          [--] <filepattern>...\n+\t  [--ignore-errors] [--] <filepattern>...\n \n DESCRIPTION\n -----------\n@@ -81,6 +81,11 @@ OPTIONS\n \tDon't add the file(s), but only refresh their stat()\n \tinformation in the index.\n \n+\\--ignore-errors::\n+\tIf some files could not be added because of errors indexing\n+\tthem, do not abort the operation, but continue adding the\n+\tothers. The command shall still exit with non-zero status.\n+\n \\--::\n \tThis option can be used to separate command-line options from\n \tthe list of files, (useful when filenames might be mistaken\ndiff --git a/builtin-add.c b/builtin-add.c\nindex bc55a0e..b67ad3f 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -191,6 +191,7 @@ static const char ignore_error[] =\n \"The following paths are ignored by one of your .gitignore files:\\n\";\n \n static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;\n+static int ignore_add_errors;\n \n static struct option builtin_add_options[] = {\n \tOPT__DRY_RUN(&show_only),\n@@ -201,6 +202,7 @@ static struct option builtin_add_options[] = {\n \tOPT_BOOLEAN('f', NULL, &ignored_too, \"allow adding otherwise ignored files\"),\n \tOPT_BOOLEAN('u', NULL, &take_worktree_changes, \"update tracked files\"),\n \tOPT_BOOLEAN( 0 , \"refresh\", &refresh_only, \"don't add, only refresh the index\"),\n+\tOPT_BOOLEAN( 0 , \"ignore-errors\", &ignore_add_errors, \"just skip files which cannot be added because of errors\"),\n \tOPT_END(),\n };\n \n@@ -231,6 +233,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \t\tif (verbose)\n \t\t\tflags |= ADD_FILES_VERBOSE;\n+\t\tif (ignore_add_errors)\n+\t\t\tflags |= ADD_FILES_IGNORE_ERRORS;\n \n \t\texit_status = add_files_to_cache(prefix, pathspec, flags);\n \t\tgoto finish;\n@@ -286,8 +290,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t}\n \n \tfor (i = 0; i < dir.nr; i++)\n-\t\tif (add_file_to_cache(dir.entries[i]->name, verbose))\n-\t\t\texit(1);\n+\t\tif (add_file_to_cache(dir.entries[i]->name, verbose)) {\n+\t\t\tif (!ignore_add_errors)\n+\t\t\t\texit(1);\n+\t\t\texit_status = 1;\n+\t\t}\n \n  finish:\n \tif (active_cache_changed) {\n-- \n1.5.4.3.391.gf5a0c\n\n"},{"id":"70647","messageId":"20080302154423.GG2973@steel.home","threadId":"12408","inReplyTo":"20080302154400.GF2973@steel.home","subject":"[PATCH] Add a test for git-add --ignore-errors","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-03-02T15:44:23Z","receivedAt":"2008-03-02T15:44:23Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n t/t3700-add.sh |    9 +++++++++\n 1 files changed, 9 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t3700-add.sh b/t/t3700-add.sh\nindex 287e058..ca3e33d 100755\n--- a/t/t3700-add.sh\n+++ b/t/t3700-add.sh\n@@ -179,4 +179,13 @@ test_expect_success 'git add --refresh' '\n \ttest -z \"`git diff-index HEAD -- foo`\"\n '\n \n+test_expect_success 'git add --ignore-errors' '\n+\tgit reset --hard &&\n+\tdate >foo1 &&\n+\tdate >foo2 &&\n+\tchmod 0 foo2 &&\n+\tgit add --verbose --ignore-errors .\n+\tgit ls-files |grep foo1\n+'\n+\n test_done\n-- \n1.5.4.3.391.gf5a0c\n\n"},{"id":"70655","messageId":"alpine.LSU.1.00.0803021555500.22527@racer.site","threadId":"12408","inReplyTo":"20080302154238.GD2973@steel.home","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-02T15:57:02Z","receivedAt":"2008-03-02T15:57:02Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 2 Mar 2008, Alex Riesen wrote:\n\n> -\t\t\tadd_file_to_cache(path, verbose);\n> +\t\t\tif (add_file_to_cache(path, verbose))\n> +\t\t\t\texit(1);\n\nDoes it really, really _have_ to be exit(1)?  I mean, now you block even \nthe faintest chance that we can libify libgit.a by overriding die_routine.\n\nA \"return -1\" might make _much_ more sense, too.\n\nCiao,\nDscho\n\n"},{"id":"70663","messageId":"7vtzjpoye6.fsf@gitster.siamese.dyndns.org","threadId":"12408","inReplyTo":"alpine.LSU.1.00.0803021555500.22527@racer.site","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-02T16:59:13Z","receivedAt":"2008-03-02T16:59:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> On Sun, 2 Mar 2008, Alex Riesen wrote:\n>\n>> -\t\t\tadd_file_to_cache(path, verbose);\n>> +\t\t\tif (add_file_to_cache(path, verbose))\n>> +\t\t\t\texit(1);\n>\n> Does it really, really _have_ to be exit(1)?  I mean, now you block even \n> the faintest chance that we can libify libgit.a by overriding die_routine.\n\nI think Alex did so not to break the existing scripts that rely on these\ndying, but it should have been exit(128) to really stay compatible.\n\nWhy is this even needed to begin with?  I am aware of Dirk's original\nissue discussed elsewhere, but we try fairly hard to be A-O-N when we can\nafford to, and this option deliberately breaks it.  What is the real\nreason why such an unreadable (either for privilege or for I/O error)\nfile should not live in .gitignore?\n\n"},{"id":"70704","messageId":"20080302214241.GB13954@steel.home","threadId":"12408","inReplyTo":"7vtzjpoye6.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-03-02T21:42:41Z","receivedAt":"2008-03-02T21:42:41Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Junio C Hamano, Sun, Mar 02, 2008 17:59:13 +0100:\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > On Sun, 2 Mar 2008, Alex Riesen wrote:\n> >\n> >> -\t\t\tadd_file_to_cache(path, verbose);\n> >> +\t\t\tif (add_file_to_cache(path, verbose))\n> >> +\t\t\t\texit(1);\n> >\n> > Does it really, really _have_ to be exit(1)?  I mean, now you block even \n> > the faintest chance that we can libify libgit.a by overriding die_routine.\n> \n> I think Alex did so not to break the existing scripts that rely on these\n> dying, but it should have been exit(128) to really stay compatible.\n\nSorry, this time it was actually mostly accident. I just selected the\nfirst non-zero.\n\n> Why is this even needed to begin with?  I am aware of Dirk's original\n> issue discussed elsewhere, but we try fairly hard to be A-O-N when we can\n> afford to, and this option deliberately breaks it.  What is the real\n> reason why such an unreadable (either for privilege or for I/O error)\n> file should not live in .gitignore?\n\nAnother program keeps the file open. There is an exclusive mode for\nopening files, which locks the files for everyone. I believe it is\neven default mode, unless selected otherwise.\n\n"},{"id":"70706","messageId":"85ablgkcjo.fsf@lupus.strangled.net","threadId":"12408","inReplyTo":"20080302214241.GB13954@steel.home","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Joachim B Haga","fromEmail":"cjhaga@fys.uio.no","sentAt":"2008-03-02T22:04:43Z","receivedAt":"2008-03-02T22:04:43Z","isPatch":true,"sender":{"key":"cjhaga@fys.uio.no","avatar":null},"body":"Alex Riesen <raa.lkml@gmail.com> writes:\n\n> Junio C Hamano, Sun, Mar 02, 2008 17:59:13 +0100:\n>> Why is this even needed to begin with?  I am aware of Dirk's original\n>> issue discussed elsewhere, but we try fairly hard to be A-O-N when we can\n>> afford to, and this option deliberately breaks it.  What is the real\n>> reason why such an unreadable (either for privilege or for I/O error)\n>> file should not live in .gitignore?\n>\n> Another program keeps the file open. There is an exclusive mode for\n> opening files, which locks the files for everyone. I believe it is\n> even default mode, unless selected otherwise.\n\nAnother minor annoyance in this area, is when a wildcard add fails\nbecause of ignored files:\n\n  potassium ~/svn/Deformation|master 0$ ls EpetraMatrix.*\n  EpetraMatrix.cpp  EpetraMatrix.cpp~  EpetraMatrix.h  EpetraMatrix.o\n  potassium ~/svn/Deformation|master 0$ git add EpetraMatrix.*\n  The following paths are ignored by one of your .gitignore files:\n  EpetraMatrix.cpp~\n  EpetraMatrix.o\n  Use -f if you really want to add them.\n  potassium ~/svn/New-Deformation|master 0$ git status\n  # On branch master\n  # Changed but not updated:\n  #   (use \"git add <file>...\" to update what will be committed)\n  #\n  [...]\n\nI don't want to add them, I just want to ignore them completely (i.e., \nadd the un-ignored ones).\n\nWould this case also be covered by the new switch?\n\n-j.\n\n"},{"id":"70749","messageId":"20080303065741.GA2916@steel.home","threadId":"12408","inReplyTo":"85ablgkcjo.fsf@lupus.strangled.net","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-03-03T06:57:41Z","receivedAt":"2008-03-03T06:57:41Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Joachim B Haga, Sun, Mar 02, 2008 23:04:43 +0100:\n> Alex Riesen <raa.lkml@gmail.com> writes:\n> > Junio C Hamano, Sun, Mar 02, 2008 17:59:13 +0100:\n> >> Why is this even needed to begin with?  I am aware of Dirk's original\n> >> issue discussed elsewhere, but we try fairly hard to be A-O-N when we can\n> >> afford to, and this option deliberately breaks it.  What is the real\n> >> reason why such an unreadable (either for privilege or for I/O error)\n> >> file should not live in .gitignore?\n> >\n> > Another program keeps the file open. There is an exclusive mode for\n> > opening files, which locks the files for everyone. I believe it is\n> > even default mode, unless selected otherwise.\n> \n> Another minor annoyance in this area, is when a wildcard add fails\n> because of ignored files:\n> \n>   potassium ~/svn/Deformation|master 0$ ls EpetraMatrix.*\n>   EpetraMatrix.cpp  EpetraMatrix.cpp~  EpetraMatrix.h  EpetraMatrix.o\n>   potassium ~/svn/Deformation|master 0$ git add EpetraMatrix.*\n>   The following paths are ignored by one of your .gitignore files:\n>   EpetraMatrix.cpp~\n>   EpetraMatrix.o\n>   Use -f if you really want to add them.\n>   potassium ~/svn/New-Deformation|master 0$ git status\n>   # On branch master\n>   # Changed but not updated:\n>   #   (use \"git add <file>...\" to update what will be committed)\n>   #\n>   [...]\n> \n> I don't want to add them, I just want to ignore them completely (i.e., \n> add the un-ignored ones).\n> \n> Would this case also be covered by the new switch?\n\nNo. This is entirely different usability issue\n\n"},{"id":"70813","messageId":"alpine.LNX.1.00.0803031252410.19665@iabervon.org","threadId":"12408","inReplyTo":"alpine.LSU.1.00.0803021555500.22527@racer.site","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-03-03T18:01:24Z","receivedAt":"2008-03-03T18:01:24Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sun, 2 Mar 2008, Johannes Schindelin wrote:\n\n> Hi,\n> \n> On Sun, 2 Mar 2008, Alex Riesen wrote:\n> \n> > -\t\t\tadd_file_to_cache(path, verbose);\n> > +\t\t\tif (add_file_to_cache(path, verbose))\n> > +\t\t\t\texit(1);\n> \n> Does it really, really _have_ to be exit(1)?  I mean, now you block even \n> the faintest chance that we can libify libgit.a by overriding die_routine.\n\nIt would be handy to have a die_no_message(), for cases like this where a \nfunction wants to print an error message but it's up to the caller whether \nto abort (in the contextually reasonable way).\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"70828","messageId":"47CC4EAC.1050905@dirk.my1.cc","threadId":"12408","inReplyTo":"20080302011900.GC22843@coredump.intra.peff.net","subject":"Re: How to \"git add .\" when some files are not accessible (permission denied)?","fromName":"Dirk Süsserott","fromEmail":"newsletter@dirk.my1.cc","sentAt":"2008-03-03T19:17:00Z","receivedAt":"2008-03-03T19:17:00Z","isPatch":false,"sender":{"key":"newsletter@dirk.my1.cc","avatar":null},"body":"Jeff King schrieb:\n> On Sat, Mar 01, 2008 at 02:46:28PM +0100, Dirk Süsserott wrote:\n>\n>   \n>> The question is: is there a way to tell \"git add .\" to add all files but\n>> ignore those that cannot be added due to lack of authorization?\n>>     \n>\n> No, there isn't. Under Linux, I would come up with a list of files I was\n> interested in and then pipe it to \"xargs git-add\", which is probably\n> unhelpful for Windows.\n>\n>   \nNot quite. I'm using the msysGit package from \nhttp://code.google.com/p/msysgit/downloads/list and that comes with some \nfundamental unix tools like a sound shell, find, xargs, and many more. \nVery good!\nThis way prepared, I used \"git ls-files -o | xargs git add -v\" until \nmost of my files were added.\nFor the rest I did \"xargs -l\" (ell) so that the files got added one by one.\nThe files that still refused to be added are finally ignored by \"git \nls-files -o >> .gitignore\".\n\nCaveat: filenames containing blanks are not handled properly as they are \nnot surrounded by quotes. \"git add\" thinks of them as two or more files \nand fails.\nI figure xargs has some cool switches to sourround the parameters with \nquotes, but I didn't find them. An option was to write a script or shell \nfunction that does it and pipe the filenames through that function or -- \nas filenames with blanks aren't so numerous -- to add them manually with \n\"git gui\".\n\nEventually, I solved the problem. Thanks for and to your pointers. :-)\n\n  -- Dirk\n\n"},{"id":"70836","messageId":"7vmypfh8s4.fsf@gitster.siamese.dyndns.org","threadId":"12408","inReplyTo":"47CC4EAC.1050905@dirk.my1.cc","subject":"Re: How to \"git add .\" when some files are not accessible (permission denied)?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-03T20:06:35Z","receivedAt":"2008-03-03T20:06:35Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dirk Süsserott <newsletter@dirk.my1.cc> writes:\n\n> This way prepared, I used \"git ls-files -o | xargs git add -v\" until\n> most of my files were added.\n> ...\n> Caveat: filenames containing blanks are not handled properly as they\n> are not surrounded by quotes. \"git add\" thinks of them as two or more\n> files and fails.\n\nPerhaps \"git ls-files -z -o | git update-index --add --stdin\"\n"},{"id":"70839","messageId":"47CC6051.1090308@dirk.my1.cc","threadId":"12408","inReplyTo":"7vmypfh8s4.fsf@gitster.siamese.dyndns.org","subject":"Re: How to \"git add .\" when some files are not accessible (permission denied)?","fromName":"Dirk Süsserott","fromEmail":"newsletter@dirk.my1.cc","sentAt":"2008-03-03T20:32:17Z","receivedAt":"2008-03-03T20:32:17Z","isPatch":false,"sender":{"key":"newsletter@dirk.my1.cc","avatar":null},"body":"Junio C Hamano schrieb:\n> Dirk Süsserott <newsletter@dirk.my1.cc> writes:\n>\n>   \n>> This way prepared, I used \"git ls-files -o | xargs git add -v\" until\n>> most of my files were added.\n>> ...\n>> Caveat: filenames containing blanks are not handled properly as they\n>> are not surrounded by quotes. \"git add\" thinks of them as two or more\n>> files and fails.\n>>     \n>\n> Perhaps \"git ls-files -z -o | git update-index --add --stdin\"\n>\n>   \nThat's exactly what I meant when I wrote \"Git almost always has a \nsolution for 'do what I mean'\".\nIt is, however, sometimes hard to find, but the solution is always there.\nIts such a great piece of software. Congratulations to you all.\n"},{"id":"76730","messageId":"20080512175654.GB3128@steel.home","threadId":"12408","inReplyTo":"7vtzjpoye6.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-05-12T17:56:54Z","receivedAt":"2008-05-12T17:56:54Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Junio C Hamano, Sun, Mar 02, 2008 17:59:13 +0100:\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> > On Sun, 2 Mar 2008, Alex Riesen wrote:\n> >\n> >> -\t\t\tadd_file_to_cache(path, verbose);\n> >> +\t\t\tif (add_file_to_cache(path, verbose))\n> >> +\t\t\t\texit(1);\n> >\n> > Does it really, really _have_ to be exit(1)?  I mean, now you block even \n> > the faintest chance that we can libify libgit.a by overriding die_routine.\n> \n> I think Alex did so not to break the existing scripts that rely on these\n> dying, but it should have been exit(128) to really stay compatible.\n\nI corrected the series to use die() again and rebased it off current\nmaster (65ea3b8c). So it is more compatible with libification (does\nnot hinder it more than previos code) and keep the exit code.\n"},{"id":"76731","messageId":"20080512175745.GC3128@steel.home","threadId":"12408","inReplyTo":"20080512175654.GB3128@steel.home","subject":"[PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-05-12T17:57:45Z","receivedAt":"2008-05-12T17:57:45Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Update the programs which used the function (as add_file_to_cache).\n\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n builtin-add.c    |    6 ++++--\n builtin-commit.c |    7 ++++---\n builtin-mv.c     |    3 ++-\n read-cache.c     |    6 +++---\n 4 files changed, 13 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin-add.c b/builtin-add.c\nindex 4a91e3e..4d72ab6 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -94,7 +94,8 @@ static void update_callback(struct diff_queue_struct *q,\n \t\tcase DIFF_STATUS_UNMERGED:\n \t\tcase DIFF_STATUS_MODIFIED:\n \t\tcase DIFF_STATUS_TYPE_CHANGED:\n-\t\t\tadd_file_to_cache(path, verbose);\n+\t\t\tif (add_file_to_cache(path, verbose))\n+\t\t\t\tdie(\"updating files failed\");\n \t\t\tbreak;\n \t\tcase DIFF_STATUS_DELETED:\n \t\t\tremove_file_from_cache(path);\n@@ -254,7 +255,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t}\n \n \tfor (i = 0; i < dir.nr; i++)\n-\t\tadd_file_to_cache(dir.entries[i]->name, verbose);\n+\t\tif (add_file_to_cache(dir.entries[i]->name, verbose))\n+\t\t\tdie(\"adding files failed\");\n \n  finish:\n \tif (active_cache_changed) {\ndiff --git a/builtin-commit.c b/builtin-commit.c\nindex a65c2b8..ae29d35 100644\n--- a/builtin-commit.c\n+++ b/builtin-commit.c\n@@ -178,9 +178,10 @@ static void add_remove_files(struct path_list *list)\n \t\tstruct stat st;\n \t\tstruct path_list_item *p = &(list->items[i]);\n \n-\t\tif (!lstat(p->path, &st))\n-\t\t\tadd_to_cache(p->path, &st, 0);\n-\t\telse\n+\t\tif (!lstat(p->path, &st)) {\n+\t\t\tif (add_to_cache(p->path, &st, 0))\n+\t\t\t\tdie(\"updating files failed\");\n+\t\t} else\n \t\t\tremove_file_from_cache(p->path);\n \t}\n }\ndiff --git a/builtin-mv.c b/builtin-mv.c\nindex 94f6dd2..fb8ffb4 100644\n--- a/builtin-mv.c\n+++ b/builtin-mv.c\n@@ -256,7 +256,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \n \t\tfor (i = 0; i < added.nr; i++) {\n \t\t\tconst char *path = added.items[i].path;\n-\t\t\tadd_file_to_cache(path, verbose);\n+\t\t\tif (add_file_to_cache(path, verbose))\n+\t\t\t\tdie(\"updating index entries failed\");\n \t\t}\n \n \t\tfor (i = 0; i < deleted.nr; i++)\ndiff --git a/read-cache.c b/read-cache.c\nindex 0382804..8b467f8 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -470,7 +470,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,\n \tunsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY;\n \n \tif (!S_ISREG(st_mode) && !S_ISLNK(st_mode) && !S_ISDIR(st_mode))\n-\t\tdie(\"%s: can only add regular files, symbolic links or git-directories\", path);\n+\t\treturn error(\"%s: can only add regular files, symbolic links or git-directories\", path);\n \n \tnamelen = strlen(path);\n \tif (S_ISDIR(st_mode)) {\n@@ -505,12 +505,12 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,\n \t\treturn 0;\n \t}\n \tif (index_path(ce->sha1, path, st, 1))\n-\t\tdie(\"unable to index file %s\", path);\n+\t\treturn error(\"unable to index file %s\", path);\n \tif (ignore_case && alias && different_name(ce, alias))\n \t\tce = create_alias_ce(ce, alias);\n \tce->ce_flags |= CE_ADDED;\n \tif (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))\n-\t\tdie(\"unable to add %s to index\",path);\n+\t\treturn error(\"unable to add %s to index\",path);\n \tif (verbose)\n \t\tprintf(\"add '%s'\\n\", path);\n \treturn 0;\n-- \n1.5.5.1.184.g5bee\n"},{"id":"76732","messageId":"20080512175810.GD3128@steel.home","threadId":"12408","inReplyTo":"20080512175745.GC3128@steel.home","subject":"[PATCH] Extend interface of add_files_to_cache to allow ignore indexing errors","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-05-12T17:58:10Z","receivedAt":"2008-05-12T17:58:10Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n builtin-add.c      |   37 ++++++++++++++++++++++++++++---------\n builtin-checkout.c |    2 +-\n builtin-commit.c   |    2 +-\n cache.h            |    8 +++++++-\n 4 files changed, 37 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin-add.c b/builtin-add.c\nindex 4d72ab6..7862808 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -79,12 +79,18 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec,\n \t\tprune_directory(dir, pathspec, baselen);\n }\n \n+struct update_callback_data\n+{\n+\tint flags;\n+\tint add_errors;\n+};\n+\n static void update_callback(struct diff_queue_struct *q,\n \t\t\t    struct diff_options *opt, void *cbdata)\n {\n-\tint i, verbose;\n+\tint i;\n+\tstruct update_callback_data *data = cbdata;\n \n-\tverbose = *((int *)cbdata);\n \tfor (i = 0; i < q->nr; i++) {\n \t\tstruct diff_filepair *p = q->queue[i];\n \t\tconst char *path = p->one->path;\n@@ -94,28 +100,35 @@ static void update_callback(struct diff_queue_struct *q,\n \t\tcase DIFF_STATUS_UNMERGED:\n \t\tcase DIFF_STATUS_MODIFIED:\n \t\tcase DIFF_STATUS_TYPE_CHANGED:\n-\t\t\tif (add_file_to_cache(path, verbose))\n-\t\t\t\tdie(\"updating files failed\");\n+\t\t\tif (add_file_to_cache(path, data->flags & ADD_FILES_VERBOSE)) {\n+\t\t\t\tif (!(data->flags & ADD_FILES_IGNORE_ERRORS))\n+\t\t\t\t\tdie(\"updating files failed\");\n+\t\t\t\tdata->add_errors++;\n+\t\t\t}\n \t\t\tbreak;\n \t\tcase DIFF_STATUS_DELETED:\n \t\t\tremove_file_from_cache(path);\n-\t\t\tif (verbose)\n+\t\t\tif (data->flags & ADD_FILES_VERBOSE)\n \t\t\t\tprintf(\"remove '%s'\\n\", path);\n \t\t\tbreak;\n \t\t}\n \t}\n }\n \n-void add_files_to_cache(int verbose, const char *prefix, const char **pathspec)\n+int add_files_to_cache(const char *prefix, const char **pathspec, int flags)\n {\n+\tstruct update_callback_data data;\n \tstruct rev_info rev;\n \tinit_revisions(&rev, prefix);\n \tsetup_revisions(0, NULL, &rev, NULL);\n \trev.prune_data = pathspec;\n \trev.diffopt.output_format = DIFF_FORMAT_CALLBACK;\n \trev.diffopt.format_callback = update_callback;\n-\trev.diffopt.format_callback_data = &verbose;\n+\tdata.flags = flags;\n+\tdata.add_errors = 0;\n+\trev.diffopt.format_callback_data = &data;\n \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n+\treturn !!data.add_errors;\n }\n \n static void refresh(int verbose, const char **pathspec)\n@@ -193,6 +206,7 @@ static struct option builtin_add_options[] = {\n \n int cmd_add(int argc, const char **argv, const char *prefix)\n {\n+\tint exit_status = 0;\n \tint i, newfd;\n \tconst char **pathspec;\n \tstruct dir_struct dir;\n@@ -209,11 +223,16 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \tnewfd = hold_locked_index(&lock_file, 1);\n \n \tif (take_worktree_changes) {\n+\t\tint flags = 0;\n \t\tconst char **pathspec;\n \t\tif (read_cache() < 0)\n \t\t\tdie(\"index file corrupt\");\n \t\tpathspec = get_pathspec(prefix, argv);\n-\t\tadd_files_to_cache(verbose, prefix, pathspec);\n+\n+\t\tif (verbose)\n+\t\t\tflags |= ADD_FILES_VERBOSE;\n+\n+\t\texit_status = add_files_to_cache(prefix, pathspec, flags);\n \t\tgoto finish;\n \t}\n \n@@ -265,5 +284,5 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t\tdie(\"Unable to write new index file\");\n \t}\n \n-\treturn 0;\n+\treturn exit_status;\n }\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 10ec137..05c0642 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -282,7 +282,7 @@ static int merge_working_tree(struct checkout_opts *opts,\n \t\t\t * entries in the index.\n \t\t\t */\n \n-\t\t\tadd_files_to_cache(0, NULL, NULL);\n+\t\t\tadd_files_to_cache(NULL, NULL, 0);\n \t\t\twork = write_tree_from_memory();\n \n \t\t\tret = reset_to_new(new->commit->tree, opts->quiet);\ndiff --git a/builtin-commit.c b/builtin-commit.c\nindex ae29d35..6a2f5c3 100644\n--- a/builtin-commit.c\n+++ b/builtin-commit.c\n@@ -246,7 +246,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)\n \t */\n \tif (all || (also && pathspec && *pathspec)) {\n \t\tint fd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(0, also ? prefix : NULL, pathspec);\n+\t\tadd_files_to_cache(also ? prefix : NULL, pathspec, 0);\n \t\trefresh_cache(REFRESH_QUIET);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\n \t\t    close_lock_file(&index_lock))\ndiff --git a/cache.h b/cache.h\nindex 9cee9a5..4fb6290 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -781,7 +781,13 @@ extern int convert_to_git(const char *path, const char *src, size_t len,\n extern int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst);\n \n /* add */\n-void add_files_to_cache(int verbose, const char *prefix, const char **pathspec);\n+#define ADD_FILES_VERBOSE\t01\n+#define ADD_FILES_IGNORE_ERRORS\t02\n+/*\n+ * return 0 if success, 1 - if addition of a file failed and\n+ * ADD_FILES_IGNORE_ERRORS was specified in flags\n+ */\n+int add_files_to_cache(const char *prefix, const char **pathspec, int flags);\n \n /* diff.c */\n extern int diff_auto_refresh_index;\n-- \n1.5.5.1.184.g5bee\n"},{"id":"76733","messageId":"20080512175829.GE3128@steel.home","threadId":"12408","inReplyTo":"20080512175810.GD3128@steel.home","subject":"[PATCH] Add --ignore-errors to git-add to allow it to skip files with read errors","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-05-12T17:58:29Z","receivedAt":"2008-05-12T17:58:29Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n Documentation/git-add.txt |    7 ++++++-\n builtin-add.c             |   11 +++++++++--\n 2 files changed, 15 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\nindex e0e730b..bb4abe2 100644\n--- a/Documentation/git-add.txt\n+++ b/Documentation/git-add.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git-add' [-n] [-v] [-f] [--interactive | -i] [--patch | -p] [-u] [--refresh]\n-          [--] <filepattern>...\n+\t  [--ignore-errors] [--] <filepattern>...\n \n DESCRIPTION\n -----------\n@@ -83,6 +83,11 @@ OPTIONS\n \tDon't add the file(s), but only refresh their stat()\n \tinformation in the index.\n \n+\\--ignore-errors::\n+\tIf some files could not be added because of errors indexing\n+\tthem, do not abort the operation, but continue adding the\n+\tothers. The command shall still exit with non-zero status.\n+\n \\--::\n \tThis option can be used to separate command-line options from\n \tthe list of files, (useful when filenames might be mistaken\ndiff --git a/builtin-add.c b/builtin-add.c\nindex 7862808..522519e 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -191,6 +191,7 @@ static const char ignore_error[] =\n \"The following paths are ignored by one of your .gitignore files:\\n\";\n \n static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;\n+static int ignore_add_errors;\n \n static struct option builtin_add_options[] = {\n \tOPT__DRY_RUN(&show_only),\n@@ -201,6 +202,7 @@ static struct option builtin_add_options[] = {\n \tOPT_BOOLEAN('f', NULL, &ignored_too, \"allow adding otherwise ignored files\"),\n \tOPT_BOOLEAN('u', NULL, &take_worktree_changes, \"update tracked files\"),\n \tOPT_BOOLEAN( 0 , \"refresh\", &refresh_only, \"don't add, only refresh the index\"),\n+\tOPT_BOOLEAN( 0 , \"ignore-errors\", &ignore_add_errors, \"just skip files which cannot be added because of errors\"),\n \tOPT_END(),\n };\n \n@@ -231,6 +233,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \t\tif (verbose)\n \t\t\tflags |= ADD_FILES_VERBOSE;\n+\t\tif (ignore_add_errors)\n+\t\t\tflags |= ADD_FILES_IGNORE_ERRORS;\n \n \t\texit_status = add_files_to_cache(prefix, pathspec, flags);\n \t\tgoto finish;\n@@ -274,8 +278,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t}\n \n \tfor (i = 0; i < dir.nr; i++)\n-\t\tif (add_file_to_cache(dir.entries[i]->name, verbose))\n-\t\t\tdie(\"adding files failed\");\n+\t\tif (add_file_to_cache(dir.entries[i]->name, verbose)) {\n+\t\t\tif (!ignore_add_errors)\n+\t\t\t\tdie(\"adding files failed\");\n+\t\t\texit_status = 1;\n+\t\t}\n \n  finish:\n \tif (active_cache_changed) {\n-- \n1.5.5.1.184.g5bee\n"},{"id":"76734","messageId":"20080512175848.GF3128@steel.home","threadId":"12408","inReplyTo":"20080512175829.GE3128@steel.home","subject":"[PATCH] Add a test for git-add --ignore-errors","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-05-12T17:58:48Z","receivedAt":"2008-05-12T17:58:48Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n t/t3700-add.sh |    9 +++++++++\n 1 files changed, 9 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t3700-add.sh b/t/t3700-add.sh\nindex 287e058..ca3e33d 100755\n--- a/t/t3700-add.sh\n+++ b/t/t3700-add.sh\n@@ -179,4 +179,13 @@ test_expect_success 'git add --refresh' '\n \ttest -z \"`git diff-index HEAD -- foo`\"\n '\n \n+test_expect_success 'git add --ignore-errors' '\n+\tgit reset --hard &&\n+\tdate >foo1 &&\n+\tdate >foo2 &&\n+\tchmod 0 foo2 &&\n+\tgit add --verbose --ignore-errors .\n+\tgit ls-files |grep foo1\n+'\n+\n test_done\n-- \n1.5.5.1.184.g5bee\n"},{"id":"76735","messageId":"20080512175923.GG3128@steel.home","threadId":"12408","inReplyTo":"20080512175848.GF3128@steel.home","subject":"[PATCH] Add a config option to ignore errors for git-add","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-05-12T17:59:23Z","receivedAt":"2008-05-12T17:59:23Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n builtin-add.c  |   11 ++++++++++-\n t/t3700-add.sh |   12 ++++++++++++\n 2 files changed, 22 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-add.c b/builtin-add.c\nindex 522519e..73235ed 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -206,6 +206,15 @@ static struct option builtin_add_options[] = {\n \tOPT_END(),\n };\n \n+static int add_config(const char *var, const char *value)\n+{\n+\tif (!strcasecmp(var, \"add.ignore-errors\")) {\n+\t\tignore_add_errors = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n+\treturn git_default_config(var, value);\n+}\n+\n int cmd_add(int argc, const char **argv, const char *prefix)\n {\n \tint exit_status = 0;\n@@ -220,7 +229,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \tif (add_interactive)\n \t\texit(interactive_add(argc, argv, prefix));\n \n-\tgit_config(git_default_config);\n+\tgit_config(add_config);\n \n \tnewfd = hold_locked_index(&lock_file, 1);\n \ndiff --git a/t/t3700-add.sh b/t/t3700-add.sh\nindex ca3e33d..08f1641 100755\n--- a/t/t3700-add.sh\n+++ b/t/t3700-add.sh\n@@ -188,4 +188,16 @@ test_expect_success 'git add --ignore-errors' '\n \tgit ls-files |grep foo1\n '\n \n+rm -f foo2\n+\n+test_expect_success 'git add (add.ignore-errors)' '\n+\tgit config add.ignore-errors 1 &&\n+\tgit reset --hard &&\n+\tdate >foo1 &&\n+\tdate >foo2 &&\n+\tchmod 0 foo2 &&\n+\tgit add --verbose .\n+\tgit ls-files |grep foo1\n+'\n+\n test_done\n-- \n1.5.5.1.184.g5bee\n"},{"id":"76744","messageId":"7vzlqvxt1p.fsf@gitster.siamese.dyndns.org","threadId":"12408","inReplyTo":"20080512175654.GB3128@steel.home","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-05-12T18:42:58Z","receivedAt":"2008-05-12T18:42:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Alex Riesen <raa.lkml@gmail.com> writes:\n\n> Junio C Hamano, Sun, Mar 02, 2008 17:59:13 +0100:\n>> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>> > On Sun, 2 Mar 2008, Alex Riesen wrote:\n>> >\n>> >> -\t\t\tadd_file_to_cache(path, verbose);\n>> >> +\t\t\tif (add_file_to_cache(path, verbose))\n>> >> +\t\t\t\texit(1);\n>> >\n>> > Does it really, really _have_ to be exit(1)?  I mean, now you block even \n>> > the faintest chance that we can libify libgit.a by overriding die_routine.\n>> \n>> I think Alex did so not to break the existing scripts that rely on these\n>> dying, but it should have been exit(128) to really stay compatible.\n>\n> I corrected the series to use die() again and rebased it off current\n> master (65ea3b8c). So it is more compatible with libification (does\n> not hinder it more than previos code) and keep the exit code.\n\nBut you did not answer my question in the part you did not quote, did you?\n\nNow when somebody either forgets to check the return value from this\nfunction, or deliberately ignores it, the resulting index will not match\nwhat the code is told to update it with.\n"},{"id":"76791","messageId":"20080512205414.GH3128@steel.home","threadId":"12408","inReplyTo":"7vzlqvxt1p.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-05-12T20:54:14Z","receivedAt":"2008-05-12T20:54:14Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Junio C Hamano, Mon, May 12, 2008 20:42:58 +0200:\n> >\n> > I corrected the series to use die() again and rebased it off current\n> > master (65ea3b8c). So it is more compatible with libification (does\n> > not hinder it more than previos code) and keep the exit code.\n> \n> But you did not answer my question in the part you did not quote, did you?\n\nI believe I did:\n\nDate:\tSun, 2 Mar 2008 22:42:41 +0100\nSubject: Re: [PATCH] Make the exit code of add_file_to_index actually useful\nMessage-ID: <20080302214241.GB13954@steel.home>\n\nJunio C Hamano, Sun, Mar 02, 2008 17:59:13 +0100:\n> Why is this even needed to begin with?  I am aware of Dirk's original\n> issue discussed elsewhere, but we try fairly hard to be A-O-N when we can\n> afford to, and this option deliberately breaks it.  What is the real\n> reason why such an unreadable (either for privilege or for I/O error)\n> file should not live in .gitignore?\n\nAnother program keeps the file open. There is an exclusive mode for\nopening files, which locks the files for everyone. I believe it is\neven default mode, unless selected otherwise.\n\n> Now when somebody either forgets to check the return value from this\n> function, or deliberately ignores it, the resulting index will not match\n> what the code is told to update it with.\n\nI think I got them all in the current code:\n\n    $git grep -E 'add_(file_)?to_(index|cache)'\n    Documentation/technical/api-in-core-index.txt:* add_file_to_index()\n    builtin-add.c:                  if (add_file_to_cache(path, data->flags\n    builtin-add.c:          if (add_file_to_cache(dir.entries[i]->name, ver\n    builtin-commit.c:                       if (add_to_cache(p->path, &st,\n    builtin-mv.c:                   if (add_file_to_cache(path, verbose))\n    cache.h:#define add_to_cache(path, st, verbose) add_to_index(&the_index\n    cache.h:#define add_file_to_cache(path, verbose) add_file_to_index(&the\n    cache.h:extern int add_to_index(struct index_state *, const char *path,\n    cache.h:extern int add_file_to_index(struct index_state *, const char *\n    read-cache.c:int add_to_index(struct index_state *istate, const char *p\n    read-cache.c:int add_file_to_index(struct index_state *istate, const ch\n    read-cache.c:   return add_to_index(istate, path, &st, verbose);\n\nRegarding the return value: isn't it very often a bug to ignore them?\nOr do you mean to say I should have renamed the function so that old\ninterface cannot be used accidentally by someone how just knows it\nnever returns in case of an error?\n"},{"id":"76802","messageId":"7viqxjxj0h.fsf@gitster.siamese.dyndns.org","threadId":"12408","inReplyTo":"20080512205414.GH3128@steel.home","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-05-12T22:19:42Z","receivedAt":"2008-05-12T22:19:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Alex Riesen <raa.lkml@gmail.com> writes:\n\n>> Why is this even needed to begin with?  I am aware of Dirk's original\n>> issue discussed elsewhere, but we try fairly hard to be A-O-N when we can\n>> afford to, and this option deliberately breaks it.  What is the real\n>> reason why such an unreadable (either for privilege or for I/O error)\n>> file should not live in .gitignore?\n>\n> Another program keeps the file open. There is an exclusive mode for\n> opening files, which locks the files for everyone. I believe it is\n> even default mode, unless selected otherwise.\n\nI would understand there can be some files that cannot be read.  But when\nthere is such a file, why is it Ok to ignore an error to update the\ncontents from that file if/when the user asks to index the current\ncontents, provided if the contents of that file is to be tracked?  Isn't\nit the true cause of the problem that the file is being tracked but it\nshouldn't?\n\n>> Now when somebody either forgets to check the return value from this\n>> function, or deliberately ignores it, the resulting index will not match\n>> what the code is told to update it with.\n>\n> I think I got them all in the current code...\n\nNot checking the return code from this function that now diagnoses and\nreturns error code is a bug as you said, and the codebase after your patch\nmay not have that bug.\n\nBut mistakes happen.\n\nThat is why I am asking why it is Ok to sometimes ignore the error to\nbegin with.  If we do not need to ignore this condition, then new callers\nhave one less thing to worry about, and we would have one less cause of an\nunnecessary bug.\n"},{"id":"76805","messageId":"20080512224844.GI3128@steel.home","threadId":"12408","inReplyTo":"7viqxjxj0h.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-05-12T22:48:44Z","receivedAt":"2008-05-12T22:48:44Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Junio C Hamano, Tue, May 13, 2008 00:19:42 +0200:\n> Alex Riesen <raa.lkml@gmail.com> writes:\n> \n> >> Why is this even needed to begin with?  I am aware of Dirk's original\n> >> issue discussed elsewhere, but we try fairly hard to be A-O-N when we can\n> >> afford to, and this option deliberately breaks it.  What is the real\n> >> reason why such an unreadable (either for privilege or for I/O error)\n> >> file should not live in .gitignore?\n> >\n> > Another program keeps the file open. There is an exclusive mode for\n> > opening files, which locks the files for everyone. I believe it is\n> > even default mode, unless selected otherwise.\n> \n> I would understand there can be some files that cannot be read.  But when\n> there is such a file, why is it Ok to ignore an error to update the\n> contents from that file if/when the user asks to index the current\n> contents, provided if the contents of that file is to be tracked?  Isn't\n> it the true cause of the problem that the file is being tracked but it\n> shouldn't?\n\nNo, I don't think so. Consider \"git add dir/\". It is _not_ 1 (one)\noperation. It is many operations (add every file in the \"dir/\"). Why\nshould all of them be considered failed just because the third file\nfrom the bottom could not be read (and the user may have not even seen\nit, because it wasn't there before, like a temporary file from Excel).\nAnd for a user (for me, at least) \"git add\" is an intermediate\noperation anyway: there'll be a review in form \"git status\" or \"git\ncommit\" afterwards. And there was a clear (sadly invisible with\n--verbose) warning regarding some file having problems.\n\n> >> Now when somebody either forgets to check the return value from this\n> >> function, or deliberately ignores it, the resulting index will not match\n> >> what the code is told to update it with.\n> >\n> > I think I got them all in the current code...\n> \n> Not checking the return code from this function that now diagnoses and\n> returns error code is a bug as you said, and the codebase after your patch\n> may not have that bug.\n> \n> But mistakes happen.\n> \n> That is why I am asking why it is Ok to sometimes ignore the error to\n> begin with.  If we do not need to ignore this condition, then new callers\n> have one less thing to worry about, and we would have one less cause of an\n> unnecessary bug.\n\nFor the reasons outlined? Where the user is in a situation when he has\nto override the safety checks. Just because it is more convenient to\ntype --ignore-errors than edit .gitignore and add there a whimsical\npatterns like \"~*.xls\", which one day have to be overridden because\nthat project got an excel file which begins with \"~\"?\n\nI am not suggesting making it default. And actually, the last patch,\nwith a config for add.ignore-errors option, better be ignored - it was\njust too simple to code up. I never used the option. I had cases for\n--ignore-errors, sadly.\n"},{"id":"76808","messageId":"7vve1jw130.fsf@gitster.siamese.dyndns.org","threadId":"12408","inReplyTo":"20080512224844.GI3128@steel.home","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-05-12T23:32:19Z","receivedAt":"2008-05-12T23:32:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Alex Riesen <raa.lkml@gmail.com> writes:\n\n> Junio C Hamano, Tue, May 13, 2008 00:19:42 +0200:\n> ...\n>> I would understand there can be some files that cannot be read.  But when\n>> there is such a file, why is it Ok to ignore an error to update the\n>> contents from that file if/when the user asks to index the current\n>> contents, provided if the contents of that file is to be tracked?  Isn't\n>> it the true cause of the problem that the file is being tracked but it\n>> shouldn't?\n>\n> No, I don't think so. Consider \"git add dir/\". It is _not_ 1 (one)\n> operation. It is many operations (add every file in the \"dir/\"). Why\n> should all of them be considered failed just because the third file\n> from the bottom could not be read (and the user may have not even seen\n> it, because it wasn't there before, like a temporary file from Excel).\n> And for a user (for me, at least) \"git add\" is an intermediate\n> operation anyway...\n\nAh, Ok, I was overly cautious, and the worry is unfounded, as long as you\ndo not trigger this \"ignore\" thing upon \"git commit -a\".\n\nThanks.  Will queue.\n"},{"id":"76827","messageId":"7v3aomx3sp.fsf@gitster.siamese.dyndns.org","threadId":"12408","inReplyTo":"20080512175848.GF3128@steel.home","subject":"Re: [PATCH] Add a test for git-add --ignore-errors","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-05-13T03:48:22Z","receivedAt":"2008-05-13T03:48:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Alex Riesen <raa.lkml@gmail.com> writes:\n\n> Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n> ---\n>  t/t3700-add.sh |    9 +++++++++\n>  1 files changed, 9 insertions(+), 0 deletions(-)\n>\n> diff --git a/t/t3700-add.sh b/t/t3700-add.sh\n> index 287e058..ca3e33d 100755\n> --- a/t/t3700-add.sh\n> +++ b/t/t3700-add.sh\n> @@ -179,4 +179,13 @@ test_expect_success 'git add --refresh' '\n>  \ttest -z \"`git diff-index HEAD -- foo`\"\n>  '\n>  \n> +test_expect_success 'git add --ignore-errors' '\n> +\tgit reset --hard &&\n> +\tdate >foo1 &&\n> +\tdate >foo2 &&\n> +\tchmod 0 foo2 &&\n> +\tgit add --verbose --ignore-errors .\n> +\tgit ls-files |grep foo1\n> +'\n> +\n>  test_done\n\nI like the fact that you added --ignore-errors and made it still error out\nwhen it cannot read some files.  Shouldn't we be testing it here with\n\"must-fail\"?\n"},{"id":"76833","messageId":"20080513060013.GA3622@steel.home","threadId":"12408","inReplyTo":"7vve1jw130.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Make the exit code of add_file_to_index actually useful","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-05-13T06:00:13Z","receivedAt":"2008-05-13T06:00:13Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Junio C Hamano, Tue, May 13, 2008 01:32:19 +0200:\n> Alex Riesen <raa.lkml@gmail.com> writes:\n> \n> > Junio C Hamano, Tue, May 13, 2008 00:19:42 +0200:\n> > ...\n> >> I would understand there can be some files that cannot be read.  But when\n> >> there is such a file, why is it Ok to ignore an error to update the\n> >> contents from that file if/when the user asks to index the current\n> >> contents, provided if the contents of that file is to be tracked?  Isn't\n> >> it the true cause of the problem that the file is being tracked but it\n> >> shouldn't?\n> >\n> > No, I don't think so. Consider \"git add dir/\". It is _not_ 1 (one)\n> > operation. It is many operations (add every file in the \"dir/\"). Why\n> > should all of them be considered failed just because the third file\n> > from the bottom could not be read (and the user may have not even seen\n> > it, because it wasn't there before, like a temporary file from Excel).\n> > And for a user (for me, at least) \"git add\" is an intermediate\n> > operation anyway...\n> \n> Ah, Ok, I was overly cautious, and the worry is unfounded, as long as you\n> do not trigger this \"ignore\" thing upon \"git commit -a\".\n\nYes, builtin-commit.c explicitely keeps its behaviour: the 0 in flags\nargument makes sure die() is called. \"Ignore errors\" must be requested\nwith ADD_FILES_IGNORE_ERRORS.\n"},{"id":"76834","messageId":"20080513060453.GB3622@steel.home","threadId":"12408","inReplyTo":"7v3aomx3sp.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Add a test for git-add --ignore-errors","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-05-13T06:04:53Z","receivedAt":"2008-05-13T06:04:53Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\nJunio C Hamano, Tue, May 13, 2008 05:48:22 +0200:\n> Alex Riesen <raa.lkml@gmail.com> writes:\n> > +test_expect_success 'git add --ignore-errors' '\n> > +\tgit reset --hard &&\n> > +\tdate >foo1 &&\n> > +\tdate >foo2 &&\n> > +\tchmod 0 foo2 &&\n> > +\tgit add --verbose --ignore-errors .\n> > +\tgit ls-files |grep foo1\n> > +'\n> > +\n> >  test_done\n> \n> I like the fact that you added --ignore-errors and made it still error out\n> when it cannot read some files.  Shouldn't we be testing it here with\n> \"must-fail\"?\n\nYes. Would you mind replacing that patch with this one?\n\n t/t3700-add.sh |    9 +++++++++\n 1 files changed, 9 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t3700-add.sh b/t/t3700-add.sh\nindex 287e058..17ab05a 100755\n--- a/t/t3700-add.sh\n+++ b/t/t3700-add.sh\n@@ -179,4 +179,13 @@ test_expect_success 'git add --refresh' '\n \ttest -z \"`git diff-index HEAD -- foo`\"\n '\n \n+test_expect_success 'git add --ignore-errors' '\n+\tgit reset --hard &&\n+\tdate >foo1 &&\n+\tdate >foo2 &&\n+\tchmod 0 foo2 &&\n+\ttest_must_fail git add --verbose --ignore-errors . &&\n+\tgit ls-files |grep foo1\n+'\n+\n test_done\n-- \n1.5.5.1.206.g7103c\n"},{"id":"76835","messageId":"7vhcd2viwi.fsf@gitster.siamese.dyndns.org","threadId":"12408","inReplyTo":"7v3aomx3sp.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Add a test for git-add --ignore-errors","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-05-13T06:05:01Z","receivedAt":"2008-05-13T06:05:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junio@pobox.com> writes:\n\n> Alex Riesen <raa.lkml@gmail.com> writes:\n>\n>> Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n>> ---\n>>  t/t3700-add.sh |    9 +++++++++\n>>  1 files changed, 9 insertions(+), 0 deletions(-)\n>>\n>> diff --git a/t/t3700-add.sh b/t/t3700-add.sh\n>> index 287e058..ca3e33d 100755\n>> --- a/t/t3700-add.sh\n>> +++ b/t/t3700-add.sh\n>> @@ -179,4 +179,13 @@ test_expect_success 'git add --refresh' '\n>>  \ttest -z \"`git diff-index HEAD -- foo`\"\n>>  '\n>>  \n>> +test_expect_success 'git add --ignore-errors' '\n>> +\tgit reset --hard &&\n>> +\tdate >foo1 &&\n>> +\tdate >foo2 &&\n>> +\tchmod 0 foo2 &&\n>> +\tgit add --verbose --ignore-errors .\n>> +\tgit ls-files |grep foo1\n>> +'\n>> +\n>>  test_done\n>\n> I like the fact that you added --ignore-errors and made it still error out\n> when it cannot read some files.  Shouldn't we be testing it here with\n> \"must-fail\"?\n\nIt is human nature to get too enthusiastic demonstrating his own shiny new\ntoy and forget to check that it does not kick in when not asked.  There is\nno test for a case to make sure \"git add\" fails when foo2 is not readable\nand does not add \"foo1\".\n\nHere is a replacement I've queued.  I have a similar addition to the test\nin the patch after this one that demonstrates the configuration variable.\nI added tests to check the case when the variable is set to false.\n\n-- >8 --\nAdd a test for git-add --ignore-errors\n\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/t3700-add.sh |   22 ++++++++++++++++++++++\n 1 files changed, 22 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t3700-add.sh b/t/t3700-add.sh\nindex 287e058..01e4d62 100755\n--- a/t/t3700-add.sh\n+++ b/t/t3700-add.sh\n@@ -179,4 +179,26 @@ test_expect_success 'git add --refresh' '\n \ttest -z \"`git diff-index HEAD -- foo`\"\n '\n \n+test_expect_success 'git add should fail atomically upon an unreadable file' '\n+\tgit reset --hard &&\n+\tdate >foo1 &&\n+\tdate >foo2 &&\n+\tchmod 0 foo2 &&\n+\ttest_must_fail git add --verbose . &&\n+\t! ( git ls-files foo1 | grep foo1 )\n+'\n+\n+rm -f foo2\n+\n+test_expect_success 'git add --ignore-errors' '\n+\tgit reset --hard &&\n+\tdate >foo1 &&\n+\tdate >foo2 &&\n+\tchmod 0 foo2 &&\n+\ttest_must_fail git add --verbose --ignore-errors . &&\n+\tgit ls-files foo1 | grep foo1\n+'\n+\n+rm -f foo2\n+\n test_done\n-- \n1.5.5.1.340.g39dc6\n"},{"id":"76891","messageId":"20080513222802.GC3981@steel.home","threadId":"12408","inReplyTo":"7vhcd2viwi.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Add a test for git-add --ignore-errors","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-05-13T22:28:02Z","receivedAt":"2008-05-13T22:28:02Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Junio C Hamano, Tue, May 13, 2008 08:05:01 +0200:\n> Junio C Hamano <junio@pobox.com> writes:\n> \n> > Alex Riesen <raa.lkml@gmail.com> writes:\n> >\n> >> Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n> >> ---\n> >>  t/t3700-add.sh |    9 +++++++++\n> >>  1 files changed, 9 insertions(+), 0 deletions(-)\n> >>\n> >> diff --git a/t/t3700-add.sh b/t/t3700-add.sh\n> >> index 287e058..ca3e33d 100755\n> >> --- a/t/t3700-add.sh\n> >> +++ b/t/t3700-add.sh\n> >> @@ -179,4 +179,13 @@ test_expect_success 'git add --refresh' '\n> >>  \ttest -z \"`git diff-index HEAD -- foo`\"\n> >>  '\n> >>  \n> >> +test_expect_success 'git add --ignore-errors' '\n> >> +\tgit reset --hard &&\n> >> +\tdate >foo1 &&\n> >> +\tdate >foo2 &&\n> >> +\tchmod 0 foo2 &&\n> >> +\tgit add --verbose --ignore-errors .\n> >> +\tgit ls-files |grep foo1\n> >> +'\n> >> +\n> >>  test_done\n> >\n> > I like the fact that you added --ignore-errors and made it still error out\n> > when it cannot read some files.  Shouldn't we be testing it here with\n> > \"must-fail\"?\n> \n> It is human nature to get too enthusiastic demonstrating his own shiny new\n> toy and forget to check that it does not kick in when not asked.  There is\n> no test for a case to make sure \"git add\" fails when foo2 is not readable\n> and does not add \"foo1\".\n\nYes, I missed that. Exactly for the reason :)\n\n> Here is a replacement I've queued.  I have a similar addition to the test\n> in the patch after this one that demonstrates the configuration variable.\n> I added tests to check the case when the variable is set to false.\n\nThanks.\n\n> -- >8 --\n> Add a test for git-add --ignore-errors\n> \n> Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n\nAcked-by: Alex Riesen <raa.lkml@gmail.com>\n"}]}