{"thread":{"id":"7051","subject":"[PATCH] Add core.symlinks to mark filesystems that do not support symbolic links.","startedAt":"2007-03-02T21:11:30Z","lastAt":"2007-03-03T12:44:07Z","messageCount":8,"participants":["Johannes Sixt","Johannes Schindelin","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"36128","messageId":"200703022211.30322.johannes.sixt@telecom.at","threadId":"7051","inReplyTo":null,"subject":"[PATCH] Add core.symlinks to mark filesystems that do not support symbolic links.","fromName":"Johannes Sixt","fromEmail":"johannes.sixt@telecom.at","sentAt":"2007-03-02T21:11:30Z","receivedAt":"2007-03-02T21:11:30Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Some file systems that can host git repositories and their working copies\ndo not support symbolic links. But then if the repository contains a symbolic\nlink, it is impossible to check out the working copy.\n\nThis patch enables partial support of symbolic links so that it is possible\nto check out a working copy on such a file system.  A new flag\ncore.symlinks (which is true by default) can be set to false to indicate\nthat the filesystem does not support symbolic links. In this case, symbolic\nlinks that exist in the trees are checked out as small plain files, and\nchecking in modifications of these files preserve the symlink property in\nthe database (as long as an entry exists in the index).\n\nOf course, this does not magically make symbolic links work on such defective\nfile systems; hence, this solution does not help if the working copy relies\non that an entry is a real symbolic link.\n\nSigned-off-by: Johannes Sixt <johannes.sixt@telecom.at>\n---\n\nThis is a resend of my earlier patch series, this time as a single patch\nsince it's quite small. And with some basic tests.\n\nHannes\n\n Documentation/config.txt           |    7 +++++++\n Documentation/git-update-index.txt |    5 +++++\n builtin-apply.c                    |    2 +-\n builtin-update-index.c             |    6 +++---\n cache.h                            |    6 +++++-\n config.c                           |    5 +++++\n diff-lib.c                         |    3 +++\n entry.c                            |    9 ++++++---\n environment.c                      |    1 +\n read-cache.c                       |   10 ++++++----\n t/t2005-checkout-index-symlinks.sh |   28 ++++++++++++++++++++++++++++\n t/t2102-update-index-symlinks.sh   |   31 +++++++++++++++++++++++++++++++\n 12 files changed, 101 insertions(+), 12 deletions(-)\n create mode 100644 t/t2005-checkout-index-symlinks.sh\n create mode 100644 t/t2102-update-index-symlinks.sh\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 9fec769..08d13ca 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -116,6 +116,13 @@ core.fileMode::\n \tthe working copy are ignored; useful on broken filesystems like FAT.\n \tSee gitlink:git-update-index[1]. True by default.\n \n+core.symlinks::\n+\tIf false, symbolic links are checked out as small plain files that\n+\tcontain the link text. gitlink:git-update-index[1] and\n+\tgitlink:git-add[1] will not change the recorded type to regular\n+\tfile. Useful on filesystems like FAT that do not support\n+\tsymbolic links. True by default.\n+\n core.gitProxy::\n \tA \"proxy command\" to execute (as 'command host port') instead\n \tof establishing direct connection to the remote server when\ndiff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt\nindex b161c8b..cd5e014 100644\n--- a/Documentation/git-update-index.txt\n+++ b/Documentation/git-update-index.txt\n@@ -295,6 +295,11 @@ in the index and the file mode on the filesystem if they differ only on\n executable bit.   On such an unfortunate filesystem, you may\n need to use `git-update-index --chmod=`.\n \n+Quite similarly, if `core.symlinks` configuration variable is set\n+to 'false' (see gitlink:git-config[1]), symbolic links are checked out\n+as plain files, and this command does not modify a recorded file mode\n+from symbolic link to regular file.\n+\n The command looks at `core.ignorestat` configuration variable.  See\n 'Using \"assume unchanged\" bit' section above.\n \ndiff --git a/builtin-apply.c b/builtin-apply.c\nindex bec95d6..83ee20b 100644\n--- a/builtin-apply.c\n+++ b/builtin-apply.c\n@@ -2284,7 +2284,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,\n {\n \tint fd;\n \n-\tif (S_ISLNK(mode))\n+\tif (has_symlinks && S_ISLNK(mode))\n \t\t/* Although buf:size is counted string, it also is NUL\n \t\t * terminated.\n \t\t */\ndiff --git a/builtin-update-index.c b/builtin-update-index.c\nindex 772aaba..982640a 100644\n--- a/builtin-update-index.c\n+++ b/builtin-update-index.c\n@@ -109,11 +109,11 @@ static int add_file_to_cache(const char *path)\n \tce->ce_flags = htons(namelen);\n \tfill_stat_cache_info(ce, &st);\n \n-\tif (trust_executable_bit)\n+\tif (trust_executable_bit && has_symlinks)\n \t\tce->ce_mode = create_ce_mode(st.st_mode);\n \telse {\n-\t\t/* If there is an existing entry, pick the mode bits\n-\t\t * from it, otherwise assume unexecutable.\n+\t\t/* If there is an existing entry, pick the mode bits and type\n+\t\t * from it, otherwise assume unexecutable regular file.\n \t\t */\n \t\tstruct cache_entry *ent;\n \t\tint pos = cache_name_pos(path, namelen);\ndiff --git a/cache.h b/cache.h\nindex 04f8e63..6f932fe 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -108,7 +108,10 @@ static inline unsigned int create_ce_mode(unsigned int mode)\n }\n static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode)\n {\n-\textern int trust_executable_bit;\n+\textern int trust_executable_bit, has_symlinks;\n+\tif (!has_symlinks && S_ISREG(mode) &&\n+\t    ce && S_ISLNK(ntohl(ce->ce_mode)))\n+\t\treturn ce->ce_mode;\n \tif (!trust_executable_bit && S_ISREG(mode)) {\n \t\tif (ce && S_ISREG(ntohl(ce->ce_mode)))\n \t\t\treturn ce->ce_mode;\n@@ -202,6 +205,7 @@ extern int delete_ref(const char *, unsigned char *sha1);\n /* Environment bits from configuration mechanism */\n extern int use_legacy_headers;\n extern int trust_executable_bit;\n+extern int has_symlinks;\n extern int assume_unchanged;\n extern int prefer_symlink_refs;\n extern int log_all_ref_updates;\ndiff --git a/config.c b/config.c\nindex c938aa0..8181c6f 100644\n--- a/config.c\n+++ b/config.c\n@@ -269,6 +269,11 @@ int git_default_config(const char *var, const char *value)\n \t\treturn 0;\n \t}\n \n+\tif (!strcmp(var, \"core.symlinks\")) {\n+\t\thas_symlinks = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n+\n \tif (!strcmp(var, \"core.bare\")) {\n \t\tis_bare_repository_cfg = git_config_bool(var, value);\n \t\treturn 0;\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 60c0fa6..2c121d2 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -134,6 +134,9 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)\n \t\t    S_ISREG(newmode) && S_ISREG(oldmode) &&\n \t\t    ((newmode ^ oldmode) == 0111))\n \t\t\tnewmode = oldmode;\n+\t\telse if (!has_symlinks &&\n+\t\t    S_ISREG(newmode) && S_ISLNK(oldmode))\n+\t\t\tnewmode = oldmode;\n \t\tdiff_change(&revs->diffopt, oldmode, newmode,\n \t\t\t    ce->sha1, (changed ? null_sha1 : ce->sha1),\n \t\t\t    ce->name, NULL);\ndiff --git a/entry.c b/entry.c\nindex c2641dd..87609ca 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -97,9 +97,12 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat\n \t\t\treturn error(\"git-checkout-index: unable to write file %s\", path);\n \t\tbreak;\n \tcase S_IFLNK:\n-\t\tif (to_tempfile) {\n-\t\t\tstrcpy(path, \".merge_link_XXXXXX\");\n-\t\t\tfd = mkstemp(path);\n+\t\tif (to_tempfile || !has_symlinks) {\n+\t\t\tif (to_tempfile) {\n+\t\t\t\tstrcpy(path, \".merge_link_XXXXXX\");\n+\t\t\t\tfd = mkstemp(path);\n+\t\t\t} else\n+\t\t\t\tfd = create_file(path, 0666);\n \t\t\tif (fd < 0) {\n \t\t\t\tfree(new);\n \t\t\t\treturn error(\"git-checkout-index: unable to create \"\ndiff --git a/environment.c b/environment.c\nindex 54c22f8..48bc4f0 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -13,6 +13,7 @@ char git_default_email[MAX_GITNAME];\n char git_default_name[MAX_GITNAME];\n int use_legacy_headers = 1;\n int trust_executable_bit = 1;\n+int has_symlinks = 1;\n int assume_unchanged;\n int prefer_symlink_refs;\n int is_bare_repository_cfg = -1; /* unspecified */\ndiff --git a/read-cache.c b/read-cache.c\nindex 605b352..e8da76c 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -125,7 +125,9 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)\n \t\t\tchanged |= MODE_CHANGED;\n \t\tbreak;\n \tcase S_IFLNK:\n-\t\tchanged |= !S_ISLNK(st->st_mode) ? TYPE_CHANGED : 0;\n+\t\tif (!S_ISLNK(st->st_mode) &&\n+\t\t    (has_symlinks || !S_ISREG(st->st_mode)))\n+\t\t\tchanged |= TYPE_CHANGED;\n \t\tbreak;\n \tdefault:\n \t\tdie(\"internal error: ce_mode is %o\", ntohl(ce->ce_mode));\n@@ -344,11 +346,11 @@ int add_file_to_index(const char *path, int verbose)\n \tce->ce_flags = htons(namelen);\n \tfill_stat_cache_info(ce, &st);\n \n-\tif (trust_executable_bit)\n+\tif (trust_executable_bit && has_symlinks)\n \t\tce->ce_mode = create_ce_mode(st.st_mode);\n \telse {\n-\t\t/* If there is an existing entry, pick the mode bits\n-\t\t * from it, otherwise assume unexecutable.\n+\t\t/* If there is an existing entry, pick the mode bits and type\n+\t\t * from it, otherwise assume unexecutable regular file.\n \t\t */\n \t\tstruct cache_entry *ent;\n \t\tint pos = cache_name_pos(path, namelen);\ndiff --git a/t/t2005-checkout-index-symlinks.sh b/t/t2005-checkout-index-symlinks.sh\nnew file mode 100644\nindex 0000000..e34a515\n--- /dev/null\n+++ b/t/t2005-checkout-index-symlinks.sh\n@@ -0,0 +1,28 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2007 Johannes Sixt\n+#\n+\n+test_description='git-checkout-index on filesystem w/o symlinks test.\n+\n+This tests that git-checkout-index creates a symbolic link as a plain\n+file if core.symlinks is false.'\n+\n+. ./test-lib.sh\n+\n+test_expect_success \\\n+'preparation' '\n+git-config core.symlinks false &&\n+l=$(echo -n file | git-hash-object -t blob -w --stdin) &&\n+echo \"120000 $l\tsymlink\" | git-update-index --index-info'\n+\n+test_expect_success \\\n+'the checked-out symlink must be a file' '\n+git-checkout-index symlink &&\n+test -f symlink'\n+\n+test_expect_success \\\n+'the file must be the blob we added during the setup' '\n+test \"$(git-hash-object -t blob symlink)\" = $l'\n+\n+test_done\ndiff --git a/t/t2102-update-index-symlinks.sh b/t/t2102-update-index-symlinks.sh\nnew file mode 100644\nindex 0000000..969ef89\n--- /dev/null\n+++ b/t/t2102-update-index-symlinks.sh\n@@ -0,0 +1,31 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2007 Johannes Sixt\n+#\n+\n+test_description='git-update-index on filesystem w/o symlinks test.\n+\n+This tests that git-update-index keeps the symbolic link property\n+even if a plain file is in the working tree if core.symlinks is false.'\n+\n+. ./test-lib.sh\n+\n+test_expect_success \\\n+'preparation' '\n+git-config core.symlinks false &&\n+l=$(echo -n file | git-hash-object -t blob -w --stdin) &&\n+echo \"120000 $l\tsymlink\" | git-update-index --index-info'\n+\n+test_expect_success \\\n+'modify the symbolic link' '\n+echo -n new-file > symlink &&\n+git-update-index symlink'\n+\n+test_expect_success \\\n+'the index entry must still be a symbolic link' '\n+case \"`git-ls-files --stage --cached symlink`\" in\n+120000\" \"*symlink) echo ok;;\n+*) echo fail; git-ls-files --stage --cached symlink; (exit 1);;\n+esac'\n+\n+test_done\n-- \n1.5.0.19.gddff\n"},{"id":"36129","messageId":"Pine.LNX.4.63.0703022219360.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7051","inReplyTo":"200703022211.30322.johannes.sixt@telecom.at","subject":"Re: [PATCH] Add core.symlinks to mark filesystems that do not support symbolic links.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-02T21:35:03Z","receivedAt":"2007-03-02T21:35:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nBTW since git.git's RelNotes is a symlink this patch is needed for MinGW. \nI tried to commit something yesterday, and had to use cygwin to do it, \nsince MinGW Git always complained about \"invalid tree d5e055...\". For \nthose who don't know: try \"git show d5e055\" in your Git repository.\n\nOn Fri, 2 Mar 2007, Johannes Sixt wrote:\n\n> diff --git a/cache.h b/cache.h\n> index 04f8e63..6f932fe 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -108,7 +108,10 @@ static inline unsigned int create_ce_mode(unsigned int mode)\n>  }\n>  static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode)\n>  {\n> -\textern int trust_executable_bit;\n> +\textern int trust_executable_bit, has_symlinks;\n\nWould it not be better to move the global variables before this function?\nI.e. these:\n\n> @@ -202,6 +205,7 @@ extern int delete_ref(const char *, unsigned char *sha1);\n>  /* Environment bits from configuration mechanism */\n>  extern int use_legacy_headers;\n>  extern int trust_executable_bit;\n> +extern int has_symlinks;\n>  extern int assume_unchanged;\n>  extern int prefer_symlink_refs;\n>  extern int log_all_ref_updates;\n>\n> [...]\n>\n> diff --git a/t/t2102-update-index-symlinks.sh b/t/t2102-update-index-symlinks.sh\n> new file mode 100644\n> index 0000000..969ef89\n> --- /dev/null\n> +++ b/t/t2102-update-index-symlinks.sh\n> @@ -0,0 +1,31 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) 2007 Johannes Sixt\n> +#\n> +\n> +test_description='git-update-index on filesystem w/o symlinks test.\n> +\n> +This tests that git-update-index keeps the symbolic link property\n> +even if a plain file is in the working tree if core.symlinks is false.'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success \\\n> +'preparation' '\n> +git-config core.symlinks false &&\n> +l=$(echo -n file | git-hash-object -t blob -w --stdin) &&\n> +echo \"120000 $l\tsymlink\" | git-update-index --index-info'\n> +\n> +test_expect_success \\\n> +'modify the symbolic link' '\n> +echo -n new-file > symlink &&\n> +git-update-index symlink'\n> +\n> +test_expect_success \\\n> +'the index entry must still be a symbolic link' '\n> +case \"`git-ls-files --stage --cached symlink`\" in\n> +120000\" \"*symlink) echo ok;;\n> +*) echo fail; git-ls-files --stage --cached symlink; (exit 1);;\n> +esac'\n\nPlease test also what happens if you replace a supposed symlink with a \ndirectory and vice versa.\n\nCiao,\nDscho\n"},{"id":"36131","messageId":"200703022305.14058.johannes.sixt@telecom.at","threadId":"7051","inReplyTo":"Pine.LNX.4.63.0703022219360.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] Add core.symlinks to mark filesystems that do not support symbolic links.","fromName":"Johannes Sixt","fromEmail":"johannes.sixt@telecom.at","sentAt":"2007-03-02T22:05:13Z","receivedAt":"2007-03-02T22:05:13Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Friday 02 March 2007 22:35, Johannes Schindelin wrote:\n> On Fri, 2 Mar 2007, Johannes Sixt wrote:\n> > diff --git a/cache.h b/cache.h\n> > index 04f8e63..6f932fe 100644\n> > --- a/cache.h\n> > +++ b/cache.h\n> > @@ -108,7 +108,10 @@ static inline unsigned int create_ce_mode(unsigned\n> > int mode) }\n> >  static inline unsigned int ce_mode_from_stat(struct cache_entry *ce,\n> > unsigned int mode) {\n> > -\textern int trust_executable_bit;\n> > +\textern int trust_executable_bit, has_symlinks;\n>\n> Would it not be better to move the global variables before this function?\n\nI'd move the whole function out-of-line, I just wouldn't know whereto...\n\n-- Hannes\n"},{"id":"36139","messageId":"7vvehjchsp.fsf@assigned-by-dhcp.cox.net","threadId":"7051","inReplyTo":"200703022211.30322.johannes.sixt@telecom.at","subject":"Re: [PATCH] Add core.symlinks to mark filesystems that do not support symbolic links.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-03T00:05:58Z","receivedAt":"2007-03-03T00:05:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <johannes.sixt@telecom.at> writes:\n\n> Some file systems that can host git repositories and their working copies\n> do not support symbolic links. But then if the repository contains a symbolic\n> link, it is impossible to check out the working copy.\n\nOverall the patch looks good.  Thanks.\n\n> Of course, this does not magically make symbolic links work on such defective\n> file systems; hence, this solution does not help if the working copy relies\n> on that an entry is a real symbolic link.\n\nProbably defective is too strong a word here, but I'll apply\nyour patch as-is anyway.  We may need a few fix-ups, but it is\neasier to deal with such small updates on top of it once it is\nin-tree.\n\n> --- a/Documentation/git-update-index.txt\n> +++ b/Documentation/git-update-index.txt\n> @@ -295,6 +295,11 @@ in the index and the file mode on the filesystem if they differ only on\n>  executable bit.   On such an unfortunate filesystem, you may\n>  need to use `git-update-index --chmod=`.\n>  \n> +Quite similarly, if `core.symlinks` configuration variable is set\n> +to 'false' (see gitlink:git-config[1]), symbolic links are checked out\n> +as plain files, and this command does not modify a recorded file mode\n> +from symbolic link to regular file.\n> +\n>  The command looks at `core.ignorestat` configuration variable.  See\n>  'Using \"assume unchanged\" bit' section above.\n\nThis is off-topic, but I am having this nagging feeling that we\nmay want to revisit the ignorestat stuff to ignore more than\nwhat it currently does.  For example, if we make it to not even\ncare if the path is missing from the working tree, I think it\nwould help working in a narrowly checked out repository.\n\n> diff --git a/cache.h b/cache.h\n> index 04f8e63..6f932fe 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -108,7 +108,10 @@ static inline unsigned int create_ce_mode(unsigned int mode)\n>  }\n>  static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode)\n>  {\n> -\textern int trust_executable_bit;\n> +\textern int trust_executable_bit, has_symlinks;\n> +\tif (!has_symlinks && S_ISREG(mode) &&\n> +\t    ce && S_ISLNK(ntohl(ce->ce_mode)))\n> +\t\treturn ce->ce_mode;\n>  \tif (!trust_executable_bit && S_ISREG(mode)) {\n>  \t\tif (ce && S_ISREG(ntohl(ce->ce_mode)))\n>  \t\t\treturn ce->ce_mode;\n\nThis code (I am the guilty one before your change above) always\nconfused me.  How about doing something like this instead?\n\n    static inline unsigned int ce_mode_from_stat(struct cache_entry *ce,...\n    {\n        /*\n         * A regular file that appears on the filesystem can have\n         * a \"wrong\" st_mode information.  A few repository config\n         * variables can tell us to trust the mode recorded in the\n         * index more than what we get from the filesystem.\n         */\n        if (ce && S_ISREG(mode)) {\n            extern int trust_executable_bit, has_symlinks;\n\n            if (!has_symlinks && S_ISLNK(ntohl(ce->ce_mode)))\n                return ce->ce_mode;\n            if (!trust_executable_bit && S_ISREG(ntohl(ce->ce_mode)))\n                return ce->ce_mode;\n            return create_ce_mode(0666);\n        }\n        return create_ce_mode(mode);\n    }\n\n> diff --git a/diff-lib.c b/diff-lib.c\n> index 60c0fa6..2c121d2 100644\n> --- a/diff-lib.c\n> +++ b/diff-lib.c\n> @@ -134,6 +134,9 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)\n>  \t\t    S_ISREG(newmode) && S_ISREG(oldmode) &&\n>  \t\t    ((newmode ^ oldmode) == 0111))\n>  \t\t\tnewmode = oldmode;\n> +\t\telse if (!has_symlinks &&\n> +\t\t    S_ISREG(newmode) && S_ISLNK(oldmode))\n> +\t\t\tnewmode = oldmode;\n>  \t\tdiff_change(&revs->diffopt, oldmode, newmode,\n>  \t\t\t    ce->sha1, (changed ? null_sha1 : ce->sha1),\n>  \t\t\t    ce->name, NULL);\n\nI suspect that this part becomes clearer if we rewrite it like\nthis:\n\n \t\tchanged = ce_match_stat(ce, &st, 0);\n \t\tif (!changed && !revs->diffopt.find_copies_harder)\n \t\t\tcontinue;\n \t\toldmode = ntohl(ce->ce_mode);\n-\n-\t\tnewmode = canon_mode(st.st_mode);\n-\t\tif (!trust_executable_bit &&\n-\t\t    S_ISREG(newmode) && S_ISREG(oldmode) &&\n-\t\t    ((newmode ^ oldmode) == 0111))\n-\t\t\tnewmode = oldmode;\n-\t\telse if (!has_symlinks &&\n-\t\t    S_ISREG(newmode) && S_ISLNK(oldmode))\n-\t\t\tnewmode = oldmode;\n+\t\tnewmode = ntohl(ce_mode_from_stat(ce, st.st_mode));\n \t\tdiff_change(&revs->diffopt, oldmode, newmode,\n \t\t\t    ce->sha1, (changed ? null_sha1 : ce->sha1),\n \t\t\t    ce->name, NULL);\n"},{"id":"36140","messageId":"7vr6s7chim.fsf@assigned-by-dhcp.cox.net","threadId":"7051","inReplyTo":"7vvehjchsp.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add core.symlinks to mark filesystems that do not support symbolic links.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-03T00:12:01Z","receivedAt":"2007-03-03T00:12:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> This code (I am the guilty one before your change above) always\n> confused me.  How about doing something like this instead?\n>\n>     static inline unsigned int ce_mode_from_stat(struct cache_entry *ce,...\n>     {\n>         /*\n>          * A regular file that appears on the filesystem can have\n>          * a \"wrong\" st_mode information.  A few repository config\n>          * variables can tell us to trust the mode recorded in the\n>          * index more than what we get from the filesystem.\n>          */\n>         if (ce && S_ISREG(mode)) {\n>             extern int trust_executable_bit, has_symlinks;\n>\n>             if (!has_symlinks && S_ISLNK(ntohl(ce->ce_mode)))\n>                 return ce->ce_mode;\n\nOops, these three lines\n\n>             if (!trust_executable_bit && S_ISREG(ntohl(ce->ce_mode)))\n>                 return ce->ce_mode;\n>             return create_ce_mode(0666);\n\nshould be:\n\n\t\tif (!trust...) {\n                \tif (S_ISREG(...))\n                        \treturn ce->ce_mode;\n\t\t\treturn create_ce_mode(0666);\n\t\t}\n\nStill confused I am ;-(.\n"},{"id":"36141","messageId":"Pine.LNX.4.63.0703030112380.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7051","inReplyTo":"7vvehjchsp.fsf@assigned-by-dhcp.cox.net","subject":"Narrow checkouts, was Re: [PATCH] Add core.symlinks to mark filesystems that do not support symbolic links.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-03T00:14:12Z","receivedAt":"2007-03-03T00:14:12Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 2 Mar 2007, Junio C Hamano wrote:\n\n> This is off-topic, but I am having this nagging feeling that we may want \n> to revisit the ignorestat stuff to ignore more than what it currently \n> does.  For example, if we make it to not even care if the path is \n> missing from the working tree, I think it would help working in a \n> narrowly checked out repository.\n\nI was thinking the same, when I heard that request, but was not able to \nfind time to do it. Maybe somebody else wants to jump in and help?\n\nCiao,\nDscho\n"},{"id":"36169","messageId":"200703031320.13535.johannes.sixt@telecom.at","threadId":"7051","inReplyTo":"7vr6s7chim.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add core.symlinks to mark filesystems that do not support symbolic links.","fromName":"Johannes Sixt","fromEmail":"johannes.sixt@telecom.at","sentAt":"2007-03-03T12:20:13Z","receivedAt":"2007-03-03T12:20:13Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Saturday 03 March 2007 01:12, Junio C Hamano wrote:\n> Junio C Hamano <junkio@cox.net> writes:\n> > This code (I am the guilty one before your change above) always\n> > confused me.  How about doing something like this instead?\n> >\n> >     static inline unsigned int ce_mode_from_stat(struct cache_entry\n> > *ce,... {\n> >         /*\n> >          * A regular file that appears on the filesystem can have\n> >          * a \"wrong\" st_mode information.  A few repository config\n> >          * variables can tell us to trust the mode recorded in the\n> >          * index more than what we get from the filesystem.\n> >          */\n> >         if (ce && S_ISREG(mode)) {\n> >             extern int trust_executable_bit, has_symlinks;\n> >\n> >             if (!has_symlinks && S_ISLNK(ntohl(ce->ce_mode)))\n> >                 return ce->ce_mode;\n>\n> Oops, these three lines\n>\n> >             if (!trust_executable_bit && S_ISREG(ntohl(ce->ce_mode)))\n> >                 return ce->ce_mode;\n> >             return create_ce_mode(0666);\n>\n> should be:\n>\n> \t\tif (!trust...) {\n>                 \tif (S_ISREG(...))\n>                         \treturn ce->ce_mode;\n> \t\t\treturn create_ce_mode(0666);\n> \t\t}\n\nI think that's still not correct. Because in the case of !trust_executable_bit \nwe want create_ce_mode(0666) regardless of whether a ce exists or not. Maybe \nthis way:\n\n    static inline unsigned int ce_mode_from_stat(struct cache_entry *ce,...\n    {\n        /*\n         * A regular file that appears on the filesystem can have\n         * a \"wrong\" st_mode information.  A few repository config\n         * variables can tell us to trust the mode recorded in the\n         * index more than what we get from the filesystem.\n         */\n        if (S_ISREG(mode)) {\n            extern int trust_executable_bit, has_symlinks;\n\n            if (!has_symlinks && ce && S_ISLNK(ntohl(ce->ce_mode)))\n                return ce->ce_mode;\n            if (!trust_executable_bit) {\n                if (ce && S_ISREG(ntohl(ce->ce_mode)))\n                    return ce->ce_mode;\n                return create_ce_mode(0666);\n            }\n        }\n        return create_ce_mode(mode);\n    }\n\n\n-- Hannes\n"},{"id":"36172","messageId":"7v1wk6cx9k.fsf@assigned-by-dhcp.cox.net","threadId":"7051","inReplyTo":"200703031320.13535.johannes.sixt@telecom.at","subject":"Re: [PATCH] Add core.symlinks to mark filesystems that do not support symbolic links.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-03T12:44:07Z","receivedAt":"2007-03-03T12:44:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <johannes.sixt@telecom.at> writes:\n\n> I think that's still not correct.\n\nOf course you are right.  Thanks.\n"}]}