* Seeing various mode changes on cygwin @ 2005-10-08 18:00 Jonas Fonseca 2005-10-08 18:51 ` Junio C Hamano 0 siblings, 1 reply; 18+ messages in thread From: Jonas Fonseca @ 2005-10-08 18:00 UTC (permalink / raw) To: git Hi, It seems that git on cygwin still have a few problems. I've experienced it both when cloning with git and Cogito. It seems that cygwin overrides the previous modes and sets the executable bit. git-reset doesn't fix it. Can this even be fixed then? A few examples below ... jonas@cygwin /usr/local/dev/git/git $ git reset Documentation/sort_glossary.pl: needs update t/lib-read-tree-m-3way.sh: needs update t/t4109-apply-multifrag.sh: needs update t/t4110-apply-scan.sh: needs update t/t6000lib.sh: needs update t/t6101-rev-parse-parents.sh: needs update templates/hooks--applypatch-msg: needs update templates/hooks--commit-msg: needs update templates/hooks--post-commit: needs update templates/hooks--post-update: needs update templates/hooks--pre-applypatch: needs update templates/hooks--pre-commit: needs update templates/hooks--update: needs update jonas@cygwin /usr/local/dev/git/git $ git diff diff --git a/Documentation/sort_glossary.pl b/Documentation/sort_glossary.pl old mode 100644 new mode 100755 diff --git a/t/lib-read-tree-m-3way.sh b/t/lib-read-tree-m-3way.sh old mode 100755 new mode 100644 diff --git a/t/t4109-apply-multifrag.sh b/t/t4109-apply-multifrag.sh old mode 100644 new mode 100755 diff --git a/t/t4110-apply-scan.sh b/t/t4110-apply-scan.sh old mode 100644 new mode 100755 diff --git a/t/t6000lib.sh b/t/t6000lib.sh old mode 100755 new mode 100644 diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh old mode 100644 new mode 100755 diff --git a/templates/hooks--applypatch-msg b/templates/hooks--applypatch-msg old mode 100644 new mode 100755 diff --git a/templates/hooks--commit-msg b/templates/hooks--commit-msg old mode 100644 new mode 100755 diff --git a/templates/hooks--post-commit b/templates/hooks--post-commit old mode 100644 new mode 100755 diff --git a/templates/hooks--post-update b/templates/hooks--post-update old mode 100644 new mode 100755 diff --git a/templates/hooks--pre-applypatch b/templates/hooks--pre-applypatch old mode 100644 new mode 100755 diff --git a/templates/hooks--pre-commit b/templates/hooks--pre-commit old mode 100644 new mode 100755 diff --git a/templates/hooks--update b/templates/hooks--update old mode 100644 new mode 100755 jonas@cygwin /usr/local/dev/git/cogito $ cg diff debian/ diff --git a/debian/helper-scripts/make-orig.tgz b/debian/helper-scripts/make-orig.tgz old mode 100644 new mode 100755 diff --git a/debian/helper-scripts/make-package b/debian/helper-scripts/make-package old mode 100644 new mode 100755 diff --git a/debian/helper-scripts/make-test b/debian/helper-scripts/make-test old mode 100644 new mode 100755 jonas@cygwin /usr/local/dev/elinks/0.11 $ cg diff diff --git a/config/config.guess b/config/config.guess old mode 100644 new mode 100755 diff --git a/config/config.sub b/config/config.sub old mode 100644 new mode 100755 diff --git a/contrib/conv/w3m2links.awk.in b/contrib/conv/w3m2links.awk.in old mode 100644 new mode 100755 diff --git a/contrib/lua/bm-to-elinks-bookmarks.lua b/contrib/lua/bm-to-elinks-bookmarks.lua old mode 100644 new mode 100755 diff --git a/contrib/wipe-out-ssl.awk b/contrib/wipe-out-ssl.awk old mode 100644 new mode 100755 diff --git a/debian/elinks.postinst b/debian/elinks.postinst old mode 100644 new mode 100755 diff --git a/debian/elinks.preinst b/debian/elinks.preinst old mode 100644 new mode 100755 diff --git a/debian/elinks.prerm b/debian/elinks.prerm old mode 100644 new mode 100755 diff --git a/po/gen_translations_stats.sh b/po/gen_translations_stats.sh old mode 100644 new mode 100755 -- Jonas Fonseca ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Seeing various mode changes on cygwin 2005-10-08 18:00 Seeing various mode changes on cygwin Jonas Fonseca @ 2005-10-08 18:51 ` Junio C Hamano 2005-10-08 21:36 ` Alex Riesen 0 siblings, 1 reply; 18+ messages in thread From: Junio C Hamano @ 2005-10-08 18:51 UTC (permalink / raw) To: git Jonas Fonseca <fonseca@diku.dk> writes: > ... It seems that cygwin overrides the previous > modes and sets the executable bit. git-reset doesn't fix it. Can this even be > fixed then? > > A few examples below ... > > jonas@cygwin /usr/local/dev/git/git > $ git reset > Documentation/sort_glossary.pl: needs update > t/lib-read-tree-m-3way.sh: needs update I do not have an access to Cygwin environment so cannot be of help on this directly, but 'git reset' without flags defaults "--mixed" and leaves the modified files intact. Maybe hard reset would help here, but the real solution is to figure out why these files acquired the extra executable bits in the first place. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Seeing various mode changes on cygwin 2005-10-08 18:51 ` Junio C Hamano @ 2005-10-08 21:36 ` Alex Riesen 2005-10-08 23:36 ` Junio C Hamano 0 siblings, 1 reply; 18+ messages in thread From: Alex Riesen @ 2005-10-08 21:36 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Junio C Hamano, Sat, Oct 08, 2005 20:51:55 +0200: > > ... It seems that cygwin overrides the previous modes and sets the > > executable bit. git-reset doesn't fix it. Can this even be fixed > > then? > > > > A few examples below ... > > > > jonas@cygwin /usr/local/dev/git/git > > $ git reset > > Documentation/sort_glossary.pl: needs update > > t/lib-read-tree-m-3way.sh: needs update > > I do not have an access to Cygwin environment so cannot be of > help on this directly, but 'git reset' without flags defaults > "--mixed" and leaves the modified files intact. Maybe hard > reset would help here, but the real solution is to figure out > why these files acquired the extra executable bits in the first > place. These are not real attributes, cygwin emulates them from the names, like .exe will always be 0755, for example. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Seeing various mode changes on cygwin 2005-10-08 21:36 ` Alex Riesen @ 2005-10-08 23:36 ` Junio C Hamano 2005-10-09 2:19 ` Linus Torvalds ` (2 more replies) 0 siblings, 3 replies; 18+ messages in thread From: Junio C Hamano @ 2005-10-08 23:36 UTC (permalink / raw) To: Alex Riesen; +Cc: git Alex Riesen <raa.lkml@gmail.com> writes: > These are not real attributes, cygwin emulates them from the names, > like .exe will always be 0755, for example. Ouch. Is this true in general, or only on FAT-derived filesystems? We may need to worry about this on the core side after all. Some people need to mount FAT even on Linux systems, ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Seeing various mode changes on cygwin 2005-10-08 23:36 ` Junio C Hamano @ 2005-10-09 2:19 ` Linus Torvalds 2005-10-09 6:46 ` Junio C Hamano 2005-10-10 6:48 ` Daniel Barkalow 2005-10-09 3:43 ` Seeing various mode changes on cygwin H. Peter Anvin 2005-10-09 13:02 ` Alex Riesen 2 siblings, 2 replies; 18+ messages in thread From: Linus Torvalds @ 2005-10-09 2:19 UTC (permalink / raw) To: Junio C Hamano; +Cc: Alex Riesen, git On Sat, 8 Oct 2005, Junio C Hamano wrote: > > Alex Riesen <raa.lkml@gmail.com> writes: > > These are not real attributes, cygwin emulates them from the names, > > like .exe will always be 0755, for example. > > Ouch. Is this true in general, or only on FAT-derived > filesystems? > > We may need to worry about this on the core side after all. > Some people need to mount FAT even on Linux systems, I think we might want to have a flag that says "don't care about filesystem modes". That should be pretty easy, I think we'd get most of them by just adding some logic to "ce_match_stat()". Then add a "git chmod" to set the mode in the index (which should end up being just a wrapper around the regular "git-update-index" using the "--cacheinfo" flag, I think). Those parts should be trivial. The more interesting issue is how to set the _flag_ that we should do this. We may have to add a config file, and it should be per-repository (ie something like ".git/config" or ".git/info/config"). Or do we just do yet another environment variable? Linus ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Seeing various mode changes on cygwin 2005-10-09 2:19 ` Linus Torvalds @ 2005-10-09 6:46 ` Junio C Hamano 2005-10-10 6:48 ` Daniel Barkalow 1 sibling, 0 replies; 18+ messages in thread From: Junio C Hamano @ 2005-10-09 6:46 UTC (permalink / raw) To: Linus Torvalds; +Cc: Alex Riesen, git Linus Torvalds <torvalds@osdl.org> writes: > The more interesting issue is how to set the _flag_ that we should do > this. We may have to add a config file, and it should be per-repository > (ie something like ".git/config" or ".git/info/config"). Or do we just do > yet another environment variable? Per-repository configuration file like .git/info/config sounds like the way to go. Long time ago, the core never read any per-repository nor per-odb configuration file, but after grafts and then now alternates, we started doing it, and there is no reason to shy away from having an official configuration file mechanism. Maybe recent HTTP related environment variables could also be folded into it. While we are at it, we may want to move things around to consolidate per-repository configuration into a single placek. Specifically, I have moving .git/remotes/ in mind. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Seeing various mode changes on cygwin 2005-10-09 2:19 ` Linus Torvalds 2005-10-09 6:46 ` Junio C Hamano @ 2005-10-10 6:48 ` Daniel Barkalow 2005-10-10 7:38 ` Junio C Hamano 1 sibling, 1 reply; 18+ messages in thread From: Daniel Barkalow @ 2005-10-10 6:48 UTC (permalink / raw) To: Linus Torvalds; +Cc: Junio C Hamano, Alex Riesen, git On Sat, 8 Oct 2005, Linus Torvalds wrote: > I think we might want to have a flag that says "don't care about > filesystem modes". That should be pretty easy, I think we'd get most of > them by just adding some logic to "ce_match_stat()". > > Then add a "git chmod" to set the mode in the index (which should end up > being just a wrapper around the regular "git-update-index" using the > "--cacheinfo" flag, I think). > > Those parts should be trivial. > > The more interesting issue is how to set the _flag_ that we should do > this. We may have to add a config file, and it should be per-repository > (ie something like ".git/config" or ".git/info/config"). Or do we just do > yet another environment variable? Perhaps have a bit in the index mode for the file to say that the mode in the filesystem is unreliable, which gets set if a stat of the newly-written file doesn't match the mode it was supposed to have, or if git chmod is used to change it; then, if the bit is set, ignore the mode in the filesystem and just use the mode in the index. This should prevent modes from magically changing, even if the user doesn't do anything special. -Daniel *This .sig left intentionally blank* ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Seeing various mode changes on cygwin 2005-10-10 6:48 ` Daniel Barkalow @ 2005-10-10 7:38 ` Junio C Hamano 2005-10-10 17:59 ` Daniel Barkalow 0 siblings, 1 reply; 18+ messages in thread From: Junio C Hamano @ 2005-10-10 7:38 UTC (permalink / raw) To: Daniel Barkalow; +Cc: git Daniel Barkalow <barkalow@iabervon.org> writes: > Perhaps have a bit in the index mode for the file to say that the mode in > the filesystem is unreliable, which gets set if a stat of the > newly-written file doesn't match the mode it was supposed to have, or if > git chmod is used to change it; then, if the bit is set, ignore the mode > in the filesystem and just use the mode in the index. In effect, you are making the "per-repo configuration" Linus mentioned a non configuration but a property recorded in the index file. I think this is a clever solution which is very helpful to the end user. I have to think about this a bit, but my gut feeling tells me that it is the right direction if it works. I do not think you have to necessarily record it in the "index mode" -- which implies this is per path -- nor even in the index file itself. We might even be able to get away with doing this check at git-init-db time just once, and record it in a file, say ".git/fs-mode-unreliable". ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Seeing various mode changes on cygwin 2005-10-10 7:38 ` Junio C Hamano @ 2005-10-10 17:59 ` Daniel Barkalow 2005-10-10 18:22 ` Linus Torvalds 0 siblings, 1 reply; 18+ messages in thread From: Daniel Barkalow @ 2005-10-10 17:59 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Mon, 10 Oct 2005, Junio C Hamano wrote: > Daniel Barkalow <barkalow@iabervon.org> writes: > > > Perhaps have a bit in the index mode for the file to say that the mode in > > the filesystem is unreliable, which gets set if a stat of the > > newly-written file doesn't match the mode it was supposed to have, or if > > git chmod is used to change it; then, if the bit is set, ignore the mode > > in the filesystem and just use the mode in the index. > > In effect, you are making the "per-repo configuration" Linus > mentioned a non configuration but a property recorded in the > index file. I think this is a clever solution which is very > helpful to the end user. I have to think about this a bit, but > my gut feeling tells me that it is the right direction if it > works. > > I do not think you have to necessarily record it in the "index > mode" -- which implies this is per path -- nor even in the index > file itself. We might even be able to get away with doing this > check at git-init-db time just once, and record it in a file, > say ".git/fs-mode-unreliable". Actually, you're right; it is information about the behavior of the working tree, and is also needed if you want to compare the working tree against a tree object, in which case you aren't using the index at all. -Daniel *This .sig left intentionally blank* ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Seeing various mode changes on cygwin 2005-10-10 17:59 ` Daniel Barkalow @ 2005-10-10 18:22 ` Linus Torvalds 2005-10-10 21:35 ` Add ".git/config" file parser Linus Torvalds 0 siblings, 1 reply; 18+ messages in thread From: Linus Torvalds @ 2005-10-10 18:22 UTC (permalink / raw) To: Daniel Barkalow; +Cc: Junio C Hamano, git On Mon, 10 Oct 2005, Daniel Barkalow wrote: > > Actually, you're right; it is information about the behavior of the > working tree, and is also needed if you want to compare the working tree > against a tree object, in which case you aren't using the index at all. Git _always_ uses the index for working tree operations. It may take the actual file _data_ from the working tree, but it will take the list of files from the index, so it's certainly possible to link the index to the working tree. That said, I don't think it's necessarily a good idea. You can have temporary indexes for various operations that ignore the main one (ie any random GIT_INDEX_FILE=tmp git-read-tree ... will create a new index). So I think it's much better to have a config file. I'll write something up. Make it extensible while at it. Linus ^ permalink raw reply [flat|nested] 18+ messages in thread
* Add ".git/config" file parser 2005-10-10 18:22 ` Linus Torvalds @ 2005-10-10 21:35 ` Linus Torvalds 2005-10-10 21:47 ` Linus Torvalds 2005-10-12 0:25 ` Junio C Hamano 0 siblings, 2 replies; 18+ messages in thread From: Linus Torvalds @ 2005-10-10 21:35 UTC (permalink / raw) To: Junio C Hamano; +Cc: Git Mailing List This is a first cut at a very simple parser for a git config file. The format of the file is a simple ini-file like thing, with simple variable/value pairs. You can (and should) make the variables have a simple single-level scope, ie a valid file looks something like this: # # This is the config file, and # a '#' or ';' character indicates # a comment # ; core variables [core] ; Don't trust file modes filemode = false ; Our diff algorithm [diff] external = "/usr/local/bin/gnu-diff -u" renames = true which parses into two variables: "core.filemode" is associated with the string "false", and "diff.external" gets the appropriate quoted value. Right now we only react to one variable: "core.filemode" is a boolean that decides if we should care about the 0100 (user-execute) bit of the stat information. Even that is just a parsing demonstration - this doesn't actually implement that st_mode compare logic itself. Different programs can react to different config options, although they should always fall back to calling "git_default_config()" on any config option name that they don't recognize. Signed-off-by: Linus Torvalds <torvalds@osdl.org> ---- Ok, so it's stupid. But quite frankly, I think the Windows ini-file format is a hell of a lot more readable than something over-engineered like XML files or other crap. The interface is really easy to use, imho. You can do things like static int enable_renames = 0; static int my_options(const char *var, const char *value) { if (!strcmp("diff.renames", var)) { enable_renames = git_config_bool(var, value); return 0; } /* * Put other local option parsing for this program * here .. */ /* Fall back on the default ones */ return git_default_config(var, value); } and then in the "main()" routine you just do git_config(my_options); at the top (or, more precisely, just after the "git_setup_directory()" if you have one). And as usual, it's not like this has gotten a whole lot of testing. Flames, comments, whatever? The code is actually written so that the config file parsing should really be pretty neutral. It doesn't even have any git-specific in it, except for the naming and the actual initial "fopen()" pathname used, I think. --- diff --git a/Makefile b/Makefile index a201187..e8b46f1 100644 --- a/Makefile +++ b/Makefile @@ -158,7 +158,7 @@ LIB_OBJS = \ object.o pack-check.o patch-delta.o path.o pkt-line.o \ quote.o read-cache.o refs.o run-command.o \ server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \ - tag.o tree.o usage.o $(DIFF_OBJS) + tag.o tree.o usage.o config.o $(DIFF_OBJS) LIBS = $(LIB_FILE) LIBS += -lz diff --git a/cache.h b/cache.h index 5987d4c..0571282 100644 --- a/cache.h +++ b/cache.h @@ -178,6 +178,8 @@ extern int hold_index_file_for_update(st extern int commit_index_file(struct cache_file *); extern void rollback_index_file(struct cache_file *); +extern int trust_executable_bit; + #define MTIME_CHANGED 0x0001 #define CTIME_CHANGED 0x0002 #define OWNER_CHANGED 0x0004 @@ -372,4 +374,10 @@ extern int gitfakemunmap(void *start, si #endif +typedef int (*config_fn_t)(const char *, const char *); +extern int git_default_config(const char *, const char *); +extern int git_config(config_fn_t fn); +extern int git_config_int(const char *, const char *); +extern int git_config_bool(const char *, const char *); + #endif /* CACHE_H */ diff --git a/config.c b/config.c new file mode 100644 index 0000000..f3c4fa4 --- /dev/null +++ b/config.c @@ -0,0 +1,222 @@ +#include <ctype.h> + +#include "cache.h" + +#define MAXNAME (256) + +static FILE *config_file; +static int config_linenr; +static int get_next_char(void) +{ + int c; + FILE *f; + + c = '\n'; + if ((f = config_file) != NULL) { + c = fgetc(f); + if (c == '\n') + config_linenr++; + if (c == EOF) { + config_file = NULL; + c = '\n'; + } + } + return c; +} + +static char *parse_value(void) +{ + static char value[1024]; + int quote = 0, comment = 0, len = 0, space = 0; + + for (;;) { + int c = get_next_char(); + if (len >= sizeof(value)) + return NULL; + if (c == '\n') { + if (quote) + return NULL; + value[len] = 0; + return value; + } + if (comment) + continue; + if (isspace(c) && !quote) { + space = 1; + continue; + } + if (space) { + if (len) + value[len++] = ' '; + space = 0; + } + if (c == '\\') { + c = get_next_char(); + switch (c) { + case '\n': + continue; + case 't': + c = '\t'; + break; + case 'b': + c = '\b'; + break; + case 'n': + c = '\n'; + break; + return NULL; + } + value[len++] = c; + continue; + } + if (c == '"') { + quote = 1-quote; + continue; + } + if (!quote) { + if (c == ';' || c == '#') { + comment = 1; + continue; + } + } + value[len++] = c; + } +} + +static int get_value(config_fn_t fn, char *name, unsigned int len) +{ + int c; + char *value; + + /* Get the full name */ + for (;;) { + c = get_next_char(); + if (c == EOF) + break; + if (!isalnum(c)) + break; + name[len++] = tolower(c); + if (len >= MAXNAME) + return -1; + } + name[len] = 0; + while (c == ' ' || c == '\t') + c = get_next_char(); + + value = NULL; + if (c != '\n') { + if (c != '=') + return -1; + value = parse_value(); + if (!value) + return -1; + } + return fn(name, value); +} + +static int get_base_var(char *name) +{ + int baselen = 0; + + for (;;) { + int c = get_next_char(); + if (c == EOF) + return -1; + if (c == ']') + return baselen; + if (!isalnum(c)) + return -1; + if (baselen > MAXNAME / 2) + return -1; + name[baselen++] = tolower(c); + } +} + +static int git_parse_file(config_fn_t fn) +{ + int comment = 0; + int baselen = 0; + static char var[MAXNAME]; + + for (;;) { + int c = get_next_char(); + if (c == '\n') { + /* EOF? */ + if (!config_file) + return 0; + comment = 0; + continue; + } + if (comment || isspace(c)) + continue; + if (c == '#' || c == ';') { + comment = 1; + continue; + } + if (c == '[') { + baselen = get_base_var(var); + if (baselen <= 0) + break; + var[baselen++] = '.'; + var[baselen] = 0; + continue; + } + if (!isalpha(c)) + break; + var[baselen] = c; + if (get_value(fn, var, baselen+1) < 0) + break; + } + die("bad config file line %d", config_linenr); +} + +int git_config_int(const char *name, const char *value) +{ + if (value && *value) { + char *end; + int val = strtol(value, &end, 0); + if (!*end) + return val; + } + die("bad config value for '%s'", name); +} + +int git_config_bool(const char *name, const char *value) +{ + if (!value) + return 1; + if (!*value) + return 0; + if (!strcasecmp(value, "true")) + return 1; + if (!strcasecmp(value, "false")) + return 0; + return git_config_int(name, value) != 0; +} + +int git_default_config(const char *var, const char *value) +{ + /* This needs a better name */ + if (!strcmp(var, "core.filemode")) { + trust_executable_bit = git_config_bool(var, value); + return 0; + } + + /* Add other config variables here.. */ + return 0; +} + +int git_config(config_fn_t fn) +{ + int ret; + FILE *f = fopen(git_path("config"), "r"); + + ret = -1; + if (f) { + config_file = f; + config_linenr = 1; + ret = git_parse_file(fn); + fclose(f); + } + return ret; +} diff --git a/diff-files.c b/diff-files.c index 5e59832..96d2c7f 100644 --- a/diff-files.c +++ b/diff-files.c @@ -38,6 +38,7 @@ int main(int argc, const char **argv) const char *prefix = setup_git_directory(); int entries, i; + git_config(git_default_config); diff_setup(&diff_options); while (1 < argc && argv[1][0] == '-') { if (!strcmp(argv[1], "-q")) diff --git a/diff-tree.c b/diff-tree.c index b2d74eb..2203fa5 100644 --- a/diff-tree.c +++ b/diff-tree.c @@ -408,6 +408,7 @@ int main(int argc, const char **argv) unsigned char sha1[2][20]; const char *prefix = setup_git_directory(); + git_config(git_default_config); nr_sha1 = 0; diff_setup(&diff_options); diff --git a/read-cache.c b/read-cache.c index d2aebdd..c7f3b26 100644 --- a/read-cache.c +++ b/read-cache.c @@ -5,6 +5,7 @@ */ #include "cache.h" +int trust_executable_bit = 1; struct cache_entry **active_cache = NULL; unsigned int active_nr = 0, active_alloc = 0, active_cache_changed = 0; ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: Add ".git/config" file parser 2005-10-10 21:35 ` Add ".git/config" file parser Linus Torvalds @ 2005-10-10 21:47 ` Linus Torvalds 2005-10-10 21:50 ` H. Peter Anvin 2005-10-12 0:25 ` Junio C Hamano 1 sibling, 1 reply; 18+ messages in thread From: Linus Torvalds @ 2005-10-10 21:47 UTC (permalink / raw) To: Junio C Hamano; +Cc: Git Mailing List On Mon, 10 Oct 2005, Linus Torvalds wrote: > > ; core variables > [core] > ; Don't trust file modes > filemode = false > > ; Our diff algorithm > [diff] > external = "/usr/local/bin/gnu-diff -u" > renames = true > > which parses into two variables: "core.filemode" is associated with the > string "false", and "diff.external" gets the appropriate quoted value. _Three_ variables. Duh. I added the "renames" thing later, as I was looking at what kinds of default flags the "git-diff-xyz" family might be interested in having. Linus ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Add ".git/config" file parser 2005-10-10 21:47 ` Linus Torvalds @ 2005-10-10 21:50 ` H. Peter Anvin 2005-10-10 22:12 ` Linus Torvalds 0 siblings, 1 reply; 18+ messages in thread From: H. Peter Anvin @ 2005-10-10 21:50 UTC (permalink / raw) To: Linus Torvalds; +Cc: Junio C Hamano, Git Mailing List Linus Torvalds wrote: > > On Mon, 10 Oct 2005, Linus Torvalds wrote: > >> ; core variables >> [core] >> ; Don't trust file modes >> filemode = false >> >> ; Our diff algorithm >> [diff] >> external = "/usr/local/bin/gnu-diff -u" >> renames = true >> >>which parses into two variables: "core.filemode" is associated with the >>string "false", and "diff.external" gets the appropriate quoted value. > > _Three_ variables. Duh. I added the "renames" thing later, as I was > looking at what kinds of default flags the "git-diff-xyz" family might be > interested in having. > A suggestion: if you make your basic types (integer, string, boolean) recognizable by the parser, you can present them in that way. This pretty much means strings will have to always be double-quoted, but that avoids a bunch of ambiguities. -hpa ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Add ".git/config" file parser 2005-10-10 21:50 ` H. Peter Anvin @ 2005-10-10 22:12 ` Linus Torvalds 0 siblings, 0 replies; 18+ messages in thread From: Linus Torvalds @ 2005-10-10 22:12 UTC (permalink / raw) To: H. Peter Anvin; +Cc: Junio C Hamano, Git Mailing List On Mon, 10 Oct 2005, H. Peter Anvin wrote: > > A suggestion: if you make your basic types (integer, string, boolean) > recognizable by the parser, you can present them in that way. This pretty > much means strings will have to always be double-quoted, but that avoids a > bunch of ambiguities. Well, the parser is already pretty unambiguous, purely by virtue of being stupid as hell. In particular, the only thing quoting does is to actually make whitespace meaningful, and as a way to allow comments inside strings (otherwise a "#" or ";" is always a "comment starts here" marker). Outside of quotes, any whitespace will just collapse to a single space (and be removed from beginning and end). And quite frankly, always keeping the things as strings just makes things so much easier and the interfaces very simple. And if/when you want to turn the string into a boolean or a regular integer, there are two helper functions that do exactly that, so it's not very hard. I considered using some "smart" parser (ie using something like flex/bison), but the thing is, I didn't want smart. I personally think it's a lot more important for the file format to be _nice_, and there I think it's fine if [diff] external=/usr/local/bin/gnu-diff doesn't need quotes, even if it's obviously a string. Simplicity is a virtue (both in parsing and in the "language" parsed). In fact, even the example I had - with a space and an argument - doesn't need quotes (since the single space will be collapsed to a single space), I just put that as an example. Side note: the design is meant to allow different programs to share the same config file without having to know about each others config variables. Anything they don't recognize is just ignored. The downside is that if you mistype an option name, nobody will recognize it, and nobody will complain either. That was one of the reasons for the "scoping". It not only allows grouping of variables, but it means that the "git-diff-xyz" family of programs might decide that they'll report anything that starts with "diff." but that they don't understand as a warning (but preferably not error, since it might be a newer option that an older version of git just doesn't understand). Linus ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Add ".git/config" file parser 2005-10-10 21:35 ` Add ".git/config" file parser Linus Torvalds 2005-10-10 21:47 ` Linus Torvalds @ 2005-10-12 0:25 ` Junio C Hamano 2005-10-12 7:43 ` [PATCH] Use core.filemode Junio C Hamano 1 sibling, 1 reply; 18+ messages in thread From: Junio C Hamano @ 2005-10-12 0:25 UTC (permalink / raw) To: Git Mailing List; +Cc: Linus Torvalds This is a WIP to implement update-index that does not care the filesystem mode change. When you have the following in .git/config: [core] filemode = false the following things happen: * "git-update-index --refresh" does not consider the executable bit change significant. * "git-update-index" on an existing path takes executable bit from the existing index entry, if the blob types are the same. * "git-diff-files" pretends the path on the filesystem has the same executable bit as the existing index entry, if the blob types are the same. Yet to be done items are: * Other programs from diff-* family that compares with the filesystem needs to be covered. * "git-update-index --chmod=+x" and "--chmod=-x". * Refector code that takes the executable bit change from an existing index entry. WIP-not-worth-signing-off-yet-by: Junio C Hamano <junkio.cox.net> --- cd /opt/packrat/playpen/public/in-place/git/git.junio/ git diff HEAD diff --git a/diff-files.c b/diff-files.c index 96d2c7f..014f74e 100644 --- a/diff-files.c +++ b/diff-files.c @@ -81,7 +81,7 @@ int main(int argc, const char **argv) for (i = 0; i < entries; i++) { struct stat st; - unsigned int oldmode; + unsigned int oldmode, newmode; struct cache_entry *ce = active_cache[i]; int changed; @@ -111,7 +111,12 @@ int main(int argc, const char **argv) if (!changed && !diff_options.find_copies_harder) continue; oldmode = ntohl(ce->ce_mode); - show_modified(oldmode, DIFF_FILE_CANON_MODE(st.st_mode), + + newmode = DIFF_FILE_CANON_MODE(st.st_mode); + if (!trust_executable_bit && + S_ISREG(newmode) && ((newmode ^ oldmode) == 0111)) + newmode = oldmode; + show_modified(oldmode, newmode, ce->sha1, (changed ? null_sha1 : ce->sha1), ce->name); } diff --git a/read-cache.c b/read-cache.c index c7f3b26..4ed369a 100644 --- a/read-cache.c +++ b/read-cache.c @@ -36,8 +36,11 @@ int ce_match_stat(struct cache_entry *ce switch (ntohl(ce->ce_mode) & S_IFMT) { case S_IFREG: changed |= !S_ISREG(st->st_mode) ? TYPE_CHANGED : 0; - /* We consider only the owner x bit to be relevant for "mode changes" */ - if (0100 & (ntohl(ce->ce_mode) ^ st->st_mode)) + /* We consider only the owner x bit to be relevant for + * "mode changes" + */ + if (trust_executable_bit && + (0100 & (ntohl(ce->ce_mode) ^ st->st_mode))) changed |= MODE_CHANGED; break; case S_IFLNK: @@ -393,7 +396,7 @@ int add_cache_entry(struct cache_entry * int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK; pos = cache_name_pos(ce->name, ntohs(ce->ce_flags)); - /* existing match? Just replace it */ + /* existing match? Just replace it. */ if (pos >= 0) { active_cache_changed = 1; active_cache[pos] = ce; @@ -416,7 +419,8 @@ int add_cache_entry(struct cache_entry * if (!ok_to_add) return -1; - if (!skip_df_check && check_file_directory_conflict(ce, pos, ok_to_replace)) { + if (!skip_df_check && + check_file_directory_conflict(ce, pos, ok_to_replace)) { if (!ok_to_replace) return -1; pos = cache_name_pos(ce->name, ntohs(ce->ce_flags)); diff --git a/update-index.c b/update-index.c index 01b4088..fd3a882 100644 --- a/update-index.c +++ b/update-index.c @@ -67,13 +67,23 @@ static int add_file_to_cache(const char return error("lstat(\"%s\"): %s", path, strerror(errno)); } + namelen = strlen(path); size = cache_entry_size(namelen); ce = xmalloc(size); memset(ce, 0, size); memcpy(ce->name, path, namelen); fill_stat_cache_info(ce, &st); + ce->ce_mode = create_ce_mode(st.st_mode); + if (!trust_executable_bit) { + /* If there is an existing entry, pick the mode bits + * from it. + */ + int pos = cache_name_pos(path, namelen); + if (0 <= pos) + ce->ce_mode = active_cache[pos]->ce_mode; + } ce->ce_flags = htons(namelen); if (index_path(ce->sha1, path, &st, !info_only)) @@ -328,6 +338,8 @@ int main(int argc, const char **argv) const char *prefix = setup_git_directory(); int prefix_length = prefix ? strlen(prefix) : 0; + git_config(git_default_config); + newfd = hold_index_file_for_update(&cache_file, get_index_file()); if (newfd < 0) die("unable to create new cachefile"); ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH] Use core.filemode. 2005-10-12 0:25 ` Junio C Hamano @ 2005-10-12 7:43 ` Junio C Hamano 0 siblings, 0 replies; 18+ messages in thread From: Junio C Hamano @ 2005-10-12 7:43 UTC (permalink / raw) To: git Junio C Hamano <junkio@cox.net> writes: > This is a WIP to implement update-index that does not care the > filesystem mode change... I finished this one and have it in the master branch. I'd appreciate feedback from folks on affected platforms, most notably Cygwin. It might not be a bad idea to populate a new repository with a default .git/config file that sets "core.filemode = false" on Cygwin platform, using the templates mechanism. People on NTFS might not like that -- I do not know. Anyway, that is a separate topic. -- >8 -- cut here -- >8 -- With "[core] filemode = false", you can tell git to ignore differences in the working tree file only in executable bit. * "git-update-index --refresh" does not say "needs update" if index entry and working tree file differs only in executable bit. * "git-update-index" on an existing path takes executable bit from the existing index entry, if the path and index entry are both regular files. * "git-diff-files" and "git-diff-index" without --cached flag pretend the path on the filesystem has the same executable bit as the existing index entry, if the path and index entry are both regular files. If you are on a filesystem with unreliable mode bits, you may need to force the executable bit after registering the path in the index. * "git-update-index --chmod=+x foo" flips the executable bit of the index file entry for path "foo" on. Use "--chmod=-x" to flip it off. Note that --chmod only works in index file and does not look at nor update the working tree. So if you are on a filesystem and do not have working executable bit, you would do: 1. set the appropriate .git/config option; 2. "git-update-index --add new-file.c" 3. "git-ls-files --stage new-file.c" to see if it has the desired mode bits. If not, e.g. to drop executable bit picked up from the filesystem, say "git-update-index --chmod=-x new-file.c". Signed-off-by: Junio C Hamano <junkio@cox.net> --- diff-files.c | 10 ++++++++-- diff-index.c | 11 +++++++++-- read-cache.c | 12 ++++++++---- update-index.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 70 insertions(+), 9 deletions(-) applies-to: 8c8a7c6987bcb0eeab559a58170fccd767ce0218 3e09cdfd114651fc61656dbd45d5ec3d9352cb2b diff --git a/diff-files.c b/diff-files.c index 96d2c7f..8a8f9b6 100644 --- a/diff-files.c +++ b/diff-files.c @@ -81,7 +81,7 @@ int main(int argc, const char **argv) for (i = 0; i < entries; i++) { struct stat st; - unsigned int oldmode; + unsigned int oldmode, newmode; struct cache_entry *ce = active_cache[i]; int changed; @@ -111,7 +111,13 @@ int main(int argc, const char **argv) if (!changed && !diff_options.find_copies_harder) continue; oldmode = ntohl(ce->ce_mode); - show_modified(oldmode, DIFF_FILE_CANON_MODE(st.st_mode), + + newmode = DIFF_FILE_CANON_MODE(st.st_mode); + if (!trust_executable_bit && + S_ISREG(newmode) && S_ISREG(oldmode) && + ((newmode ^ oldmode) == 0111)) + newmode = oldmode; + show_modified(oldmode, newmode, ce->sha1, (changed ? null_sha1 : ce->sha1), ce->name); } diff --git a/diff-index.c b/diff-index.c index 62b36cc..c9a9f4c 100644 --- a/diff-index.c +++ b/diff-index.c @@ -15,7 +15,7 @@ static void show_file(const char *prefix } static int get_stat_data(struct cache_entry *ce, - unsigned char **sha1p, unsigned int *modep) + unsigned char ** sha1p, unsigned int *modep) { unsigned char *sha1 = ce->sha1; unsigned int mode = ce->ce_mode; @@ -35,6 +35,10 @@ static int get_stat_data(struct cache_en changed = ce_match_stat(ce, &st); if (changed) { mode = create_ce_mode(st.st_mode); + if (!trust_executable_bit && + S_ISREG(mode) && S_ISREG(ce->ce_mode) && + ((mode ^ ce->ce_mode) == 0111)) + mode = ce->ce_mode; sha1 = no_sha1; } } @@ -49,7 +53,9 @@ static void show_new_file(struct cache_e unsigned char *sha1; unsigned int mode; - /* New file in the index: it might actually be different in the working copy */ + /* New file in the index: it might actually be different in + * the working copy. + */ if (get_stat_data(new, &sha1, &mode) < 0) return; @@ -174,6 +180,7 @@ int main(int argc, const char **argv) int allow_options = 1; int i; + git_config(git_default_config); diff_setup(&diff_options); for (i = 1; i < argc; i++) { const char *arg = argv[i]; diff --git a/read-cache.c b/read-cache.c index c7f3b26..4ed369a 100644 --- a/read-cache.c +++ b/read-cache.c @@ -36,8 +36,11 @@ int ce_match_stat(struct cache_entry *ce switch (ntohl(ce->ce_mode) & S_IFMT) { case S_IFREG: changed |= !S_ISREG(st->st_mode) ? TYPE_CHANGED : 0; - /* We consider only the owner x bit to be relevant for "mode changes" */ - if (0100 & (ntohl(ce->ce_mode) ^ st->st_mode)) + /* We consider only the owner x bit to be relevant for + * "mode changes" + */ + if (trust_executable_bit && + (0100 & (ntohl(ce->ce_mode) ^ st->st_mode))) changed |= MODE_CHANGED; break; case S_IFLNK: @@ -393,7 +396,7 @@ int add_cache_entry(struct cache_entry * int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK; pos = cache_name_pos(ce->name, ntohs(ce->ce_flags)); - /* existing match? Just replace it */ + /* existing match? Just replace it. */ if (pos >= 0) { active_cache_changed = 1; active_cache[pos] = ce; @@ -416,7 +419,8 @@ int add_cache_entry(struct cache_entry * if (!ok_to_add) return -1; - if (!skip_df_check && check_file_directory_conflict(ce, pos, ok_to_replace)) { + if (!skip_df_check && + check_file_directory_conflict(ce, pos, ok_to_replace)) { if (!ok_to_replace) return -1; pos = cache_name_pos(ce->name, ntohs(ce->ce_flags)); diff --git a/update-index.c b/update-index.c index 01b4088..1eeb45d 100644 --- a/update-index.c +++ b/update-index.c @@ -67,13 +67,23 @@ static int add_file_to_cache(const char return error("lstat(\"%s\"): %s", path, strerror(errno)); } + namelen = strlen(path); size = cache_entry_size(namelen); ce = xmalloc(size); memset(ce, 0, size); memcpy(ce->name, path, namelen); fill_stat_cache_info(ce, &st); + ce->ce_mode = create_ce_mode(st.st_mode); + if (!trust_executable_bit) { + /* If there is an existing entry, pick the mode bits + * from it. + */ + int pos = cache_name_pos(path, namelen); + if (0 <= pos) + ce->ce_mode = active_cache[pos]->ce_mode; + } ce->ce_flags = htons(namelen); if (index_path(ce->sha1, path, &st, !info_only)) @@ -253,8 +263,32 @@ static int add_cacheinfo(const char *arg return add_cache_entry(ce, option); } -static struct cache_file cache_file; +static int chmod_path(int flip, const char *path) +{ + int pos; + struct cache_entry *ce; + unsigned int mode; + + pos = cache_name_pos(path, strlen(path)); + if (pos < 0) + return -1; + ce = active_cache[pos]; + mode = ntohl(ce->ce_mode); + if (!S_ISREG(mode)) + return -1; + switch (flip) { + case '+': + ce->ce_mode |= htonl(0111); break; + case '-': + ce->ce_mode &= htonl(~0111); break; + default: + return -1; + } + active_cache_changed = 1; + return 0; +} +static struct cache_file cache_file; static void update_one(const char *path, const char *prefix, int prefix_length) { @@ -328,6 +362,8 @@ int main(int argc, const char **argv) const char *prefix = setup_git_directory(); int prefix_length = prefix ? strlen(prefix) : 0; + git_config(git_default_config); + newfd = hold_index_file_for_update(&cache_file, get_index_file()); if (newfd < 0) die("unable to create new cachefile"); @@ -376,6 +412,14 @@ int main(int argc, const char **argv) i += 3; continue; } + if (!strcmp(path, "--chmod=-x") || + !strcmp(path, "--chmod=+x")) { + if (argc <= i+1) + die("git-update-index: %s <path>", path); + if (chmod_path(path[8], argv[++i])) + die("git-update-index: %s cannot chmod %s", path, argv[i]); + continue; + } if (!strcmp(path, "--info-only")) { info_only = 1; continue; --- 0.99.8.GIT ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: Seeing various mode changes on cygwin 2005-10-08 23:36 ` Junio C Hamano 2005-10-09 2:19 ` Linus Torvalds @ 2005-10-09 3:43 ` H. Peter Anvin 2005-10-09 13:02 ` Alex Riesen 2 siblings, 0 replies; 18+ messages in thread From: H. Peter Anvin @ 2005-10-09 3:43 UTC (permalink / raw) To: Junio C Hamano; +Cc: Alex Riesen, git Junio C Hamano wrote: > Alex Riesen <raa.lkml@gmail.com> writes: > >>These are not real attributes, cygwin emulates them from the names, >>like .exe will always be 0755, for example. > > Ouch. Is this true in general, or only on FAT-derived > filesystems? > > We may need to worry about this on the core side after all. > Some people need to mount FAT even on Linux systems, > At least on Cygwin/NTFS, you can do chmod just fine. -hpa ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Seeing various mode changes on cygwin 2005-10-08 23:36 ` Junio C Hamano 2005-10-09 2:19 ` Linus Torvalds 2005-10-09 3:43 ` Seeing various mode changes on cygwin H. Peter Anvin @ 2005-10-09 13:02 ` Alex Riesen 2 siblings, 0 replies; 18+ messages in thread From: Alex Riesen @ 2005-10-09 13:02 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Junio C Hamano, Sun, Oct 09, 2005 01:36:17 +0200: > > These are not real attributes, cygwin emulates them from the names, > > like .exe will always be 0755, for example. > > Ouch. Is this true in general, or only on FAT-derived > filesystems? > Before they are chmod'ed by cygwin (with chmod): probably everywhere on windows (I'm sure about vfat, were chmod wont help at all). Even if you can save user (unix) attributes somewhere, initial clone will still always have this problem. ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2005-10-12 7:43 UTC | newest] Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2005-10-08 18:00 Seeing various mode changes on cygwin Jonas Fonseca 2005-10-08 18:51 ` Junio C Hamano 2005-10-08 21:36 ` Alex Riesen 2005-10-08 23:36 ` Junio C Hamano 2005-10-09 2:19 ` Linus Torvalds 2005-10-09 6:46 ` Junio C Hamano 2005-10-10 6:48 ` Daniel Barkalow 2005-10-10 7:38 ` Junio C Hamano 2005-10-10 17:59 ` Daniel Barkalow 2005-10-10 18:22 ` Linus Torvalds 2005-10-10 21:35 ` Add ".git/config" file parser Linus Torvalds 2005-10-10 21:47 ` Linus Torvalds 2005-10-10 21:50 ` H. Peter Anvin 2005-10-10 22:12 ` Linus Torvalds 2005-10-12 0:25 ` Junio C Hamano 2005-10-12 7:43 ` [PATCH] Use core.filemode Junio C Hamano 2005-10-09 3:43 ` Seeing various mode changes on cygwin H. Peter Anvin 2005-10-09 13:02 ` Alex Riesen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).