{"thread":{"id":"22867","subject":"[PATCH 2/4] convert: Keep foreign $Id$ on checkout.","startedAt":"2010-03-01T16:16:55Z","lastAt":"2010-03-09T09:22:29Z","messageCount":9,"participants":["Henrik Grubbström","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"135953","messageId":"1267460218-1172-1-git-send-email-grubba@grubba.org","threadId":"22867","inReplyTo":null,"subject":"[PATCH 1/4] convert: Safer handling of $Id$ contraction.","fromName":"Henrik Grubbström","fromEmail":"grubba@grubba.org","sentAt":"2010-03-01T16:16:55Z","receivedAt":"2010-03-01T16:16:55Z","isPatch":true,"sender":{"key":"grubba@grubba.org","avatar":"https://avatars.githubusercontent.com/u/1169458?v=4"},"body":"From: Henrik Grubbström (Grubba) <grubba@grubba.org>\n\nThe code to contract $Id:xxxxx$ strings could eat an arbitrary amount\nof source text if the terminating $ was lost. It now refuses to\ncontract $Id:xxxxx$ strings spanning multiple lines.\n\nSigned-off-by: Henrik Grubbström <grubba@grubba.org>\n---\n convert.c |   17 +++++++++++++++--\n 1 files changed, 15 insertions(+), 2 deletions(-)\n\ndiff --git a/convert.c b/convert.c\nindex 4f8fcb7..91207ab 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -425,6 +425,7 @@ static int count_ident(const char *cp, unsigned long size)\n \t\t\t\tcnt++;\n \t\t\t\tbreak;\n \t\t\t}\n+\t\t\tif (ch == '\\n') break;\n \t\t}\n \t}\n \treturn cnt;\n@@ -433,7 +434,7 @@ static int count_ident(const char *cp, unsigned long size)\n static int ident_to_git(const char *path, const char *src, size_t len,\n                         struct strbuf *buf, int ident)\n {\n-\tchar *dst, *dollar;\n+\tchar *dst, *dollar, *nl;\n \n \tif (!ident || !count_ident(src, len))\n \t\treturn 0;\n@@ -455,6 +456,12 @@ static int ident_to_git(const char *path, const char *src, size_t len,\n \t\t\tdollar = memchr(src + 3, '$', len - 3);\n \t\t\tif (!dollar)\n \t\t\t\tbreak;\n+\t\t\tnl = memchr(src + 3, '\\n', len - 3);\n+\t\t\tif (nl && nl < dollar) {\n+\t\t\t\t/* Line break before the next dollar. */\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n \t\t\tmemcpy(dst, \"Id$\", 3);\n \t\t\tdst += 3;\n \t\t\tlen -= dollar + 1 - src;\n@@ -470,7 +477,7 @@ static int ident_to_worktree(const char *path, const char *src, size_t len,\n                              struct strbuf *buf, int ident)\n {\n \tunsigned char sha1[20];\n-\tchar *to_free = NULL, *dollar;\n+\tchar *to_free = NULL, *dollar, *nl;\n \tint cnt;\n \n \tif (!ident)\n@@ -514,6 +521,12 @@ static int ident_to_worktree(const char *path, const char *src, size_t len,\n \t\t\t\tbreak;\n \t\t\t}\n \n+\t\t\tnl = memchr(src + 3, '\\n', len - 3);\n+\t\t\tif (nl && nl < dollar) {\n+\t\t\t\t/* Line break before the next dollar. */\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n \t\t\tlen -= dollar + 1 - src;\n \t\t\tsrc  = dollar + 1;\n \t\t} else {\n-- \n1.6.4.122.g6ffd7\n"},{"id":"135951","messageId":"1267460218-1172-2-git-send-email-grubba@grubba.org","threadId":"22867","inReplyTo":"1267460218-1172-1-git-send-email-grubba@grubba.org","subject":"[PATCH 2/4] convert: Keep foreign $Id$ on checkout.","fromName":"Henrik Grubbström","fromEmail":"grubba@grubba.org","sentAt":"2010-03-01T16:16:56Z","receivedAt":"2010-03-01T16:16:56Z","isPatch":true,"sender":{"key":"grubba@grubba.org","avatar":"https://avatars.githubusercontent.com/u/1169458?v=4"},"body":"From: Henrik Grubbström (Grubba) <grubba@grubba.org>\n\nIf there are foreign $Id$ keywords in the repository, they are most\nlikely there for a reason. Let's keep them on checkout (which is also\nwhat the documentation indicates). Foreign $Id$ keywords are now\nrecognized by there being multiple space separated fields in $Id:xxxxx$.\n\nSigned-off-by: Henrik Grubbström <grubba@grubba.org>\n---\n convert.c |   14 +++++++++++++-\n 1 files changed, 13 insertions(+), 1 deletions(-)\n\ndiff --git a/convert.c b/convert.c\nindex 91207ab..28aeea3 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -513,7 +513,10 @@ static int ident_to_worktree(const char *path, const char *src, size_t len,\n \t\t} else if (src[2] == ':') {\n \t\t\t/*\n \t\t\t * It's possible that an expanded Id has crept its way into the\n-\t\t\t * repository, we cope with that by stripping the expansion out\n+\t\t\t * repository, we cope with that by stripping the expansion out.\n+\t\t\t * This is probably not a good idea, since it will cause changes\n+\t\t\t * on checkout, which won't go away by stash, but let's keep it\n+\t\t\t * for git-style ids.\n \t\t\t */\n \t\t\tdollar = memchr(src + 3, '$', len - 3);\n \t\t\tif (!dollar) {\n@@ -527,6 +530,15 @@ static int ident_to_worktree(const char *path, const char *src, size_t len,\n \t\t\t\tcontinue;\n \t\t\t}\n \n+\t\t\tif ((src[3] != ' ') ||\n+\t\t\t    (memchr(src + 4, ' ', len - 4) != dollar-1)) {\n+\t\t\t\t/* There are spaces in unexpected places.\n+\t\t\t\t * This is probably an id from some other\n+\t\t\t\t * versioning system. Keep it for now.\n+\t\t\t\t */\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n \t\t\tlen -= dollar + 1 - src;\n \t\t\tsrc  = dollar + 1;\n \t\t} else {\n-- \n1.6.4.122.g6ffd7\n"},{"id":"135952","messageId":"1267460218-1172-3-git-send-email-grubba@grubba.org","threadId":"22867","inReplyTo":"1267460218-1172-2-git-send-email-grubba@grubba.org","subject":"[PATCH 3/4] convert: Inhibit contraction of foreign $Id$ during stats.","fromName":"Henrik Grubbström","fromEmail":"grubba@grubba.org","sentAt":"2010-03-01T16:16:57Z","receivedAt":"2010-03-01T16:16:57Z","isPatch":true,"sender":{"key":"grubba@grubba.org","avatar":"https://avatars.githubusercontent.com/u/1169458?v=4"},"body":"From: Henrik Grubbström (Grubba) <grubba@grubba.org>\n\nFiles containing foreign $Id$'s were reported as modified directly\non checkout, which ment that it was difficult to keep a clean working\ntree when handling commits with files containing such. convert_to_git()\nnow takes one more mode parameter for controlling this.\n\nSigned-off-by: Henrik Grubbström <grubba@grubba.org>\n---\n builtin-apply.c |    2 +-\n builtin-blame.c |    2 +-\n cache.h         |    8 +++++++-\n combine-diff.c  |    2 +-\n convert.c       |   20 +++++++++++++++++---\n diff.c          |    2 +-\n sha1_file.c     |    3 ++-\n 7 files changed, 30 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin-apply.c b/builtin-apply.c\nindex 3af4ae0..25adef8 100644\n--- a/builtin-apply.c\n+++ b/builtin-apply.c\n@@ -1759,7 +1759,7 @@ static int read_old_data(struct stat *st, const char *path, struct strbuf *buf)\n \tcase S_IFREG:\n \t\tif (strbuf_read_file(buf, path, st->st_size) != st->st_size)\n \t\t\treturn error(\"unable to open or read %s\", path);\n-\t\tconvert_to_git(path, buf->buf, buf->len, buf, 0);\n+\t\tconvert_to_git(path, buf->buf, buf->len, buf, 0, 0);\n \t\treturn 0;\n \tdefault:\n \t\treturn -1;\ndiff --git a/builtin-blame.c b/builtin-blame.c\nindex 10f7eac..f21bf3d 100644\n--- a/builtin-blame.c\n+++ b/builtin-blame.c\n@@ -2050,7 +2050,7 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con\n \t\tif (strbuf_read(&buf, 0, 0) < 0)\n \t\t\tdie_errno(\"failed to read from stdin\");\n \t}\n-\tconvert_to_git(path, buf.buf, buf.len, &buf, 0);\n+\tconvert_to_git(path, buf.buf, buf.len, &buf, 0, 0);\n \torigin->file.ptr = buf.buf;\n \torigin->file.size = buf.len;\n \tpretend_sha1_file(buf.buf, buf.len, OBJ_BLOB, origin->blob_sha1);\ndiff --git a/cache.h b/cache.h\nindex d478eff..1c9f491 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -547,6 +547,11 @@ enum safe_crlf {\n \tSAFE_CRLF_WARN = 2,\n };\n \n+enum ident_mode {\n+\tIDENT_MODE_FALSE = 0,\n+\tIDENT_MODE_KEEP_FOREIGN = 1,\n+};\n+\n extern enum safe_crlf safe_crlf;\n \n enum branch_track {\n@@ -996,7 +1001,8 @@ extern void trace_argv_printf(const char **argv, const char *format, ...);\n /* convert.c */\n /* returns 1 if *dst was used */\n extern int convert_to_git(const char *path, const char *src, size_t len,\n-                          struct strbuf *dst, enum safe_crlf checksafe);\n+                          struct strbuf *dst, enum safe_crlf checksafe,\n+                          enum ident_mode identmode);\n extern int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst);\n \n /* add */\ndiff --git a/combine-diff.c b/combine-diff.c\nindex 6162691..8c9320a 100644\n--- a/combine-diff.c\n+++ b/combine-diff.c\n@@ -758,7 +758,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,\n \t\t\tif (is_file) {\n \t\t\t\tstruct strbuf buf = STRBUF_INIT;\n \n-\t\t\t\tif (convert_to_git(elem->path, result, len, &buf, safe_crlf)) {\n+\t\t\t\tif (convert_to_git(elem->path, result, len, &buf, safe_crlf, 0)) {\n \t\t\t\t\tfree(result);\n \t\t\t\t\tresult = strbuf_detach(&buf, &len);\n \t\t\t\t\tresult_size = len;\ndiff --git a/convert.c b/convert.c\nindex 28aeea3..c053bcd 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -432,7 +432,8 @@ static int count_ident(const char *cp, unsigned long size)\n }\n \n static int ident_to_git(const char *path, const char *src, size_t len,\n-                        struct strbuf *buf, int ident)\n+                        struct strbuf *buf, int ident,\n+                        enum ident_mode identmode)\n {\n \tchar *dst, *dollar, *nl;\n \n@@ -462,6 +463,18 @@ static int ident_to_git(const char *path, const char *src, size_t len,\n \t\t\t\tcontinue;\n \t\t\t}\n \n+\t\t\tif ((identmode == IDENT_MODE_KEEP_FOREIGN) &&\n+\t\t\t    ((src[3] != ' ') ||\n+\t\t\t     (memchr(src + 4, ' ', len - 4) != dollar-1))) {\n+\t\t\t\t/* Foreign id.\n+\t\t\t\t * Contraction of these is inhibited during\n+\t\t\t\t * status operations to avoid all files\n+\t\t\t\t * containing such being marked as modified\n+\t\t\t\t * on checkout. cf sha1_file.c:index_mem().\n+\t\t\t\t */\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n \t\t\tmemcpy(dst, \"Id$\", 3);\n \t\t\tdst += 3;\n \t\t\tlen -= dollar + 1 - src;\n@@ -594,7 +607,8 @@ static int git_path_check_ident(const char *path, struct git_attr_check *check)\n }\n \n int convert_to_git(const char *path, const char *src, size_t len,\n-                   struct strbuf *dst, enum safe_crlf checksafe)\n+                   struct strbuf *dst, enum safe_crlf checksafe,\n+                   enum ident_mode identmode)\n {\n \tstruct git_attr_check check[3];\n \tint crlf = CRLF_GUESS;\n@@ -621,7 +635,7 @@ int convert_to_git(const char *path, const char *src, size_t len,\n \t\tsrc = dst->buf;\n \t\tlen = dst->len;\n \t}\n-\treturn ret | ident_to_git(path, src, len, dst, ident);\n+\treturn ret | ident_to_git(path, src, len, dst, ident, identmode);\n }\n \n int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst)\ndiff --git a/diff.c b/diff.c\nindex 989dbc5..64726c8 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -2113,7 +2113,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)\n \t\t/*\n \t\t * Convert from working tree format to canonical git format\n \t\t */\n-\t\tif (convert_to_git(s->path, s->data, s->size, &buf, safe_crlf)) {\n+\t\tif (convert_to_git(s->path, s->data, s->size, &buf, safe_crlf, 0)) {\n \t\t\tsize_t size = 0;\n \t\t\tmunmap(s->data, s->size);\n \t\t\ts->should_munmap = 0;\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 657825e..fd8c5df 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -2419,7 +2419,8 @@ static int index_mem(unsigned char *sha1, void *buf, size_t size,\n \tif ((type == OBJ_BLOB) && path) {\n \t\tstruct strbuf nbuf = STRBUF_INIT;\n \t\tif (convert_to_git(path, buf, size, &nbuf,\n-\t\t                   write_object ? safe_crlf : 0)) {\n+\t\t                   write_object ? safe_crlf : 0,\n+\t\t                   write_object ? 0 : IDENT_MODE_KEEP_FOREIGN)) {\n \t\t\tbuf = strbuf_detach(&nbuf, &size);\n \t\t\tre_allocated = 1;\n \t\t}\n-- \n1.6.4.122.g6ffd7\n"},{"id":"135954","messageId":"1267460218-1172-4-git-send-email-grubba@grubba.org","threadId":"22867","inReplyTo":"1267460218-1172-3-git-send-email-grubba@grubba.org","subject":"[PATCH 4/4] convert: Added core.refilteronadd feature.","fromName":"Henrik Grubbström","fromEmail":"grubba@grubba.org","sentAt":"2010-03-01T16:16:58Z","receivedAt":"2010-03-01T16:16:58Z","isPatch":true,"sender":{"key":"grubba@grubba.org","avatar":"https://avatars.githubusercontent.com/u/1169458?v=4"},"body":"From: Henrik Grubbström (Grubba) <grubba@grubba.org>\n\nWhen having $Id$ tags in other versioning systems, it is customary\nto recalculate the tags in the source on commit or equvivalent.\nThis commit adds a configuration option to git that causes source\nfiles to pass through a conversion roundtrip when added to the index.\n\nSigned-off-by: Henrik Grubbström <grubba@grubba.org>\n---\n Documentation/config.txt |    6 +++++\n cache.h                  |    1 +\n config.c                 |    5 ++++\n environment.c            |    1 +\n sha1_file.c              |   57 ++++++++++++++++++++++++++++++++++++++++++++++\n 5 files changed, 70 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 664de6b..900b095 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -533,6 +533,12 @@ core.sparseCheckout::\n \tEnable \"sparse checkout\" feature. See section \"Sparse checkout\" in\n \tlinkgit:git-read-tree[1] for more information.\n \n+core.refilterOnAdd::\n+\tEnable \"refilter on add\" feature. This causes source files to be\n+\tbehave as if they were checked out after a linkgit:git-add[1].\n+\tThis is typically usefull if eg the `ident` attribute is active,\n+\tin which case the $Id$ tags will be updated.\n+\n add.ignore-errors::\n \tTells 'git add' to continue adding files when some files cannot be\n \tadded due to indexing errors. Equivalent to the '--ignore-errors'\ndiff --git a/cache.h b/cache.h\nindex 1c9f491..beb60f9 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -540,6 +540,7 @@ extern int read_replace_refs;\n extern int fsync_object_files;\n extern int core_preload_index;\n extern int core_apply_sparse_checkout;\n+extern int core_refilter_on_add;\n \n enum safe_crlf {\n \tSAFE_CRLF_FALSE = 0,\ndiff --git a/config.c b/config.c\nindex 6963fbe..b1db505 100644\n--- a/config.c\n+++ b/config.c\n@@ -523,6 +523,11 @@ static int git_default_core_config(const char *var, const char *value)\n \t\treturn 0;\n \t}\n \n+\tif (!strcmp(var, \"core.refilteronadd\")) {\n+\t\tcore_refilter_on_add = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n+\n \t/* Add other config variables here and to Documentation/config.txt. */\n \treturn 0;\n }\ndiff --git a/environment.c b/environment.c\nindex 739ec27..eed7ef1 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -52,6 +52,7 @@ enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;\n char *notes_ref_name;\n int grafts_replace_parents = 1;\n int core_apply_sparse_checkout;\n+int core_refilter_on_add;\n \n /* Parallel index stat data preload? */\n int core_preload_index = 0;\ndiff --git a/sha1_file.c b/sha1_file.c\nindex fd8c5df..f2659cb 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -2459,6 +2459,54 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object,\n \treturn ret;\n }\n \n+static int refilter_fd(int fd, struct stat *st, const char *path)\n+{\n+\tint ret = -1;\n+\tsize_t size = xsize_t(st->st_size);\n+\tstruct strbuf gbuf = STRBUF_INIT;\n+\n+\tif (!S_ISREG(st->st_mode)) {\n+\t\tstruct strbuf sbuf = STRBUF_INIT;\n+\t\tif (strbuf_read(&sbuf, fd, 4096) >= 0)\n+\t\t\tret = convert_to_git(path, sbuf.buf, sbuf.len, &gbuf, safe_crlf, 0);\n+\t\telse\n+\t\t\tret = -1;\n+\t\tstrbuf_release(&sbuf);\n+\t} else if (size) {\n+\t\tvoid *buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);\n+\t\tret = convert_to_git(path, buf, size, &gbuf, safe_crlf, 0);\n+\t\tmunmap(buf, size);\n+\t} else\n+\t\tret = -1;\n+\n+\tif (ret > 0) {\n+\t\t/* Something happened during conversion to git.\n+\t\t * Now convert it back, and save the result.\n+\t\t */\n+\t\tstruct strbuf obuf = STRBUF_INIT;\n+\n+\t\tlseek(fd, 0, SEEK_SET);\n+\n+\t\tif (convert_to_working_tree(path, gbuf.buf, gbuf.len, &obuf)) {\n+\t\t\tif (write_or_whine(fd, obuf.buf, obuf.len, path))\n+\t\t\t\tftruncate(fd, obuf.len);\n+\t\t\telse\n+\t\t\t\tret = -1;\n+\t\t} else {\n+\t\t\tif (write_or_whine(fd, gbuf.buf, gbuf.len, path))\n+\t\t\t\tftruncate(fd, gbuf.len);\n+\t\t\telse\n+\t\t\t\tret = -1;\n+\t\t}\n+\n+\t\tstrbuf_release(&obuf);\n+\t}\n+\tstrbuf_release(&gbuf);\n+\n+\tclose(fd);\n+\treturn ret;\n+}\n+\n int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object)\n {\n \tint fd;\n@@ -2473,6 +2521,15 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, int write\n \t\tif (index_fd(sha1, fd, st, write_object, OBJ_BLOB, path) < 0)\n \t\t\treturn error(\"%s: failed to insert into database\",\n \t\t\t\t     path);\n+\t\tif (write_object && core_refilter_on_add) {\n+\t\t\tfd = open(path, O_RDWR);\n+\t\t\tif (fd < 0)\n+\t\t\t\treturn error(\"open(\\\"%s\\\"): %s\", path,\n+\t\t\t\t\t     strerror(errno));\n+\t\t\tif (refilter_fd(fd, st, path) < 0)\n+\t\t\t\treturn error(\"%s: failed to refilter file\",\n+\t\t\t\t\t     path);\n+\t\t}\n \t\tbreak;\n \tcase S_IFLNK:\n \t\tif (strbuf_readlink(&sb, path, st->st_size)) {\n-- \n1.6.4.122.g6ffd7\n"},{"id":"136050","messageId":"7vljeamcpq.fsf@alter.siamese.dyndns.org","threadId":"22867","inReplyTo":"1267460218-1172-1-git-send-email-grubba@grubba.org","subject":"Re: [PATCH 1/4] convert: Safer handling of $Id$ contraction.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-03T01:10:57Z","receivedAt":"2010-03-03T01:10:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Henrik Grubbström <grubba@grubba.org> writes:\n\n> From: Henrik Grubbström (Grubba) <grubba@grubba.org>\n\nYou can omit this line, as it is the same as your From: header.\n\n> The code to contract $Id:xxxxx$ strings could eat an arbitrary amount\n> of source text if the terminating $ was lost. It now refuses to\n> contract $Id:xxxxx$ strings spanning multiple lines.\n\nHmm, at least when going from working tree to the index, shouldn't the\ncode refuse _and_ die(), instead of silently pass the garbage through?\n"},{"id":"136052","messageId":"7vfx4imcpl.fsf@alter.siamese.dyndns.org","threadId":"22867","inReplyTo":"1267460218-1172-2-git-send-email-grubba@grubba.org","subject":"Re: [PATCH 2/4] convert: Keep foreign $Id$ on checkout.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-03T01:11:02Z","receivedAt":"2010-03-03T01:11:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Henrik Grubbström <grubba@grubba.org> writes:\n\n> If there are foreign $Id$ keywords in the repository, they are most\n> likely there for a reason.\n\nIf so what is the user doing by using \"ident\" attribute?\n"},{"id":"136066","messageId":"Pine.GSO.4.63.1003031129340.1164@shipon.roxen.com","threadId":"22867","inReplyTo":"7vljeamcpq.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/4] convert: Safer handling of $Id$ contraction.","fromName":"Henrik Grubbström","fromEmail":"grubba@roxen.com","sentAt":"2010-03-03T10:40:00Z","receivedAt":"2010-03-03T10:40:00Z","isPatch":true,"sender":{"key":"grubba@roxen.com","avatar":null},"body":"On Tue, 2 Mar 2010, Junio C Hamano wrote:\n\n> Henrik Grubbström <grubba@grubba.org> writes:\n>\n>> From: Henrik Grubbström (Grubba) <grubba@grubba.org>\n>\n> You can omit this line, as it is the same as your From: header.\n\nI blame git-send-email(1).\n\n>> The code to contract $Id:xxxxx$ strings could eat an arbitrary amount\n>> of source text if the terminating $ was lost. It now refuses to\n>> contract $Id:xxxxx$ strings spanning multiple lines.\n>\n> Hmm, at least when going from working tree to the index, shouldn't the\n> code refuse _and_ die(), instead of silently pass the garbage through?\n\nIt depends; it could be part of some code that scans for the $Id: tag.\nA warning might be appropriate though.\n\n--\nHenrik Grubbström\t\t\t\t\tgrubba@grubba.org\nRoxen Internet Software AB\t\t\t\tgrubba@roxen.com"},{"id":"136071","messageId":"Pine.GSO.4.63.1003031140110.1164@shipon.roxen.com","threadId":"22867","inReplyTo":"7vfx4imcpl.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/4] convert: Keep foreign $Id$ on checkout.","fromName":"Henrik Grubbström","fromEmail":"grubba@grubba.org","sentAt":"2010-03-03T11:36:26Z","receivedAt":"2010-03-03T11:36:26Z","isPatch":true,"sender":{"key":"grubba@grubba.org","avatar":"https://avatars.githubusercontent.com/u/1169458?v=4"},"body":"On Tue, 2 Mar 2010, Junio C Hamano wrote:\n\n> Henrik Grubbström <grubba@grubba.org> writes:\n>\n>> If there are foreign $Id$ keywords in the repository, they are most\n>> likely there for a reason.\n>\n> If so what is the user doing by using \"ident\" attribute?\n\nExample:\n\n   The user has recently converted from a different versioning system,\n   and kept the $Id$ tags from that system verbatim since they have been\n   refered to by external systems (eg bug reports, etc).\n\n   Having the ident property active (with my patches) will cause the $Id$\n   tag to be zapped as soon as (but not before) the file is altered.\n\n--\nHenrik Grubbström\t\t\t\t\tgrubba@grubba.org\nRoxen Internet Software AB\t\t\t\tgrubba@roxen.com"},{"id":"136426","messageId":"Pine.GSO.4.63.1003081951000.1164@shipon.roxen.com","threadId":"22867","inReplyTo":"Pine.GSO.4.63.1003031129340.1164@shipon.roxen.com","subject":"Re: [PATCH 1/4] convert: Safer handling of $Id$ contraction.","fromName":"Henrik Grubbström","fromEmail":"grubba@roxen.com","sentAt":"2010-03-09T09:22:29Z","receivedAt":"2010-03-09T09:22:29Z","isPatch":true,"sender":{"key":"grubba@roxen.com","avatar":null},"body":"On Wed, 3 Mar 2010, Henrik Grubbström wrote:\n\n> On Tue, 2 Mar 2010, Junio C Hamano wrote:\n>\n>> Henrik Grubbström <grubba@grubba.org> writes:\n>> \n>>> The code to contract $Id:xxxxx$ strings could eat an arbitrary amount\n>>> of source text if the terminating $ was lost. It now refuses to\n>>> contract $Id:xxxxx$ strings spanning multiple lines.\n>> \n>> Hmm, at least when going from working tree to the index, shouldn't the\n>> code refuse _and_ die(), instead of silently pass the garbage through?\n>\n> It depends; it could be part of some code that scans for the $Id: tag.\n> A warning might be appropriate though.\n\nA nonscientific survey of some version control systems gives:\n\nVCS\t\tId-keyword\tEats linefeed\n-------------------------------------------------\nbzr\t\tno\t\t-\ncvs\t\tyes\t\tno, silent accept\ngit(1.7.0)\tyes\t\tyes, silent\nhg\t\tyes(hgext)\tno, silent accept\nmonotone\tno\t\t-\nrcs\t\tyes\t\tno, silent accept\nsvn\t\tyes\t\tno, silent accept\n\nSo it seems my original patch is in line with what other version control \nsystems do.\n\n--\nHenrik Grubbström\t\t\t\t\tgrubba@grubba.org\nRoxen Internet Software AB\t\t\t\tgrubba@roxen.com"}]}