Re: [PATCH v9 5/8] config: add `git_die_config()` to the config-set API
On 8/8/2014 12:25 AM, Junio C Hamano wrote: > Tanay Abhra writes: > >> diff --git a/Documentation/technical/api-config.txt >> b/Documentation/technical/api-config.txt >> index 21f280c..0d8b99b 100644 >> --- a/Documentation/technical/api-config.txt >> +++ b/Documentation/technical/api-config.txt >> @@ -155,6 +155,19 @@ as well as retrieval for the queried variable, >> including: >> Similar to `git_config_get_string`, but expands `~` or `~user` into >> the user's home directory when found at the beginning of the path. >> >> +`git_die_config(const char *key, const char *err, ...)`:: >> + >> +First prints the error message specified by the caller in `err` and then >> +dies printing the line number and the file name of the highest priority >> +value for the configuration variable `key`. > > Reviewed with a wider context, I notice that this entry alone lacks > the return type. I am assuming that this is just an oversight, and > adding 'void ' in front of the filename to match the next entry is > simple enough. > Yikes, yes, you are right, it's just an oversight. I will send an amended patch. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/8] builtin/mv.c cleanup
I was looking at builtin/mv.c for pathspec support and ended up cleaning it up a bit. The first patch is definitely good. The rest could be questionable. Although the output in the end looks better in my opinion. Nguyễn Thái Ngọc Duy (8): mv: mark strings for translations mv: no "Huh?" to the user mv: flatten error handling code block mv: split submodule move preparation code out mv: remove an "if" that's always true mv: move index search code out mv: unindent one level for directory move code mv: combine two if(s) builtin/mv.c | 168 +-- 1 file changed, 84 insertions(+), 84 deletions(-) -- 2.1.0.rc0.78.gc0d8480 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/8] mv: no "Huh?" to the user
Although if we are frisky, this could do static NORETURN void die_builtin(const char *err, va_list params) { - vreportf("fatal: ", err, params); + vreportf("Huh? ", err, params); exit(128); } Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/mv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/builtin/mv.c b/builtin/mv.c index b892f63..a7e02c0 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -135,7 +135,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (first >= 0) { struct strbuf submodule_dotgit = STRBUF_INIT; if (!S_ISGITLINK(active_cache[first]->ce_mode)) - die (_("Huh? Directory %s is in index and no submodule?"), src); + die (_("Directory %s is in index and no submodule?"), src); if (!is_staging_gitmodules_ok()) die (_("Please, stage your changes to .gitmodules or stash them to proceed")); strbuf_addf(&submodule_dotgit, "%s/.git", src); @@ -153,8 +153,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) first = cache_name_pos(src_w_slash, len_w_slash); if (first >= 0) - die (_("Huh? %.*s is in index?"), - len_w_slash, src_w_slash); + die (_("%.*s is in index"), len_w_slash, src_w_slash); first = -1 - first; for (last = first; last < active_nr; last++) { -- 2.1.0.rc0.78.gc0d8480 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/8] mv: split submodule move preparation code out
Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/mv.c | 35 +-- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/builtin/mv.c b/builtin/mv.c index 5c6f58f..e192f2d 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -66,6 +66,23 @@ static void move_up_one(void *p, int nmemb, int size) static struct lock_file lock_file; #define SUBMODULE_WITH_GITDIR ((const char *)1) +static void prepare_move_submodule(const char *src, int first, + const char **submodule_gitfile) +{ + struct strbuf submodule_dotgit = STRBUF_INIT; + if (!S_ISGITLINK(active_cache[first]->ce_mode)) + die (_("Directory %s is in index and no submodule?"), src); + if (!is_staging_gitmodules_ok()) + die (_("Please, stage your changes to .gitmodules or stash them to proceed")); + strbuf_addf(&submodule_dotgit, "%s/.git", src); + *submodule_gitfile = read_gitfile(submodule_dotgit.buf); + if (*submodule_gitfile) + *submodule_gitfile = xstrdup(*submodule_gitfile); + else + *submodule_gitfile = SUBMODULE_WITH_GITDIR; + strbuf_release(&submodule_dotgit); +} + int cmd_mv(int argc, const char **argv, const char *prefix) { int i, gitmodules_modified = 0; @@ -137,20 +154,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix) bad = _("cannot move directory over file"); else if (src_is_dir) { int first = cache_name_pos(src, length); - if (first >= 0) { - struct strbuf submodule_dotgit = STRBUF_INIT; - if (!S_ISGITLINK(active_cache[first]->ce_mode)) - die (_("Directory %s is in index and no submodule?"), src); - if (!is_staging_gitmodules_ok()) - die (_("Please, stage your changes to .gitmodules or stash them to proceed")); - strbuf_addf(&submodule_dotgit, "%s/.git", src); - submodule_gitfile[i] = read_gitfile(submodule_dotgit.buf); - if (submodule_gitfile[i]) - submodule_gitfile[i] = xstrdup(submodule_gitfile[i]); - else - submodule_gitfile[i] = SUBMODULE_WITH_GITDIR; - strbuf_release(&submodule_dotgit); - } else { + if (first >= 0) + prepare_move_submodule(src, first, + submodule_gitfile + i); + else { const char *src_w_slash = add_slash(src); int last, len_w_slash = length + 1; -- 2.1.0.rc0.78.gc0d8480 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/8] mv: mark strings for translations
Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/mv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/mv.c b/builtin/mv.c index 6ffe540..b892f63 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -108,7 +108,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) destination = internal_copy_pathspec(dest_path[0], argv, argc, DUP_BASENAME); } else { if (argc != 1) - die("destination '%s' is not a directory", dest_path[0]); + die(_("destination '%s' is not a directory"), dest_path[0]); destination = dest_path; } -- 2.1.0.rc0.78.gc0d8480 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/8] mv: flatten error handling code block
Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/mv.c | 35 +-- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/builtin/mv.c b/builtin/mv.c index a7e02c0..5c6f58f 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -58,6 +58,11 @@ static const char *add_slash(const char *path) return path; } +static void move_up_one(void *p, int nmemb, int size) +{ + memmove(p, (char*)p + size, nmemb * size); +} + static struct lock_file lock_file; #define SUBMODULE_WITH_GITDIR ((const char *)1) @@ -224,24 +229,18 @@ int cmd_mv(int argc, const char **argv, const char *prefix) else string_list_insert(&src_for_dst, dst); - if (bad) { - if (ignore_errors) { - if (--argc > 0) { - memmove(source + i, source + i + 1, - (argc - i) * sizeof(char *)); - memmove(destination + i, - destination + i + 1, - (argc - i) * sizeof(char *)); - memmove(modes + i, modes + i + 1, - (argc - i) * sizeof(enum update_mode)); - memmove(submodule_gitfile + i, - submodule_gitfile + i + 1, - (argc - i) * sizeof(char *)); - i--; - } - } else - die (_("%s, source=%s, destination=%s"), -bad, src, dst); + if (!bad) + continue; + if (!ignore_errors) + die (_("%s, source=%s, destination=%s"), +bad, src, dst); + if (--argc > 0) { + int n = argc - i; + move_up_one(source + i, n, sizeof(*source)); + move_up_one(destination + i, n, sizeof(*destination)); + move_up_one(modes + i, n, sizeof(*modes)); + move_up_one(submodule_gitfile + i, n, sizeof(*submodule_gitfile)); + i--; } } -- 2.1.0.rc0.78.gc0d8480 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/8] mv: remove an "if" that's always true
This is inside an "else" block of "if (last - first < 1)", so we know that "last - first >= 1" when we come here. No need to check "last - first > 0". While at there, save "argc + last - first" to a variable to shorten the statements a bit. Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/mv.c | 22 +++--- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/builtin/mv.c b/builtin/mv.c index e192f2d..a45226e 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -179,22 +179,14 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (last - first < 1) bad = _("source directory is empty"); else { - int j, dst_len; + int j, dst_len, n; - if (last - first > 0) { - source = xrealloc(source, - (argc + last - first) - * sizeof(char *)); - destination = xrealloc(destination, - (argc + last - first) - * sizeof(char *)); - modes = xrealloc(modes, - (argc + last - first) - * sizeof(enum update_mode)); - submodule_gitfile = xrealloc(submodule_gitfile, - (argc + last - first) - * sizeof(char *)); - } + n = argc + last - first; + source = xrealloc(source, n * sizeof(char *)); + destination = xrealloc(destination, n * sizeof(char *)); + modes = xrealloc(modes, n * sizeof(enum update_mode)); + submodule_gitfile = + xrealloc(submodule_gitfile, n * sizeof(char *)); dst = add_slash(dst); dst_len = strlen(dst); -- 2.1.0.rc0.78.gc0d8480 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 8/8] mv: combine two if(s)
Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/mv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/builtin/mv.c b/builtin/mv.c index a2e33b5..4eb420b 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -276,10 +276,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (gitmodules_modified) stage_updated_gitmodules(); - if (active_cache_changed) { - if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK)) + if (active_cache_changed && + write_locked_index(&the_index, &lock_file, COMMIT_LOCK)) die(_("Unable to write new index file")); - } return 0; } -- 2.1.0.rc0.78.gc0d8480 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/8] mv: move index search code out
Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/mv.c | 41 + 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/builtin/mv.c b/builtin/mv.c index a45226e..f8d65e2 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -83,6 +83,29 @@ static void prepare_move_submodule(const char *src, int first, strbuf_release(&submodule_dotgit); } +static int index_range_of_same_dir(const char *src, int length, + int *first_p, int *last_p) +{ + const char *src_w_slash = add_slash(src); + int first, last, len_w_slash = length + 1; + + first = cache_name_pos(src_w_slash, len_w_slash); + if (first >= 0) + die (_("%.*s is in index"), len_w_slash, src_w_slash); + + first = -1 - first; + for (last = first; last < active_nr; last++) { + const char *path = active_cache[last]->name; + if (strncmp(path, src_w_slash, len_w_slash)) + break; + } + if (src_w_slash != src) + free((char *)src_w_slash); + *first_p = first; + *last_p = last; + return last - first; +} + int cmd_mv(int argc, const char **argv, const char *prefix) { int i, gitmodules_modified = 0; @@ -158,24 +181,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix) prepare_move_submodule(src, first, submodule_gitfile + i); else { - const char *src_w_slash = add_slash(src); - int last, len_w_slash = length + 1; + int last; modes[i] = WORKING_DIRECTORY; - - first = cache_name_pos(src_w_slash, len_w_slash); - if (first >= 0) - die (_("%.*s is in index"), len_w_slash, src_w_slash); - - first = -1 - first; - for (last = first; last < active_nr; last++) { - const char *path = active_cache[last]->name; - if (strncmp(path, src_w_slash, len_w_slash)) - break; - } - if (src_w_slash != src) - free((char *)src_w_slash); - + index_range_of_same_dir(src, length, &first, &last); if (last - first < 1) bad = _("source directory is empty"); else { -- 2.1.0.rc0.78.gc0d8480 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/8] mv: unindent one level for directory move code
Signed-off-by: Nguyễn Thái Ngọc Duy --- builtin/mv.c | 47 +-- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/builtin/mv.c b/builtin/mv.c index f8d65e2..a2e33b5 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -176,42 +176,37 @@ int cmd_mv(int argc, const char **argv, const char *prefix) && lstat(dst, &st) == 0) bad = _("cannot move directory over file"); else if (src_is_dir) { - int first = cache_name_pos(src, length); + int first = cache_name_pos(src, length), last; if (first >= 0) prepare_move_submodule(src, first, submodule_gitfile + i); - else { - int last; - + else if (index_range_of_same_dir(src, length, +&first, &last) < 1) { modes[i] = WORKING_DIRECTORY; - index_range_of_same_dir(src, length, &first, &last); if (last - first < 1) bad = _("source directory is empty"); - else { - int j, dst_len, n; + } else { /* last - first >= 1 */ + int j, dst_len, n; - n = argc + last - first; - source = xrealloc(source, n * sizeof(char *)); - destination = xrealloc(destination, n * sizeof(char *)); - modes = xrealloc(modes, n * sizeof(enum update_mode)); - submodule_gitfile = - xrealloc(submodule_gitfile, n * sizeof(char *)); + modes[i] = WORKING_DIRECTORY; + n = argc + last - first; + source = xrealloc(source, n * sizeof(char *)); + destination = xrealloc(destination, n * sizeof(char *)); + modes = xrealloc(modes, n * sizeof(enum update_mode)); + submodule_gitfile = xrealloc(submodule_gitfile, n * sizeof(char *)); - dst = add_slash(dst); - dst_len = strlen(dst); + dst = add_slash(dst); + dst_len = strlen(dst); - for (j = 0; j < last - first; j++) { - const char *path = - active_cache[first + j]->name; - source[argc + j] = path; - destination[argc + j] = - prefix_path(dst, dst_len, - path + length + 1); - modes[argc + j] = INDEX; - submodule_gitfile[argc + j] = NULL; - } - argc += last - first; + for (j = 0; j < last - first; j++) { + const char *path = active_cache[first + j]->name; + source[argc + j] = path; + destination[argc + j] = + prefix_path(dst, dst_len, path + length + 1); + modes[argc + j] = INDEX; + submodule_gitfile[argc + j] = NULL; } + argc += last - first; } } else if (cache_name_pos(src, length) < 0) bad = _("not under version control"); -- 2.1.0.rc0.78.gc0d8480 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
push from one remote to another
What is the correct syntax/setup to push from one remote to another? I did something like this, to feed a github repo: # rm -rf $$ # mkdir $$ # cd $$ # git --init # git remote add --tags t git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git # git remote add --tags o g...@github.com:user/repo.git # git fetch --all This syntax does not work for me: # git push t master o master # git push --tags t master o master Is there a way to kind of mirror without doing a checkout, to save diskspace? Olaf -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: push from one remote to another
Olaf Hering writes: > What is the correct syntax/setup to push from one remote to another? > I did something like this, to feed a github repo: > > # rm -rf $$ > # mkdir $$ > # cd $$ > # git --init > # git remote add --tags t > git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git > # git remote add --tags o g...@github.com:user/repo.git > # git fetch --all > > This syntax does not work for me: > # git push t master o master > # git push --tags t master o master $ git push o remotes/t/master:master Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v8 0/8] Rewrite `git_config()` using config-set API
On 8/8/2014 2:01 AM, Junio C Hamano wrote: > Matthieu Moy writes: > Why is this needed? Are you now using key_value_info outside config.c? Or is it a leftover from a previous experiment? >>> >>> Has this been resolved in the new round? >> >> Tanay explained in another subthread why this was needed. For callers >> iterating over the string_list who want to get the file/line info, they >> need to be able to cast the void * pointer to struct key_value_info *. > > For callers that want to see all the multi-values, it would be > preferrable for the iterator to pass the filename and the linenumber > to the callback function, instead of exposing its implementation > detail as a single string list and telling them to pick it apart, > no? > > Not a very convincing argument, but OK for now in the sense that we > can fix it later if we wanted to before it gets too late. > (cc to Ramsay) The discussion in both threads (v8 and v9), boils down to this, is the `key_value_info` struct really required to be declared public or should be just an implementation detail. I will give you the context, The usage of the above mentioned struct is only required for git_config_get_value_multi(). With the public struct, the code flow would look like, -- 8< -- diff --git a/notes.c b/notes.c index 5fe691d..b7ab115 100644 --- a/notes.c +++ b/notes.c @@ -961,19 +961,6 @@ void string_list_add_refs_from_colon_sep(struct string_list *list, free(globs_copy); } -static int notes_display_config(const char *k, const char *v, void *cb) -{ - int *load_refs = cb; - - if (*load_refs && !strcmp(k, "notes.displayref")) { - if (!v) - config_error_nonbool(k); - string_list_add_refs_by_glob(&display_notes_refs, v); - } - - return 0; -} - const char *default_notes_ref(void) { const char *notes_ref = NULL; @@ -1041,7 +1028,9 @@ struct notes_tree **load_notes_trees(struct string_list *refs) void init_display_notes(struct display_notes_opt *opt) { char *display_ref_env; - int load_config_refs = 0; + const struct string_list *values; + struct key_value_info *kv_info; + int load_config_refs = 0, i; display_notes_refs.strdup_strings = 1; assert(!display_notes_trees); @@ -1058,7 +1047,21 @@ void init_display_notes(struct display_notes_opt *opt) load_config_refs = 1; } - git_config(notes_display_config, &load_config_refs); + if (load_config_refs) { + values = git_config_get_value_multi("notes.displayref"); + if (values) { + for (i = 0; i < values->nr; i++) { + if (!values->items[i].string) { + kv_info = values->items[i].util; + config_error_nonbool("notes.displayref"); + git_die_config_linenr("notes.displayref", kv_info->filename, kv_info->linenr); + } + else + string_list_add_refs_by_glob(&display_notes_refs, + values->items[i].string); + } + } + } if (opt) { struct string_list_item *item; -- 8< -- We cannot use git_die_config() here because it is applicable to the last value for a given variable. Alternative solution to the problem can be a helper function like this, git_die_config_index(key, value_index, err_msg, ...) which needs the value_index for a multi valued one, + values = git_config_get_value_multi("notes.displayref"); + if (values) { + for (i = 0; i < values->nr; i++) { + if (!values->items[i].string) + git_die_config_linenr("notes.displayref", i, "no null values allowed for :'%s'", "notes.displayref"); + else ; /* do stuff */ + } A callback iterator which supplies the linenr and filename to the callback function is not helpful, because there are many variable checks in a git_config() call where multi valued and single valued both reside, so we cannot use a callback iterator without adding more code cruft. What do you think, which way seems least obtrusive, or is there an another way out? -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v8 0/8] Rewrite `git_config()` using config-set API
On 08/08/14 15:07, Tanay Abhra wrote: > On 8/8/2014 2:01 AM, Junio C Hamano wrote: >> Matthieu Moy writes: >> > Why is this needed? Are you now using key_value_info outside config.c? > Or is it a leftover from a previous experiment? Has this been resolved in the new round? >>> >>> Tanay explained in another subthread why this was needed. For callers >>> iterating over the string_list who want to get the file/line info, they >>> need to be able to cast the void * pointer to struct key_value_info *. >> >> For callers that want to see all the multi-values, it would be >> preferrable for the iterator to pass the filename and the linenumber >> to the callback function, instead of exposing its implementation >> detail as a single string list and telling them to pick it apart, >> no? >> >> Not a very convincing argument, but OK for now in the sense that we >> can fix it later if we wanted to before it gets too late. >> > > (cc to Ramsay) > > The discussion in both threads (v8 and v9), boils down to this, > is the `key_value_info` struct really required to be declared public or > should be > just an implementation detail. I will give you the context, No, this is not the issue for me. The patch which introduces the struct in cache.h does not make use of that struct in any interface. It *is* an implementation detail of some code in config.c only. I do not know how that structure will be used in future patches. ;-) ATB, Ramsay Jones -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Pluggable backends for refs,wip
On Thu, Aug 7, 2014 at 5:57 AM, Michael Haggerty wrote: > On 08/05/2014 02:40 PM, Ronnie Sahlberg wrote: >> Please see >> https://github.com/rsahlberg/git/tree/backend-struct-db-2 >> for an example of a pluggable backend for refs storage. >> >> This series contain changes to make it possible to add new backends >> for handling/storage of refs and implements one new backend : >> refs-be-be.c . >> >> This new backend offloads the actual refs handling to a small database >> daemon with which ita talks via a very simple rpc protocol. That >> daemon in turn then connects to the datastore and read/writes the >> values to it. >> [...] > > Ronnie, > > This is awesome! Congratulations on your progress. > > I'm still on vacation and haven't yet looked at the code. I will be > back next week and hope to find time to check it out, and also to do > some more review of the code that you have already submitted to git core. Thanks! > > > Have you thought about how to test alternate reference backends? This > will be very important to getting one or more of them accepted into git > core (not to mention giving people confidence to actually *use* them!) I have thought about it and also done some experiments. For the initial git support, I think we first should try to get the pluggable backend support into git, and also the work to change the current files backend into a built-in pluggable backend. I.e. get everything in the https://github.com/rsahlberg/git/tree/backend-struct-db-2 branch except the last three patches. That brings us to a stage where we have pluggable backend support and we have one backend, the files backend, that works just like today. The last three patches in that series are then just confirmation that the pluggable backend approach works and we can add that a little later once we finish tests and other things. For tests there are the issues with "git-clone" and "git-init" requiring two additional arguments in order to set up and initialize a repository to use the "database daemon backend". Other future backends I would imagine would have similar needs. The way I handle in the experiments I did was to use two new environment variables GIT_INIT and GIT_CLONE that would default to "git-clone" and "git-init" respectively and then just override them with GIT_INIT="git-init --db-repo-name=ROCKy --db-socket=/tmp/refsd.socket" when I wanted the tests to initialize a "database backend" repository. This required some updates to test-lib.sh and test-lib-functions.sh as well as the tests themself to use ${GIT_INIT} instead of git-init directly. I am not sure what is the best approach here is and would love if you could help out with this once we get the basic pluggable backend stuff in. > > It seems to me that a few steps are needed: > > * Each backend would need a suite of backend-aware tests that verify > proper operation *within* the backend. These tests would mostly use > low-level plumbing commands like update-refs to create/modify/delete > references, and would be allowed to grub around in the filesystem, talk > directly with the database, etc. to make sure that the commands have the > correct effects. For example, for the traditional filesystem backend, > these tests would be the ones to check that creating a reference causes > a file to spring into existence under $GIT_DIR/refs. Yes. Quite a few tests do muck around with the files directly. Some for good reasons but I think there are a lot of cases where the tests do it just out of convenience. For this we will need to convert the tests that don't strictly need to muck around with the files to use a backend agnostic method to do the same checks. For the tests that are truly testing the backend itself, such as a hypothetical test to check that a symbolic link to a ref behaves as it should, we will need a mechanism where we can conditionalize the tests based on what is the current backend. So lots of "if backend == database then skip this test" > > The tests for pack-refs, and all tests that care about the distinction > between packed and loose refs, would become part of the backend-aware > tests for the filesystem backend. > > All of the backend-aware tests should be run every time the test suite > is run (provided, of course, that the correct prerequisites are > available, and subject to being turned off manually). > > * The rest of the test suite has to be made backend-agnostic. For > example, such tests should *not* be allowed to look under $GIT_DIR for > the existence/absence of loose reference files [1] but would rather have > to inquire about references via git commands. > > * It should be possible for the developer to choose easily which > reference backend to use when running the agnostic part of the test > suite. The chosen backend should be used to run *all* backend-agnostic > tests. > Agree. It would be great if we could work on this together. > A database-backed backend might even want to be testable in two modes: > one
Re: [PATCH 0/5] ref-transactions-send-pack
Ping On Thu, Jul 31, 2014 at 2:39 PM, Ronnie Sahlberg wrote: > List, > > This small patch series adds atomic-push support to for pushes. > By default git will use the old style non-atomic updates for pushes, > as not to cause disruption in client scripts that may depend on that > behaviour. > > Command line arguments are introduced to allow the client side to request/ > negotiate atomic pushes if the remote repo supports it. > There is also a new configuration variable where a repo can set that it > wants all pushes to become atomic whether the client requests it or not. > > This patch series is called ref-transactions-send-pack and depends on/is built > ontop of the series called ref-transactions-req-strbuf-err > > > Ronnie Sahlberg (5): > receive-pack.c: add protocol support to negotiate atomic-push > send-pack.c: add an --atomic-push command line argument > receive-pack.c: use a single transaction when atomic-push is > negotiated > receive-pack.c: add receive.atomicpush configuration option > push.c: add an --atomic-push argument > > Documentation/config.txt| 5 > Documentation/git-push.txt | 7 - > Documentation/git-send-pack.txt | 7 - > builtin/push.c | 2 ++ > builtin/receive-pack.c | 66 > + > builtin/send-pack.c | 6 +++- > send-pack.c | 18 +-- > send-pack.h | 1 + > transport.c | 1 + > transport.h | 1 + > 10 files changed, 96 insertions(+), 18 deletions(-) > > -- > 2.0.1.528.gd0e7a84 > -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/5] ref-transactions-req-strbuf-err
Ping ? On Thu, Jul 31, 2014 at 2:25 PM, Ronnie Sahlberg wrote: > List, > > This is the next patch series in the ref transaction work. > This patch series is called ref-transactions-req-strbuf-err and builds ontop > of the series called ref-transactions-req-packed-refs which is origin/pu > > > This patch series mainly adds some nice strbuf arguments to some functions to > pass errors back to callers. > The only thing noteworthy is that we finally get to remove > -enum action_on_err { > - UPDATE_REFS_MSG_ON_ERR, > - UPDATE_REFS_DIE_ON_ERR, > - UPDATE_REFS_QUIET_ON_ERR > -}; > > aside from that there is little/nothing much interesting in there. > > > Ronnie Sahlberg (5): > refs.c: replace the onerr argument in update_ref with a strbuf err > refs.c: make add_packed_ref return an error instead of calling die > refs.c: make lock_packed_refs take an err argument > refs.c: add an err argument to commit_packed_refs > refs.c: add an err argument to pack_refs > > builtin/checkout.c | 7 ++- > builtin/clone.c | 23 +--- > builtin/merge.c | 20 --- > builtin/notes.c | 24 + > builtin/pack-refs.c | 8 ++- > builtin/reset.c | 12 +++-- > builtin/update-ref.c | 7 ++- > notes-cache.c| 2 +- > notes-utils.c| 5 +- > refs.c | 148 > +-- > refs.h | 13 ++--- > transport-helper.c | 7 ++- > transport.c | 9 ++-- > 13 files changed, 170 insertions(+), 115 deletions(-) > > -- > 2.0.1.523.g70700c9 > -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Fwd: Rebase safely (Re: cherry picking and merge)
[ sorry for the dup ] Begin forwarded message: On Aug 6, 2014, at 12:44 PM, Nico Williams wrote: > It's not a good idea to rebase a branch in a repo that others pull from. Well, so rebase is then out, as I don’t want to rebase _my_ tree, I want to rebase _the_ tree. Recall, I don’t want to cherry pick for my tree, I want to cherry pick for the tree. [ reads rest of email ] Oh, wait, maybe I have misunderstood the prohibition. I have: upstream <—— fsf | \ | v Me <—> master <—> coworker. Me is a git clone of master, coworker is a git clone of master. Master is a bare repo on a shared server where we put all of our work. upstream is a bare git repo of the fsf git tree for gcc. fsf is a box owned by other that hosts the gcc git repository. I do a git pull fsf in upstream from time to time, and a corresponding git merge fsf in Me from time to time. When I like my work I do a git push (to master exclusively). To go to upstream, we submit patches by hand, git is not really involved. I never pull into master from upstream (don’t even think that’s possible since they are both bare). I read the prohibition as don’t rebase my branch called master on Me and push it to master on master as others then pull master from master. Did I misunderstand? Instead, the prohibition is you can use push/pull freely and you can have as many coworkers as you want, just don’t use push -f and don’t let anyone push/pull from your own private clone. I had envisions that the rebase of master on Me once pushed to master and then pull from master to coworker is the exact case that would screw us. > The only use-case I've seen where a rebase-based workflow doesn't work Well, and now mine, which I claim is a the canonical open source use case. Can't use source, unless you import the source, can’t be real unless you can change the source, once you do that, you then need to merge in newer sources, and if the company has or will have more than a single individual and these folks are ever to work together, then they need to share the source between them. I’m trying to envision how anyone could ever use rebase. If you can’t share your work, it isn’t work. > is where you have multiple upstreams that you're following. I only have a single (for this repo) upstream. >> Now, I found the stack-overflow commentary first, and all the horrors >> of it, and all the nuances. I carefully read what people were doing, >> how what I wanted to related to what they were doing, and it sure felt >> like I was in the, don’t go there camp. > > A lot of people rant about rebase. They're wrong. They've distorted > your perspective. What I saw were the people that screwed their world and were trying to recover. It was a question, how do I recover, and what did I do wrong. There was no rant. Or, at least, I’m impervious to rants and don’t actually see them. I deal in the cold hard facts and transform the rant into what happened, what they did wrong, and how to avoid doing it myself. No, you’ve set my perspective, let me quote you: It's not a good idea to rebase a branch in a repo that others pull from. this matches the doc, matches the experience of users on stack overflow and matches what what I think is true. You are free to correct that if I am wrong. I don’t know why you think my perspective is distorted. Either, I can rebase all my patches, all my coworkers patches, and push those up to master and have all my coworkers pull from master and develop (meaning branches off master as well as patches to master) as normal, or I can’t. > There's just two simple rules to follow and you'll be safe: > > 1) NEVER git push -f (--force) to a "published" repo/branch. I can never use push -f. That seems trivial. git config --system receive.denyNonFastForwards true seems to be exactly what I would do to my master to enforce this rule. This then seems to permanently be a non-issue. > 2) NEVER work directly in a published repo. Instead work in a private > clone. I only ever work in a private to me clone, so I’m safe. The only published repo is a bare repo, which can’t be worked in by design, so, again, I think I’m perfectly safe. So, if that is true, why do others write such things as (from http://ctoinsights.wordpress.com/2012/06/29/git-flow-with-rebase/): > The way to get the best of both worlds is to be explicit about when to use > one versus the other. For us the simple rules to follow are: > • Rebase feature branches. > • Never rebase develop or master branch. (Always merge into develop and > master.) > • Never rebase public branches. master is public, I want to rebase master. This violates rule 3 above, but not any of your rules? I develop on master, thus violating rule 2. This does’t violate any of your rules? I want to rebase master, thus, violating rule 1. This doesn’t violate any of your rules? I
Re: [PATCH 3/7] Documentation: git-init: template directory: reword
On Wed, Aug 06, 2014 at 10:21:33AM -0700, Junio C Hamano wrote: > Linus Arver writes: > > > No, the unindenting/removal of blank lines is a non-grammar change and > > is not necessary, as it doesn't have any effect on the actual output > > (html/txt/manpage). > > > > I can either keep the same coding style with the rewording, or chop this > > into two commits, one for the rewording and another for reformatting. > > Which one do you suggest? > > If I were doing this change, I wouldn't touch the formatting, > because I did not find that the reformatted version would be any > easier to read or maintain compared to the original. > > But I suspect that you must have thought the reformatting was a good > thing to do for a reason, and I suspected I might have been missing > something obvious to you, and that was why I asked. If there is a > good reason to reformat, then lets hear it in the commit log message > of one of the two patches. Otherwise we can drop the reformatting > part. And well, considering that the rewording makes the separate items into a single sentence, I thought it would help readability to delete all the whitespace. In retrospect, I don't think this is a good enough reason to reformat. It was more of a personal writing style judgment call. I am dropping the reformatting part. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/7] Documentation: git-init: --separate-git-dir: clarify
On Wed, Aug 06, 2014 at 10:35:31AM -0700, Junio C Hamano wrote: > While I agree that it is a very good idea to state "what it does, > what it is for" with the very first sentence of the paragraph, > "separate the git repository from your working tree" does not say > much more than the name of the option "--separate-git-dir" already > tells the reader. Ah, I see. > And I do not offhand think of a better version > (and obviously I didn't think of any when the current text was > reviewed and committed). The second sentence in your version is > definitely an improvement over the first and the second sentences of > the original ("where it is supposed to be" does not give any new > information to those who don't know, and does not help those who > already know). OK. > Perhaps we can simply remove the first sentence from your version? Yes, I agree. I enjoy cutting excess verbiage. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/22] refs.c: create a public function for is_refname_available
Export a generic is_refname_available() function. We will need this as a public shared function later when we add additional refs backends since we want to keep using the same rules for ref naming across all backends. Signed-off-by: Ronnie Sahlberg --- refs.c | 29 ++--- refs.h | 6 ++ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/refs.c b/refs.c index 7e13c0f..4a22513 100644 --- a/refs.c +++ b/refs.c @@ -830,9 +830,9 @@ static int name_conflict_fn(struct ref_entry *entry, void *cb_data) * operation). skip contains a list of refs we want to skip checking for * conflicts with. */ -static int is_refname_available(const char *refname, - struct ref_dir *dir, - const char **skip, int skipnum) +static int is_refname_available_dir(const char *refname, + struct ref_dir *dir, + const char **skip, int skipnum) { struct name_conflict_cb data; data.refname = refname; @@ -1238,6 +1238,18 @@ static struct ref_dir *get_loose_refs(struct ref_cache *refs) return get_ref_dir(refs->loose); } +int is_refname_available(const char *refname, const char **skip, int skipnum) +{ + if (!is_refname_available_dir(refname, get_packed_refs(&ref_cache), + skip, skipnum)) + return 0; + + if (!is_refname_available_dir(refname, get_loose_refs(&ref_cache), + skip, skipnum)) + return 0; + return 1; +} + /* We allow "recursive" symbolic refs. Only within reason, though */ #define MAXDEPTH 5 #define MAXREFLEN (1024) @@ -2168,8 +2180,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, * name is a proper prefix of our refname. */ if (missing && -!is_refname_available(refname, get_packed_refs(&ref_cache), - skip, skipnum)) { +!is_refname_available_dir(refname, get_packed_refs(&ref_cache), + skip, skipnum)) { last_errno = ENOTDIR; goto error_return; } @@ -2676,12 +2688,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms return 1; } - if (!is_refname_available(newrefname, get_packed_refs(&ref_cache), - &oldrefname, 1)) - return 1; - - if (!is_refname_available(newrefname, get_loose_refs(&ref_cache), - &oldrefname, 1)) + if (!is_refname_available(newrefname, &oldrefname, 1)) return 1; log = reflog_exists(oldrefname); diff --git a/refs.h b/refs.h index f44b5c8..7b59044 100644 --- a/refs.h +++ b/refs.h @@ -131,6 +131,12 @@ extern int ref_exists(const char *); extern int is_branch(const char *refname); /* + * Check is a particular refname is available for creation. skip contains + * a list of refnames to exclude from the refname collission tests. + */ +int is_refname_available(const char *refname, const char **skip, int skipnum); + +/* * If refname is a non-symbolic reference that refers to a tag object, * and the tag can be (recursively) dereferenced to a non-tag object, * store the SHA1 of the referred-to object to sha1 and return 0. If -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/22] refs-common.c: move update_ref to refs-common.c
This change moves update_ref() to the refs-common.c file since this function does not contain any backend specific code. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 25 + refs.c| 23 --- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/refs-common.c b/refs-common.c index 44d96d2..cb884b2 100644 --- a/refs-common.c +++ b/refs-common.c @@ -1,2 +1,27 @@ /* common code for all ref backends */ +#include "cache.h" +#include "refs.h" + +int update_ref(const char *action, const char *refname, + const unsigned char *sha1, const unsigned char *oldval, + int flags, struct strbuf *e) +{ + struct ref_transaction *t; + struct strbuf err = STRBUF_INIT; + + t = transaction_begin(&err); + if (!t || + transaction_update_sha1(t, refname, sha1, oldval, flags, + !!oldval, action, &err) || + transaction_commit(t, &err)) { + const char *str = "update_ref failed for ref '%s': %s"; + + transaction_free(t); + if (e) + strbuf_addf(e, str, refname, err.buf); + strbuf_release(&err); + return 1; + } + return 0; +} diff --git a/refs.c b/refs.c index 4a22513..eb66cf7 100644 --- a/refs.c +++ b/refs.c @@ -3576,29 +3576,6 @@ int transaction_delete_sha1(struct ref_transaction *transaction, old_sha1, flags, have_old, msg, err); } -int update_ref(const char *action, const char *refname, - const unsigned char *sha1, const unsigned char *oldval, - int flags, struct strbuf *e) -{ - struct ref_transaction *t; - struct strbuf err = STRBUF_INIT; - - t = transaction_begin(&err); - if (!t || - transaction_update_sha1(t, refname, sha1, oldval, flags, - !!oldval, action, &err) || - transaction_commit(t, &err)) { - const char *str = "update_ref failed for ref '%s': %s"; - - transaction_free(t); - if (e) - strbuf_addf(e, str, refname, err.buf); - strbuf_release(&err); - return 1; - } - return 0; -} - static int ref_update_compare(const void *r1, const void *r2) { const struct ref_update * const *u1 = r1; -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/22] refs-common.c: move read_ref_at to the refs common file
This change moves read_ref_at() to the refs-common.c file since this function does not contain any backend specific code. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 114 ++ refs.c| 114 -- 2 files changed, 114 insertions(+), 114 deletions(-) diff --git a/refs-common.c b/refs-common.c index f99d83e..3d7354e 100644 --- a/refs-common.c +++ b/refs-common.c @@ -135,3 +135,117 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms transaction_free(transaction); return 1; } + +struct read_ref_at_cb { + const char *refname; + unsigned long at_time; + int cnt; + int reccnt; + unsigned char *sha1; + int found_it; + + unsigned char osha1[20]; + unsigned char nsha1[20]; + int tz; + unsigned long date; + char **msg; + unsigned long *cutoff_time; + int *cutoff_tz; + int *cutoff_cnt; +}; + +static int read_ref_at_ent(unsigned char *osha1, unsigned char *nsha1, + const char *id, unsigned long timestamp, int tz, + const char *message, void *cb_data) +{ + struct read_ref_at_cb *cb = cb_data; + + cb->reccnt++; + cb->tz = tz; + cb->date = timestamp; + + if (timestamp <= cb->at_time || cb->cnt == 0) { + if (cb->msg) + *cb->msg = xstrdup(message); + if (cb->cutoff_time) + *cb->cutoff_time = timestamp; + if (cb->cutoff_tz) + *cb->cutoff_tz = tz; + if (cb->cutoff_cnt) + *cb->cutoff_cnt = cb->reccnt - 1; + /* +* we have not yet updated cb->[n|o]sha1 so they still +* hold the values for the previous record. +*/ + if (!is_null_sha1(cb->osha1)) { + hashcpy(cb->sha1, nsha1); + if (hashcmp(cb->osha1, nsha1)) + warning("Log for ref %s has gap after %s.", + cb->refname, show_date(cb->date, cb->tz, DATE_RFC2822)); + } + else if (cb->date == cb->at_time) + hashcpy(cb->sha1, nsha1); + else if (hashcmp(nsha1, cb->sha1)) + warning("Log for ref %s unexpectedly ended on %s.", + cb->refname, show_date(cb->date, cb->tz, + DATE_RFC2822)); + hashcpy(cb->osha1, osha1); + hashcpy(cb->nsha1, nsha1); + cb->found_it = 1; + return 1; + } + hashcpy(cb->osha1, osha1); + hashcpy(cb->nsha1, nsha1); + if (cb->cnt > 0) + cb->cnt--; + return 0; +} + +static int read_ref_at_ent_oldest(unsigned char *osha1, unsigned char *nsha1, + const char *id, unsigned long timestamp, + int tz, const char *message, void *cb_data) +{ + struct read_ref_at_cb *cb = cb_data; + + if (cb->msg) + *cb->msg = xstrdup(message); + if (cb->cutoff_time) + *cb->cutoff_time = timestamp; + if (cb->cutoff_tz) + *cb->cutoff_tz = tz; + if (cb->cutoff_cnt) + *cb->cutoff_cnt = cb->reccnt; + hashcpy(cb->sha1, osha1); + if (is_null_sha1(cb->sha1)) + hashcpy(cb->sha1, nsha1); + /* We just want the first entry */ + return 1; +} + +int read_ref_at(const char *refname, unsigned long at_time, int cnt, + unsigned char *sha1, char **msg, + unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt) +{ + struct read_ref_at_cb cb; + + memset(&cb, 0, sizeof(cb)); + cb.refname = refname; + cb.at_time = at_time; + cb.cnt = cnt; + cb.msg = msg; + cb.cutoff_time = cutoff_time; + cb.cutoff_tz = cutoff_tz; + cb.cutoff_cnt = cutoff_cnt; + cb.sha1 = sha1; + + for_each_reflog_ent_reverse(refname, read_ref_at_ent, &cb); + + if (!cb.reccnt) + die("Log for %s is empty.", refname); + if (cb.found_it) + return 0; + + for_each_reflog_ent(refname, read_ref_at_ent_oldest, &cb); + + return 1; +} diff --git a/refs.c b/refs.c index 7d579be..52ca0bb 100644 --- a/refs.c +++ b/refs.c @@ -2935,120 +2935,6 @@ int create_symref(const char *ref_target, const char *refs_heads_master, return 0; } -struct read_ref_at_cb { - const char *refname; - unsigned long at_time; - int cnt; - int reccnt; - unsigned char *sha1; - int found_it; - - unsigned char osha1[20]; - unsigned char nsha1[20]; - int tz; - unsigned long date; - char **msg;
[PATCH 07/22] refs-common.c: move the hidden refs functions to the common code
This change moves the hidden refs functions to the refs-common.c file since these functions do not contain any backend specific code. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 44 refs.c| 43 --- 2 files changed, 44 insertions(+), 43 deletions(-) diff --git a/refs-common.c b/refs-common.c index 3d7354e..c40fa96 100644 --- a/refs-common.c +++ b/refs-common.c @@ -1,6 +1,7 @@ /* common code for all ref backends */ #include "cache.h" #include "refs.h" +#include "string-list.h" int update_ref(const char *action, const char *refname, const unsigned char *sha1, const unsigned char *oldval, @@ -249,3 +250,46 @@ int read_ref_at(const char *refname, unsigned long at_time, int cnt, return 1; } + +static struct string_list *hide_refs; + +int parse_hide_refs_config(const char *var, const char *value, const char *section) +{ + if (!strcmp("transfer.hiderefs", var) || + /* NEEDSWORK: use parse_config_key() once both are merged */ + (starts_with(var, section) && var[strlen(section)] == '.' && +!strcmp(var + strlen(section), ".hiderefs"))) { + char *ref; + int len; + + if (!value) + return config_error_nonbool(var); + ref = xstrdup(value); + len = strlen(ref); + while (len && ref[len - 1] == '/') + ref[--len] = '\0'; + if (!hide_refs) { + hide_refs = xcalloc(1, sizeof(*hide_refs)); + hide_refs->strdup_strings = 1; + } + string_list_append(hide_refs, ref); + } + return 0; +} + +int ref_is_hidden(const char *refname) +{ + struct string_list_item *item; + + if (!hide_refs) + return 0; + for_each_string_list_item(item, hide_refs) { + int len; + if (!starts_with(refname, item->string)) + continue; + len = strlen(item->string); + if (!refname[len] || refname[len] == '/') + return 1; + } + return 0; +} diff --git a/refs.c b/refs.c index 52ca0bb..6181edf 100644 --- a/refs.c +++ b/refs.c @@ -3796,46 +3796,3 @@ char *shorten_unambiguous_ref(const char *refname, int strict) free(short_name); return xstrdup(refname); } - -static struct string_list *hide_refs; - -int parse_hide_refs_config(const char *var, const char *value, const char *section) -{ - if (!strcmp("transfer.hiderefs", var) || - /* NEEDSWORK: use parse_config_key() once both are merged */ - (starts_with(var, section) && var[strlen(section)] == '.' && -!strcmp(var + strlen(section), ".hiderefs"))) { - char *ref; - int len; - - if (!value) - return config_error_nonbool(var); - ref = xstrdup(value); - len = strlen(ref); - while (len && ref[len - 1] == '/') - ref[--len] = '\0'; - if (!hide_refs) { - hide_refs = xcalloc(1, sizeof(*hide_refs)); - hide_refs->strdup_strings = 1; - } - string_list_append(hide_refs, ref); - } - return 0; -} - -int ref_is_hidden(const char *refname) -{ - struct string_list_item *item; - - if (!hide_refs) - return 0; - for_each_string_list_item(item, hide_refs) { - int len; - if (!starts_with(refname, item->string)) - continue; - len = strlen(item->string); - if (!refname[len] || refname[len] == '/') - return 1; - } - return 0; -} -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/22] backend-struct-db
List, This series is called backend-struct-db and is also available at https://github.com/rsahlberg/git/tree/backend-struct-db This series is built on and follows after the series ref-transactions-send-pack This series does not change any logic or behaviour but mainly just shuffles code around and adds method pointers for the backend functions. The first patch adds a new public function for checking if a refname is available or not. This function is needed not because we want to have different is_refname_available semantics for different backends, we don't, but because its implementation is quite dependant on the backend type. 15 of the patches, the refs-common.c patches, focuses on moving all backend agnostic refs functions to a common file. This file will contain all backend agnostic refs functions. The last 6 patches adds a backend structure with the methods we need to describe a pluggable backend. Currently we only have one built in backend, the current files based backend. These patches do not change any of the behavior other than that we now call the methods through backend specific wrapper functions rather than calling them directly. At this stage we now have a defined set of methods needed for a refs backend and we can start building and adding new types of ref backends to git. Ronnie Sahlberg (22): refs.c: create a public function for is_refname_available refs-common.c: create a file to host all common refs code refs-common.c: move update_ref to refs-common.c refs-common.c: move delete_ref to the common code refs-common.c: move rename_ref to the common code refs-common.c: move read_ref_at to the refs common file refs-common.c: move the hidden refs functions to the common code refs-common.c: move dwim and friend functions to refs common refs-common.c: move warn_if_dangling_symref* to refs-common refs-common.c: move read_ref, read_ref_full and ref_exists to common refs-common.c: move resolve_refdup to common refs-common.c: move check_refname_component to the common code refs-common.c: move is_branch to the common code refs-common.c: move names_conflict to the common code refs-common.c: move prettify_refname to the common code refs-common.c: move ref iterators to the common code refs.c: add a backend method structure with transaction functions refs.c: add reflog backend methods refs.c: add methods for misc ref operations refs.c: add methods for head_ref* refs.c: add methods for the ref iterators refs-be-files.c: rename refs.c to refs-be-files.c Makefile|3 +- refs-be-files.c | 3343 + refs-common.c | 956 + refs.c | 4082 --- refs.h | 117 ++ 5 files changed, 4418 insertions(+), 4083 deletions(-) create mode 100644 refs-be-files.c create mode 100644 refs-common.c delete mode 100644 refs.c -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/22] refs-common.c: move warn_if_dangling_symref* to refs-common
These functions do not use any backend specific code so we can move them to the common code. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 52 refs.c| 52 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/refs-common.c b/refs-common.c index ac081e1..ab3a118 100644 --- a/refs-common.c +++ b/refs-common.c @@ -495,3 +495,55 @@ char *shorten_unambiguous_ref(const char *refname, int strict) free(short_name); return xstrdup(refname); } + +struct warn_if_dangling_data { + FILE *fp; + const char *refname; + const struct string_list *refnames; + const char *msg_fmt; +}; + +static int warn_if_dangling_symref(const char *refname, const unsigned char *sha1, + int flags, void *cb_data) +{ + struct warn_if_dangling_data *d = cb_data; + const char *resolves_to; + unsigned char junk[20]; + + if (!(flags & REF_ISSYMREF)) + return 0; + + resolves_to = resolve_ref_unsafe(refname, junk, 0, NULL); + if (!resolves_to + || (d->refname + ? strcmp(resolves_to, d->refname) + : !string_list_has_string(d->refnames, resolves_to))) { + return 0; + } + + fprintf(d->fp, d->msg_fmt, refname); + fputc('\n', d->fp); + return 0; +} + +void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname) +{ + struct warn_if_dangling_data data; + + data.fp = fp; + data.refname = refname; + data.refnames = NULL; + data.msg_fmt = msg_fmt; + for_each_rawref(warn_if_dangling_symref, &data); +} + +void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames) +{ + struct warn_if_dangling_data data; + + data.fp = fp; + data.refname = NULL; + data.refnames = refnames; + data.msg_fmt = msg_fmt; + for_each_rawref(warn_if_dangling_symref, &data); +} diff --git a/refs.c b/refs.c index 56e146f..40c329b 100644 --- a/refs.c +++ b/refs.c @@ -1667,58 +1667,6 @@ int peel_ref(const char *refname, unsigned char *sha1) return peel_object(base, sha1); } -struct warn_if_dangling_data { - FILE *fp; - const char *refname; - const struct string_list *refnames; - const char *msg_fmt; -}; - -static int warn_if_dangling_symref(const char *refname, const unsigned char *sha1, - int flags, void *cb_data) -{ - struct warn_if_dangling_data *d = cb_data; - const char *resolves_to; - unsigned char junk[20]; - - if (!(flags & REF_ISSYMREF)) - return 0; - - resolves_to = resolve_ref_unsafe(refname, junk, 0, NULL); - if (!resolves_to - || (d->refname - ? strcmp(resolves_to, d->refname) - : !string_list_has_string(d->refnames, resolves_to))) { - return 0; - } - - fprintf(d->fp, d->msg_fmt, refname); - fputc('\n', d->fp); - return 0; -} - -void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname) -{ - struct warn_if_dangling_data data; - - data.fp = fp; - data.refname = refname; - data.refnames = NULL; - data.msg_fmt = msg_fmt; - for_each_rawref(warn_if_dangling_symref, &data); -} - -void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames) -{ - struct warn_if_dangling_data data; - - data.fp = fp; - data.refname = NULL; - data.refnames = refnames; - data.msg_fmt = msg_fmt; - for_each_rawref(warn_if_dangling_symref, &data); -} - /* * Call fn for each reference in the specified ref_cache, omitting * references not in the containing_dir of base. fn is called for all -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 20/22] refs.c: add methods for head_ref*
Add methods for the head_ref* functions. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 15 +++ refs.c| 10 +++--- refs.h| 8 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/refs-common.c b/refs-common.c index 45e6fca..d9308a3 100644 --- a/refs-common.c +++ b/refs-common.c @@ -903,3 +903,18 @@ int resolve_gitlink_ref(const char *path, const char *refname, { return refs->resolve_gitlink_ref(path, refname, sha1); } + +int head_ref(each_ref_fn fn, void *cb_data) +{ + return refs->head_ref(fn, cb_data); +} + +int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) +{ + return refs->head_ref_submodule(submodule, fn, cb_data); +} + +int head_ref_namespaced(each_ref_fn fn, void *cb_data) +{ + return refs->head_ref_namespaced(fn, cb_data); +} diff --git a/refs.c b/refs.c index c4076f3..94d6160 100644 --- a/refs.c +++ b/refs.c @@ -1600,12 +1600,12 @@ static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data) return 0; } -int head_ref(each_ref_fn fn, void *cb_data) +static int files_head_ref(each_ref_fn fn, void *cb_data) { return do_head_ref(NULL, fn, cb_data); } -int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) +static int files_head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) { return do_head_ref(submodule, fn, cb_data); } @@ -1636,7 +1636,7 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data) return do_for_each_ref(&ref_cache, "refs/replace/", fn, 13, 0, cb_data); } -int head_ref_namespaced(each_ref_fn fn, void *cb_data) +static int files_head_ref_namespaced(each_ref_fn fn, void *cb_data) { struct strbuf buf = STRBUF_INIT; int ret = 0; @@ -3326,6 +3326,10 @@ struct ref_be refs_files = { .peel_ref = files_peel_ref, .create_symref = files_create_symref, .resolve_gitlink_ref= files_resolve_gitlink_ref, + + .head_ref = files_head_ref, + .head_ref_submodule = files_head_ref_submodule, + .head_ref_namespaced= files_head_ref_namespaced, }; struct ref_be *refs = &refs_files; diff --git a/refs.h b/refs.h index c56bfcd..b35c406 100644 --- a/refs.h +++ b/refs.h @@ -397,6 +397,11 @@ typedef int (*create_symref_fn)(const char *ref_target, typedef int (*resolve_gitlink_ref_fn)(const char *path, const char *refname, unsigned char *sha1); +typedef int (*head_ref_fn)(each_ref_fn fn, void *cb_data); +typedef int (*head_ref_submodule_fn)(const char *submodule, each_ref_fn fn, +void *cb_data); +typedef int (*head_ref_namespaced_fn)(each_ref_fn fn, void *cb_data); + struct ref_be { transaction_begin_fn transaction_begin; transaction_update_sha1_fn transaction_update_sha1; @@ -420,6 +425,9 @@ struct ref_be { create_symref_fn create_symref; resolve_gitlink_ref_fn resolve_gitlink_ref; + head_ref_fn head_ref; + head_ref_submodule_fn head_ref_submodule; + head_ref_namespaced_fn head_ref_namespaced; }; extern struct ref_be *refs; -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/22] refs-common.c: move resolve_refdup to common
This function can be shared across all refs backends so move it to the common code. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 6 ++ refs.c| 6 -- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/refs-common.c b/refs-common.c index 37d3d14..655a1a0 100644 --- a/refs-common.c +++ b/refs-common.c @@ -565,3 +565,9 @@ int ref_exists(const char *refname) unsigned char sha1[20]; return !!resolve_ref_unsafe(refname, sha1, RESOLVE_REF_READING, NULL); } + +char *resolve_refdup(const char *ref, unsigned char *sha1, int flags, int *ref_flag) +{ + const char *ret = resolve_ref_unsafe(ref, sha1, flags, ref_flag); + return ret ? xstrdup(ret) : NULL; +} diff --git a/refs.c b/refs.c index a94378e..ed7bc61 100644 --- a/refs.c +++ b/refs.c @@ -1501,12 +1501,6 @@ const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int fla } } -char *resolve_refdup(const char *ref, unsigned char *sha1, int flags, int *ref_flag) -{ - const char *ret = resolve_ref_unsafe(ref, sha1, flags, ref_flag); - return ret ? xstrdup(ret) : NULL; -} - /* The argument to filter_refs */ struct ref_filter { const char *pattern; -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/22] refs-common.c: move dwim and friend functions to refs common
These functions do not contain any backend specific code so we can move them to the common code and share across all backends. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 202 ++ refs.c| 202 -- 2 files changed, 202 insertions(+), 202 deletions(-) diff --git a/refs-common.c b/refs-common.c index c40fa96..ac081e1 100644 --- a/refs-common.c +++ b/refs-common.c @@ -293,3 +293,205 @@ int ref_is_hidden(const char *refname) } return 0; } + +static const char *ref_rev_parse_rules[] = { + "%.*s", + "refs/%.*s", + "refs/tags/%.*s", + "refs/heads/%.*s", + "refs/remotes/%.*s", + "refs/remotes/%.*s/HEAD", + NULL +}; + +int refname_match(const char *abbrev_name, const char *full_name) +{ + const char **p; + const int abbrev_name_len = strlen(abbrev_name); + + for (p = ref_rev_parse_rules; *p; p++) { + if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) { + return 1; + } + } + + return 0; +} + +/* + * *string and *len will only be substituted, and *string returned (for + * later free()ing) if the string passed in is a magic short-hand form + * to name a branch. + */ +static char *substitute_branch_name(const char **string, int *len) +{ + struct strbuf buf = STRBUF_INIT; + int ret = interpret_branch_name(*string, *len, &buf); + + if (ret == *len) { + size_t size; + *string = strbuf_detach(&buf, &size); + *len = size; + return (char *)*string; + } + + return NULL; +} + +int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) +{ + char *last_branch = substitute_branch_name(&str, &len); + const char **p, *r; + int refs_found = 0; + + *ref = NULL; + for (p = ref_rev_parse_rules; *p; p++) { + char fullref[PATH_MAX]; + unsigned char sha1_from_ref[20]; + unsigned char *this_result; + int flag; + + this_result = refs_found ? sha1_from_ref : sha1; + mksnpath(fullref, sizeof(fullref), *p, len, str); + r = resolve_ref_unsafe(fullref, this_result, + RESOLVE_REF_READING, &flag); + if (r) { + if (!refs_found++) + *ref = xstrdup(r); + if (!warn_ambiguous_refs) + break; + } else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) { + warning("ignoring dangling symref %s.", fullref); + } else if ((flag & REF_ISBROKEN) && strchr(fullref, '/')) { + warning("ignoring broken ref %s.", fullref); + } + } + free(last_branch); + return refs_found; +} + +int dwim_log(const char *str, int len, unsigned char *sha1, char **log) +{ + char *last_branch = substitute_branch_name(&str, &len); + const char **p; + int logs_found = 0; + + *log = NULL; + for (p = ref_rev_parse_rules; *p; p++) { + unsigned char hash[20]; + char path[PATH_MAX]; + const char *ref, *it; + + mksnpath(path, sizeof(path), *p, len, str); + ref = resolve_ref_unsafe(path, hash, RESOLVE_REF_READING, NULL); + if (!ref) + continue; + if (reflog_exists(path)) + it = path; + else if (strcmp(ref, path) && reflog_exists(ref)) + it = ref; + else + continue; + if (!logs_found++) { + *log = xstrdup(it); + hashcpy(sha1, hash); + } + if (!warn_ambiguous_refs) + break; + } + free(last_branch); + return logs_found; +} + +char *shorten_unambiguous_ref(const char *refname, int strict) +{ + int i; + static char **scanf_fmts; + static int nr_rules; + char *short_name; + + if (!nr_rules) { + /* +* Pre-generate scanf formats from ref_rev_parse_rules[]. +* Generate a format suitable for scanf from a +* ref_rev_parse_rules rule by interpolating "%s" at the +* location of the "%.*s". +*/ + size_t total_len = 0; + size_t offset = 0; + + /* the rule list is NULL terminated, count them first */ + for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++) + /* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */ + total_len += strlen(ref_rev_parse_rules[nr_rules]) -
[PATCH 18/22] refs.c: add reflog backend methods
Add methods for the reflog functions. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 32 refs.c| 19 +-- refs.h| 18 ++ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/refs-common.c b/refs-common.c index d4782ad..083964f 100644 --- a/refs-common.c +++ b/refs-common.c @@ -838,3 +838,35 @@ void transaction_free(struct ref_transaction *transaction) { return refs->transaction_free(transaction); } + +int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, + void *cb_data) +{ + return refs->for_each_reflog_ent_reverse(refname, fn, cb_data); +} + +int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, + void *cb_data) +{ + return refs->for_each_reflog_ent(refname, fn, cb_data); +} + +int for_each_reflog(each_ref_fn fn, void *cb_data) +{ + return refs->for_each_reflog(fn, cb_data); +} + +int reflog_exists(const char *refname) +{ + return refs->reflog_exists(refname); +} + +int create_reflog(const char *refname) +{ + return refs->create_reflog(refname); +} + +int delete_reflog(const char *refname) +{ + return refs->delete_reflog(refname); +} diff --git a/refs.c b/refs.c index bfb42d8..49fd360 100644 --- a/refs.c +++ b/refs.c @@ -2266,7 +2266,7 @@ static int copy_msg(char *buf, const char *msg) } /* This function must set a meaningful errno on failure */ -int create_reflog(const char *refname) +static int files_create_reflog(const char *refname) { int logfd, oflags = O_APPEND | O_WRONLY; char logfile[PATH_MAX]; @@ -2531,7 +2531,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master, return 0; } -int reflog_exists(const char *refname) +static int files_reflog_exists(const char *refname) { struct stat st; @@ -2539,7 +2539,7 @@ int reflog_exists(const char *refname) S_ISREG(st.st_mode); } -int delete_reflog(const char *refname) +static int files_delete_reflog(const char *refname) { return remove_path(git_path("logs/%s", refname)); } @@ -2583,7 +2583,7 @@ static char *find_beginning_of_line(char *bob, char *scan) return scan; } -int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data) +static int files_for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data) { struct strbuf sb = STRBUF_INIT; FILE *logfp; @@ -2660,7 +2660,7 @@ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void return ret; } -int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data) +static int files_for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data) { FILE *logfp; struct strbuf sb = STRBUF_INIT; @@ -2721,7 +2721,7 @@ static int do_for_each_reflog(struct strbuf *name, each_ref_fn fn, void *cb_data return retval; } -int for_each_reflog(each_ref_fn fn, void *cb_data) +static int files_for_each_reflog(each_ref_fn fn, void *cb_data) { int retval; struct strbuf name; @@ -3310,6 +3310,13 @@ struct ref_be refs_files = { .transaction_update_reflog = files_transaction_update_reflog, .transaction_commit = files_transaction_commit, .transaction_free = files_transaction_free, + + .for_each_reflog_ent= files_for_each_reflog_ent, + .for_each_reflog_ent_reverse= files_for_each_reflog_ent_reverse, + .for_each_reflog= files_for_each_reflog, + .reflog_exists = files_reflog_exists, + .create_reflog = files_create_reflog, + .delete_reflog = files_delete_reflog, }; struct ref_be *refs = &refs_files; diff --git a/refs.h b/refs.h index 7b92241..f630e20 100644 --- a/refs.h +++ b/refs.h @@ -373,6 +373,17 @@ typedef int (*transaction_commit_fn)(struct ref_transaction *transaction, struct strbuf *err); typedef void (*transaction_free_fn)(struct ref_transaction *transaction); +typedef int (*for_each_reflog_ent_fn)(const char *refname, + each_reflog_ent_fn fn, + void *cb_data); +typedef int (*for_each_reflog_ent_reverse_fn)(const char *refname, + each_reflog_ent_fn fn, + void *cb_data); +typedef int (*for_each_reflog_fn)(each_ref_fn fn, void *cb_data); +typedef int (*reflog_exists_fn)(const char *refname); +typedef int (*create_reflog_fn)(const char *refname); +typedef int (*delete_reflog_fn)(const char *refname); + struct ref_be { transaction_begin_fn transaction_begin; transaction_update_sha1_fn transaction_update_sha1; @@ -381,6 +392,
[PATCH 17/22] refs.c: add a backend method structure with transaction functions
Add a ref structure for backend methods. Start by adding method pointers for the transaction functions. Rename the existing transaction functions to files_* and make them static. Add new transaction functions that just pass through to the appropriate methods for the backend. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 54 +++ refs.c| 68 +++ refs.h| 35 ++ 3 files changed, 130 insertions(+), 27 deletions(-) diff --git a/refs-common.c b/refs-common.c index 3b20db3..d4782ad 100644 --- a/refs-common.c +++ b/refs-common.c @@ -784,3 +784,57 @@ int check_refname_format(const char *refname, int flags) return -1; /* Refname has only one component. */ return 0; } + +/* backend functions */ +struct ref_transaction *transaction_begin(struct strbuf *err) +{ + return refs->transaction_begin(err); +} + +int transaction_update_sha1(struct ref_transaction *transaction, + const char *refname, const unsigned char *new_sha1, + const unsigned char *old_sha1, int flags, + int have_old, const char *msg, struct strbuf *err) +{ + return refs->transaction_update_sha1(transaction, refname, new_sha1, +old_sha1, flags, have_old, msg, +err); +} + +int transaction_create_sha1(struct ref_transaction *transaction, + const char *refname, const unsigned char *new_sha1, + int flags, const char *msg, struct strbuf *err) +{ + return refs->transaction_create_sha1(transaction, refname, new_sha1, +flags, msg, err); +} +int transaction_delete_sha1(struct ref_transaction *transaction, + const char *refname, const unsigned char *old_sha1, + int flags, int have_old, const char *msg, + struct strbuf *err) +{ + return refs->transaction_delete_sha1(transaction, refname, old_sha1, +flags, have_old, msg, err); +} + +int transaction_update_reflog(struct ref_transaction *transaction, + const char *refname, + const unsigned char *new_sha1, + const unsigned char *old_sha1, + struct reflog_committer_info *ci, + const char *msg, int flags, + struct strbuf *err) +{ + return refs->transaction_update_reflog(transaction, refname, new_sha1, + old_sha1, ci, msg, flags, err); +} + +int transaction_commit(struct ref_transaction *transaction, struct strbuf *err) +{ + return refs->transaction_commit(transaction, err); +} + +void transaction_free(struct ref_transaction *transaction) +{ + return refs->transaction_free(transaction); +} diff --git a/refs.c b/refs.c index 9aa88ef..bfb42d8 100644 --- a/refs.c +++ b/refs.c @@ -2792,12 +2792,12 @@ struct ref_transaction { enum ref_transaction_state state; }; -struct ref_transaction *transaction_begin(struct strbuf *err) +static struct ref_transaction *files_transaction_begin(struct strbuf *err) { return xcalloc(1, sizeof(struct ref_transaction)); } -void transaction_free(struct ref_transaction *transaction) +static void files_transaction_free(struct ref_transaction *transaction) { int i; @@ -2827,13 +2827,13 @@ static struct ref_update *add_update(struct ref_transaction *transaction, return update; } -int transaction_update_reflog(struct ref_transaction *transaction, - const char *refname, - const unsigned char *new_sha1, - const unsigned char *old_sha1, - struct reflog_committer_info *ci, - const char *msg, int flags, - struct strbuf *err) +static int files_transaction_update_reflog(struct ref_transaction *transaction, + const char *refname, + const unsigned char *new_sha1, + const unsigned char *old_sha1, + struct reflog_committer_info *ci, + const char *msg, int flags, + struct strbuf *err) { struct ref_update *update; int i; @@ -2880,12 +2880,13 @@ int transaction_update_reflog(struct ref_transaction *transaction, return 0; } -int transaction_update_sha1(struct ref_transaction *transaction, - const char *refname, -
[PATCH 13/22] refs-common.c: move is_branch to the common code
Signed-off-by: Ronnie Sahlberg --- refs-common.c | 5 + refs.c| 5 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/refs-common.c b/refs-common.c index f8b79e0..5f83d7e 100644 --- a/refs-common.c +++ b/refs-common.c @@ -3,6 +3,11 @@ #include "refs.h" #include "string-list.h" +int is_branch(const char *refname) +{ + return !strcmp(refname, "HEAD") || starts_with(refname, "refs/heads/"); +} + int update_ref(const char *action, const char *refname, const unsigned char *sha1, const unsigned char *oldval, int flags, struct strbuf *e) diff --git a/refs.c b/refs.c index 55bced9..70c034c 100644 --- a/refs.c +++ b/refs.c @@ -2483,11 +2483,6 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1, return 0; } -int is_branch(const char *refname) -{ - return !strcmp(refname, "HEAD") || starts_with(refname, "refs/heads/"); -} - static int write_sha1_update_reflog(struct ref_lock *lock, const unsigned char *sha1, const char *logmsg) { -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 16/22] refs-common.c: move ref iterators to the common code
Signed-off-by: Ronnie Sahlberg --- refs-common.c | 81 +++ refs.c| 81 --- 2 files changed, 81 insertions(+), 81 deletions(-) diff --git a/refs-common.c b/refs-common.c index d8a295c..3b20db3 100644 --- a/refs-common.c +++ b/refs-common.c @@ -668,6 +668,87 @@ out: return cp - refname; } +/* The argument to filter_refs */ +struct ref_filter { + const char *pattern; + each_ref_fn *fn; + void *cb_data; +}; + +static int filter_refs(const char *refname, const unsigned char *sha1, int flags, + void *data) +{ + struct ref_filter *filter = (struct ref_filter *)data; + if (wildmatch(filter->pattern, refname, 0, NULL)) + return 0; + return filter->fn(refname, sha1, flags, filter->cb_data); +} + +int for_each_tag_ref(each_ref_fn fn, void *cb_data) +{ + return for_each_ref_in("refs/tags/", fn, cb_data); +} + +int for_each_tag_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) +{ + return for_each_ref_in_submodule(submodule, "refs/tags/", fn, cb_data); +} + +int for_each_branch_ref(each_ref_fn fn, void *cb_data) +{ + return for_each_ref_in("refs/heads/", fn, cb_data); +} + +int for_each_branch_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) +{ + return for_each_ref_in_submodule(submodule, "refs/heads/", fn, cb_data); +} + +int for_each_remote_ref(each_ref_fn fn, void *cb_data) +{ + return for_each_ref_in("refs/remotes/", fn, cb_data); +} + +int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) +{ + return for_each_ref_in_submodule(submodule, "refs/remotes/", fn, cb_data); +} + +int for_each_glob_ref_in(each_ref_fn fn, const char *pattern, + const char *prefix, void *cb_data) +{ + struct strbuf real_pattern = STRBUF_INIT; + struct ref_filter filter; + int ret; + + if (!prefix && !starts_with(pattern, "refs/")) + strbuf_addstr(&real_pattern, "refs/"); + else if (prefix) + strbuf_addstr(&real_pattern, prefix); + strbuf_addstr(&real_pattern, pattern); + + if (!has_glob_specials(pattern)) { + /* Append implied '/' '*' if not present. */ + if (real_pattern.buf[real_pattern.len - 1] != '/') + strbuf_addch(&real_pattern, '/'); + /* No need to check for '*', there is none. */ + strbuf_addch(&real_pattern, '*'); + } + + filter.pattern = real_pattern.buf; + filter.fn = fn; + filter.cb_data = cb_data; + ret = for_each_ref(filter_refs, &filter); + + strbuf_release(&real_pattern); + return ret; +} + +int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data) +{ + return for_each_glob_ref_in(fn, pattern, NULL, cb_data); +} + int check_refname_format(const char *refname, int flags) { int component_len, component_count = 0; diff --git a/refs.c b/refs.c index fb9c614..9aa88ef 100644 --- a/refs.c +++ b/refs.c @@ -1377,22 +1377,6 @@ const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int fla } } -/* The argument to filter_refs */ -struct ref_filter { - const char *pattern; - each_ref_fn *fn; - void *cb_data; -}; - -static int filter_refs(const char *refname, const unsigned char *sha1, int flags, - void *data) -{ - struct ref_filter *filter = (struct ref_filter *)data; - if (wildmatch(filter->pattern, refname, 0, NULL)) - return 0; - return filter->fn(refname, sha1, flags, filter->cb_data); -} - enum peel_status { /* object was peeled successfully: */ PEEL_PEELED = 0, @@ -1646,36 +1630,6 @@ int for_each_ref_in_submodule(const char *submodule, const char *prefix, return do_for_each_ref(get_ref_cache(submodule), prefix, fn, strlen(prefix), 0, cb_data); } -int for_each_tag_ref(each_ref_fn fn, void *cb_data) -{ - return for_each_ref_in("refs/tags/", fn, cb_data); -} - -int for_each_tag_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) -{ - return for_each_ref_in_submodule(submodule, "refs/tags/", fn, cb_data); -} - -int for_each_branch_ref(each_ref_fn fn, void *cb_data) -{ - return for_each_ref_in("refs/heads/", fn, cb_data); -} - -int for_each_branch_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) -{ - return for_each_ref_in_submodule(submodule, "refs/heads/", fn, cb_data); -} - -int for_each_remote_ref(each_ref_fn fn, void *cb_data) -{ - return for_each_ref_in("refs/remotes/", fn, cb_data); -} - -int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) -{ - return for_each_ref_in_submodule(submodule, "refs/remotes/", fn, cb_data); -} - int for_each_replace_ref(each_r
[PATCH 21/22] refs.c: add methods for the ref iterators
Signed-off-by: Ronnie Sahlberg --- refs-common.c | 36 refs.c| 22 +++--- refs.h| 20 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/refs-common.c b/refs-common.c index d9308a3..11c3660 100644 --- a/refs-common.c +++ b/refs-common.c @@ -918,3 +918,39 @@ int head_ref_namespaced(each_ref_fn fn, void *cb_data) { return refs->head_ref_namespaced(fn, cb_data); } + +int for_each_ref(each_ref_fn fn, void *cb_data) +{ + return refs->for_each_ref(fn, cb_data); +} + +int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) +{ + return refs->for_each_ref_submodule(submodule, fn, cb_data); +} + +int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data) +{ + return refs->for_each_ref_in(prefix, fn, cb_data); +} + +int for_each_ref_in_submodule(const char *submodule, const char *prefix, + each_ref_fn fn, void *cb_data) +{ + return refs->for_each_ref_in_submodule(submodule, prefix, fn, cb_data); +} + +int for_each_rawref(each_ref_fn fn, void *cb_data) +{ + return refs->for_each_rawref(fn, cb_data); +} + +int for_each_namespaced_ref(each_ref_fn fn, void *cb_data) +{ + return refs->for_each_namespaced_ref(fn, cb_data); +} + +int for_each_replace_ref(each_ref_fn fn, void *cb_data) +{ + return refs->for_each_replace_ref(fn, cb_data); +} diff --git a/refs.c b/refs.c index 94d6160..1b2272d 100644 --- a/refs.c +++ b/refs.c @@ -1610,28 +1610,28 @@ static int files_head_ref_submodule(const char *submodule, each_ref_fn fn, void return do_head_ref(submodule, fn, cb_data); } -int for_each_ref(each_ref_fn fn, void *cb_data) +static int files_for_each_ref(each_ref_fn fn, void *cb_data) { return do_for_each_ref(&ref_cache, "", fn, 0, 0, cb_data); } -int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) +static int files_for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) { return do_for_each_ref(get_ref_cache(submodule), "", fn, 0, 0, cb_data); } -int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data) +static int files_for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data) { return do_for_each_ref(&ref_cache, prefix, fn, strlen(prefix), 0, cb_data); } -int for_each_ref_in_submodule(const char *submodule, const char *prefix, +static int files_for_each_ref_in_submodule(const char *submodule, const char *prefix, each_ref_fn fn, void *cb_data) { return do_for_each_ref(get_ref_cache(submodule), prefix, fn, strlen(prefix), 0, cb_data); } -int for_each_replace_ref(each_ref_fn fn, void *cb_data) +static int files_for_each_replace_ref(each_ref_fn fn, void *cb_data) { return do_for_each_ref(&ref_cache, "refs/replace/", fn, 13, 0, cb_data); } @@ -1651,7 +1651,7 @@ static int files_head_ref_namespaced(each_ref_fn fn, void *cb_data) return ret; } -int for_each_namespaced_ref(each_ref_fn fn, void *cb_data) +static int files_for_each_namespaced_ref(each_ref_fn fn, void *cb_data) { struct strbuf buf = STRBUF_INIT; int ret; @@ -1661,7 +1661,7 @@ int for_each_namespaced_ref(each_ref_fn fn, void *cb_data) return ret; } -int for_each_rawref(each_ref_fn fn, void *cb_data) +static int files_for_each_rawref(each_ref_fn fn, void *cb_data) { return do_for_each_ref(&ref_cache, "", fn, 0, DO_FOR_EACH_INCLUDE_BROKEN, cb_data); @@ -3330,6 +3330,14 @@ struct ref_be refs_files = { .head_ref = files_head_ref, .head_ref_submodule = files_head_ref_submodule, .head_ref_namespaced= files_head_ref_namespaced, + + .for_each_ref = files_for_each_ref, + .for_each_ref_submodule = files_for_each_ref_submodule, + .for_each_ref_in= files_for_each_ref_in, + .for_each_ref_in_submodule = files_for_each_ref_in_submodule, + .for_each_rawref= files_for_each_rawref, + .for_each_namespaced_ref= files_for_each_namespaced_ref, + .for_each_replace_ref = files_for_each_replace_ref, }; struct ref_be *refs = &refs_files; diff --git a/refs.h b/refs.h index b35c406..61b6728 100644 --- a/refs.h +++ b/refs.h @@ -402,6 +402,18 @@ typedef int (*head_ref_submodule_fn)(const char *submodule, each_ref_fn fn, void *cb_data); typedef int (*head_ref_namespaced_fn)(each_ref_fn fn, void *cb_data); +typedef int (*for_each_ref_fn)(each_ref_fn fn, void *cb_data); +typedef int (*for_each_ref_submodule_fn)(const char *submodule, each_ref_fn fn, +void *cb_data); +typedef int (*for_each_ref_in_fn)(const char *prefix, each_ref_fn fn, + voi
[PATCH 12/22] refs-common.c: move check_refname_component to the common code
This function does not contain any backend specific code so we can move it to the common code. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 110 ++ refs.c| 110 -- 2 files changed, 110 insertions(+), 110 deletions(-) diff --git a/refs-common.c b/refs-common.c index 655a1a0..f8b79e0 100644 --- a/refs-common.c +++ b/refs-common.c @@ -571,3 +571,113 @@ char *resolve_refdup(const char *ref, unsigned char *sha1, int flags, int *ref_f const char *ret = resolve_ref_unsafe(ref, sha1, flags, ref_flag); return ret ? xstrdup(ret) : NULL; } + +/* + * How to handle various characters in refnames: + * 0: An acceptable character for refs + * 1: End-of-component + * 2: ., look for a preceding . to reject .. in refs + * 3: {, look for a preceding @ to reject @{ in refs + * 4: A bad character: ASCII control characters, "~", "^", ":" or SP + */ +static unsigned char refname_disposition[256] = { + 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4 +}; + +/* + * Try to read one refname component from the front of refname. + * Return the length of the component found, or -1 if the component is + * not legal. It is legal if it is something reasonable to have under + * ".git/refs/"; We do not like it if: + * + * - any path component of it begins with ".", or + * - it has double dots "..", or + * - it has ASCII control character, "~", "^", ":" or SP, anywhere, or + * - it ends with a "/". + * - it ends with ".lock" + * - it contains a "\" (backslash) + */ +static int check_refname_component(const char *refname, int flags) +{ + const char *cp; + char last = '\0'; + + for (cp = refname; ; cp++) { + int ch = *cp & 255; + unsigned char disp = refname_disposition[ch]; + switch (disp) { + case 1: + goto out; + case 2: + if (last == '.') + return -1; /* Refname contains "..". */ + break; + case 3: + if (last == '@') + return -1; /* Refname contains "@{". */ + break; + case 4: + return -1; + } + last = ch; + } +out: + if (cp == refname) + return 0; /* Component has zero length. */ + if (refname[0] == '.') { + if (!(flags & REFNAME_DOT_COMPONENT)) + return -1; /* Component starts with '.'. */ + /* +* Even if leading dots are allowed, don't allow "." +* as a component (".." is prevented by a rule above). +*/ + if (refname[1] == '\0') + return -1; /* Component equals ".". */ + } + if (cp - refname >= 5 && !memcmp(cp - 5, ".lock", 5)) + return -1; /* Refname ends with ".lock". */ + return cp - refname; +} + +int check_refname_format(const char *refname, int flags) +{ + int component_len, component_count = 0; + + if (!strcmp(refname, "@")) + /* Refname is a single character '@'. */ + return -1; + + while (1) { + /* We are at the start of a path component. */ + component_len = check_refname_component(refname, flags); + if (component_len <= 0) { + if ((flags & REFNAME_REFSPEC_PATTERN) && + refname[0] == '*' && + (refname[1] == '\0' || refname[1] == '/')) { + /* Accept one wildcard as a full refname component. */ + flags &= ~REFNAME_REFSPEC_PATTERN; + component_len = 1; + } else { + return -1; + } + } + component_count++; + if (refname[component_len] == '\0') + break; + /* Skip to next component. */ + refname += component_len + 1; + } + + if (refname[component_len - 1] == '.') + return -1; /* Refname ends with '.'. */ + if (!(flags & REFNAME_ALLOW_ONELEVEL) && component_count < 2) + return -1; /* Refname has only one component. */ + return 0; +} diff --git a/refs.c b/refs.c index ed7bc61..55bced9 100644
[PATCH 15/22] refs-common.c: move prettify_refname to the common code
Signed-off-by: Ronnie Sahlberg --- refs-common.c | 9 + refs.c| 9 - 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/refs-common.c b/refs-common.c index 6eef80b..d8a295c 100644 --- a/refs-common.c +++ b/refs-common.c @@ -3,6 +3,15 @@ #include "refs.h" #include "string-list.h" +const char *prettify_refname(const char *name) +{ + return name + ( + starts_with(name, "refs/heads/") ? 11 : + starts_with(name, "refs/tags/") ? 10 : + starts_with(name, "refs/remotes/") ? 13 : + 0); +} + int names_conflict(const char *refname1, const char *refname2) { for (; *refname1 && *refname1 == *refname2; refname1++, refname2++) diff --git a/refs.c b/refs.c index 6542969..fb9c614 100644 --- a/refs.c +++ b/refs.c @@ -1747,15 +1747,6 @@ int for_each_rawref(each_ref_fn fn, void *cb_data) DO_FOR_EACH_INCLUDE_BROKEN, cb_data); } -const char *prettify_refname(const char *name) -{ - return name + ( - starts_with(name, "refs/heads/") ? 11 : - starts_with(name, "refs/tags/") ? 10 : - starts_with(name, "refs/remotes/") ? 13 : - 0); -} - static void unlock_ref(struct ref_lock *lock) { /* Do not free lock->lk -- atexit() still looks at them */ -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/22] refs-common.c: move read_ref, read_ref_full and ref_exists to common
These functions do not depend on the backend implementation so we can move them to the common code. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 18 ++ refs.c| 18 -- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/refs-common.c b/refs-common.c index ab3a118..37d3d14 100644 --- a/refs-common.c +++ b/refs-common.c @@ -547,3 +547,21 @@ void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_li data.msg_fmt = msg_fmt; for_each_rawref(warn_if_dangling_symref, &data); } + +int read_ref_full(const char *refname, unsigned char *sha1, int flags, int *ref_flag) +{ + if (resolve_ref_unsafe(refname, sha1, flags, ref_flag)) + return 0; + return -1; +} + +int read_ref(const char *refname, unsigned char *sha1) +{ + return read_ref_full(refname, sha1, RESOLVE_REF_READING, NULL); +} + +int ref_exists(const char *refname) +{ + unsigned char sha1[20]; + return !!resolve_ref_unsafe(refname, sha1, RESOLVE_REF_READING, NULL); +} diff --git a/refs.c b/refs.c index 40c329b..a94378e 100644 --- a/refs.c +++ b/refs.c @@ -1514,24 +1514,6 @@ struct ref_filter { void *cb_data; }; -int read_ref_full(const char *refname, unsigned char *sha1, int flags, int *ref_flag) -{ - if (resolve_ref_unsafe(refname, sha1, flags, ref_flag)) - return 0; - return -1; -} - -int read_ref(const char *refname, unsigned char *sha1) -{ - return read_ref_full(refname, sha1, RESOLVE_REF_READING, NULL); -} - -int ref_exists(const char *refname) -{ - unsigned char sha1[20]; - return !!resolve_ref_unsafe(refname, sha1, RESOLVE_REF_READING, NULL); -} - static int filter_refs(const char *refname, const unsigned char *sha1, int flags, void *data) { -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/22] refs-common.c: move names_conflict to the common code
Signed-off-by: Ronnie Sahlberg --- refs-common.c | 8 refs.c| 14 -- refs.h| 9 + 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/refs-common.c b/refs-common.c index 5f83d7e..6eef80b 100644 --- a/refs-common.c +++ b/refs-common.c @@ -3,6 +3,14 @@ #include "refs.h" #include "string-list.h" +int names_conflict(const char *refname1, const char *refname2) +{ + for (; *refname1 && *refname1 == *refname2; refname1++, refname2++) + ; + return (*refname1 == '\0' && *refname2 == '/') + || (*refname1 == '/' && *refname2 == '\0'); +} + int is_branch(const char *refname) { return !strcmp(refname, "HEAD") || starts_with(refname, "refs/heads/"); diff --git a/refs.c b/refs.c index 70c034c..6542969 100644 --- a/refs.c +++ b/refs.c @@ -676,20 +676,6 @@ static void prime_ref_dir(struct ref_dir *dir) prime_ref_dir(get_ref_dir(entry)); } } -/* - * Return true iff refname1 and refname2 conflict with each other. - * Two reference names conflict if one of them exactly matches the - * leading components of the other; e.g., "foo/bar" conflicts with - * both "foo" and with "foo/bar/baz" but not with "foo/bar" or - * "foo/barbados". - */ -static int names_conflict(const char *refname1, const char *refname2) -{ - for (; *refname1 && *refname1 == *refname2; refname1++, refname2++) - ; - return (*refname1 == '\0' && *refname2 == '/') - || (*refname1 == '/' && *refname2 == '\0'); -} struct name_conflict_cb { const char *refname; diff --git a/refs.h b/refs.h index 7b59044..5577824 100644 --- a/refs.h +++ b/refs.h @@ -128,6 +128,15 @@ int pack_refs(unsigned int flags, struct strbuf *err); extern int ref_exists(const char *); +/* + * Return true iff refname1 and refname2 conflict with each other. + * Two reference names conflict if one of them exactly matches the + * leading components of the other; e.g., "foo/bar" conflicts with + * both "foo" and with "foo/bar/baz" but not with "foo/bar" or + * "foo/barbados". + */ +int names_conflict(const char *refname1, const char *refname2); + extern int is_branch(const char *refname); /* -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/22] refs-common.c: create a file to host all common refs code
Create refs-common.c which will hold all backend agnostic refs code. Signed-off-by: Ronnie Sahlberg --- Makefile | 1 + refs-common.c | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 refs-common.c diff --git a/Makefile b/Makefile index 07ea105..7705136 100644 --- a/Makefile +++ b/Makefile @@ -858,6 +858,7 @@ LIB_OBJS += reachable.o LIB_OBJS += read-cache.o LIB_OBJS += reflog-walk.o LIB_OBJS += refs.o +LIB_OBJS += refs-common.o LIB_OBJS += remote.o LIB_OBJS += replace_object.o LIB_OBJS += rerere.o diff --git a/refs-common.c b/refs-common.c new file mode 100644 index 000..44d96d2 --- /dev/null +++ b/refs-common.c @@ -0,0 +1,2 @@ +/* common code for all ref backends */ + -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 19/22] refs.c: add methods for misc ref operations
Add ref backend methods for resolve_ref_unsafe_fn resolve_ref_unsafe; is_refname_available_fn is_refname_available; pack_refs_fn pack_refs; peel_ref_fn peel_ref; create_symref_fn create_symref; resolve_gitlink_ref_fn resolve_gitlink_ref; Signed-off-by: Ronnie Sahlberg --- refs-common.c | 33 + refs.c| 23 --- refs.h| 21 + 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/refs-common.c b/refs-common.c index 083964f..45e6fca 100644 --- a/refs-common.c +++ b/refs-common.c @@ -870,3 +870,36 @@ int delete_reflog(const char *refname) { return refs->delete_reflog(refname); } + +const char *resolve_ref_unsafe(const char *ref, unsigned char *sha1, + int reading, int *flag) +{ + return refs->resolve_ref_unsafe(ref, sha1, reading, flag); +} + +int is_refname_available(const char *refname, const char **skip, int skipnum) +{ + return refs->is_refname_available(refname, skip, skipnum); +} + +int pack_refs(unsigned int flags, struct strbuf *err) +{ + return refs->pack_refs(flags, err); +} + +int peel_ref(const char *refname, unsigned char *sha1) +{ + return refs->peel_ref(refname, sha1); +} + +int create_symref(const char *ref_target, const char *refs_heads_master, + const char *logmsg) +{ + return refs->create_symref(ref_target, refs_heads_master, logmsg); +} + +int resolve_gitlink_ref(const char *path, const char *refname, + unsigned char *sha1) +{ + return refs->resolve_gitlink_ref(path, refname, sha1); +} diff --git a/refs.c b/refs.c index 49fd360..c4076f3 100644 --- a/refs.c +++ b/refs.c @@ -1114,7 +1114,8 @@ static struct ref_dir *get_loose_refs(struct ref_cache *refs) return get_ref_dir(refs->loose); } -int is_refname_available(const char *refname, const char **skip, int skipnum) +static int files_is_refname_available(const char *refname, const char **skip, + int skipnum) { if (!is_refname_available_dir(refname, get_packed_refs(&ref_cache), skip, skipnum)) @@ -1188,7 +1189,7 @@ static int resolve_gitlink_ref_recursive(struct ref_cache *refs, return resolve_gitlink_ref_recursive(refs, p, sha1, recursion+1); } -int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1) +static int files_resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1) { int len = strlen(path), retval; char *submodule; @@ -1247,7 +1248,7 @@ static const char *handle_missing_loose_ref(const char *refname, } /* This function needs to return a meaningful errno on failure */ -const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int flags, int *ref_flag) +static const char *files_resolve_ref_unsafe(const char *refname, unsigned char *sha1, int flags, int *ref_flag) { int depth = MAXDEPTH; ssize_t len; @@ -1466,7 +1467,7 @@ static enum peel_status peel_entry(struct ref_entry *entry, int repeel) return status; } -int peel_ref(const char *refname, unsigned char *sha1) +static int files_peel_ref(const char *refname, unsigned char *sha1) { int flag; unsigned char base[20]; @@ -2095,7 +2096,7 @@ static void prune_refs(struct ref_to_prune *r) } } -int pack_refs(unsigned int flags, struct strbuf *err) +static int files_pack_refs(unsigned int flags, struct strbuf *err) { struct pack_refs_cb_data cbdata; @@ -2468,8 +2469,9 @@ static int write_ref_sha1(struct ref_lock *lock, return 0; } -int create_symref(const char *ref_target, const char *refs_heads_master, - const char *logmsg) +static int files_create_symref(const char *ref_target, + const char *refs_heads_master, + const char *logmsg) { const char *lockpath; char ref[1000]; @@ -3317,6 +3319,13 @@ struct ref_be refs_files = { .reflog_exists = files_reflog_exists, .create_reflog = files_create_reflog, .delete_reflog = files_delete_reflog, + + .resolve_ref_unsafe = files_resolve_ref_unsafe, + .is_refname_available = files_is_refname_available, + .pack_refs = files_pack_refs, + .peel_ref = files_peel_ref, + .create_symref = files_create_symref, + .resolve_gitlink_ref= files_resolve_gitlink_ref, }; struct ref_be *refs = &refs_files; diff --git a/refs.h b/refs.h index f630e20..c56bfcd 100644 --- a/refs.h +++ b/refs.h @@ -384,6 +384,19 @@ typedef int (*reflog_exists_fn)(const char *refname); typedef int (*create_reflog_fn)(const char *refname); typedef int (*delete_reflog_fn)(c
[PATCH 05/22] refs-common.c: move rename_ref to the common code
This change moves rename_ref() to the refs-common.c file since this function does not contain any backend specific code. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 92 +++ refs.c| 92 --- 2 files changed, 92 insertions(+), 92 deletions(-) diff --git a/refs-common.c b/refs-common.c index 71ad358..f99d83e 100644 --- a/refs-common.c +++ b/refs-common.c @@ -43,3 +43,95 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt) transaction_free(transaction); return 0; } + +struct rename_reflog_cb { + struct ref_transaction *transaction; + const char *refname; + struct strbuf *err; +}; + +static int rename_reflog_ent(unsigned char *osha1, unsigned char *nsha1, +const char *id, unsigned long timestamp, int tz, +const char *message, void *cb_data) +{ + struct rename_reflog_cb *cb = cb_data; + struct reflog_committer_info ci; + + memset(&ci, 0, sizeof(ci)); + ci.id = id; + ci.timestamp = timestamp; + ci.tz = tz; + return transaction_update_reflog(cb->transaction, cb->refname, +nsha1, osha1, &ci, message, 0, +cb->err); +} + +int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg) +{ + unsigned char sha1[20]; + int flag = 0, log; + struct ref_transaction *transaction = NULL; + struct strbuf err = STRBUF_INIT; + const char *symref = NULL; + struct rename_reflog_cb cb; + struct reflog_committer_info ci; + + memset(&ci, 0, sizeof(ci)); + ci.committer_info = git_committer_info(0); + + symref = resolve_ref_unsafe(oldrefname, sha1, + RESOLVE_REF_READING, &flag); + if (flag & REF_ISSYMREF) { + error("refname %s is a symbolic ref, renaming it is not supported", + oldrefname); + return 1; + } + if (!symref) { + error("refname %s not found", oldrefname); + return 1; + } + + if (!is_refname_available(newrefname, &oldrefname, 1)) + return 1; + + log = reflog_exists(oldrefname); + transaction = transaction_begin(&err); + if (!transaction) + goto fail; + + if (strcmp(oldrefname, newrefname)) { + if (log && transaction_update_reflog(transaction, newrefname, +sha1, sha1, &ci, NULL, +REFLOG_TRUNCATE, &err)) + goto fail; + cb.transaction = transaction; + cb.refname = newrefname; + cb.err = &err; + if (log && for_each_reflog_ent(oldrefname, rename_reflog_ent, + &cb)) + goto fail; + + if (transaction_delete_sha1(transaction, oldrefname, sha1, + REF_NODEREF, + 1, NULL, &err)) + goto fail; + } + if (transaction_update_sha1(transaction, newrefname, sha1, + NULL, 0, 0, NULL, &err)) + goto fail; + if (log && transaction_update_reflog(transaction, newrefname, sha1, +sha1, &ci, logmsg, +REFLOG_COMMITTER_INFO_IS_VALID, +&err)) + goto fail; + if (transaction_commit(transaction, &err)) + goto fail; + transaction_free(transaction); + return 0; + + fail: + error("rename_ref failed: %s", err.buf); + strbuf_release(&err); + transaction_free(transaction); + return 1; +} diff --git a/refs.c b/refs.c index faf794c..7d579be 100644 --- a/refs.c +++ b/refs.c @@ -2622,98 +2622,6 @@ static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf *err) return 0; } -struct rename_reflog_cb { - struct ref_transaction *transaction; - const char *refname; - struct strbuf *err; -}; - -static int rename_reflog_ent(unsigned char *osha1, unsigned char *nsha1, -const char *id, unsigned long timestamp, int tz, -const char *message, void *cb_data) -{ - struct rename_reflog_cb *cb = cb_data; - struct reflog_committer_info ci; - - memset(&ci, 0, sizeof(ci)); - ci.id = id; - ci.timestamp = timestamp; - ci.tz = tz; - return transaction_update_reflog(cb->transaction, cb->refname, -nsha1, osha1, &ci, message, 0, -
[PATCH 04/22] refs-common.c: move delete_ref to the common code
This change moves delete_ref() to the refs-common.c file since this function does not contain any backend specific code. Signed-off-by: Ronnie Sahlberg --- refs-common.c | 18 ++ refs.c| 19 --- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/refs-common.c b/refs-common.c index cb884b2..71ad358 100644 --- a/refs-common.c +++ b/refs-common.c @@ -25,3 +25,21 @@ int update_ref(const char *action, const char *refname, return 0; } +int delete_ref(const char *refname, const unsigned char *sha1, int delopt) +{ + struct ref_transaction *transaction; + struct strbuf err = STRBUF_INIT; + + transaction = transaction_begin(&err); + if (!transaction || + transaction_delete_sha1(transaction, refname, sha1, delopt, + sha1 && !is_null_sha1(sha1), NULL, &err) || + transaction_commit(transaction, &err)) { + error("%s", err.buf); + transaction_free(transaction); + strbuf_release(&err); + return 1; + } + transaction_free(transaction); + return 0; +} diff --git a/refs.c b/refs.c index eb66cf7..faf794c 100644 --- a/refs.c +++ b/refs.c @@ -2622,25 +2622,6 @@ static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf *err) return 0; } -int delete_ref(const char *refname, const unsigned char *sha1, int delopt) -{ - struct ref_transaction *transaction; - struct strbuf err = STRBUF_INIT; - - transaction = transaction_begin(&err); - if (!transaction || - transaction_delete_sha1(transaction, refname, sha1, delopt, - sha1 && !is_null_sha1(sha1), NULL, &err) || - transaction_commit(transaction, &err)) { - error("%s", err.buf); - transaction_free(transaction); - strbuf_release(&err); - return 1; - } - transaction_free(transaction); - return 0; -} - struct rename_reflog_cb { struct ref_transaction *transaction; const char *refname; -- 2.0.1.553.geee1b3e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Transaction patch series overview
List, please see here an overview and ordering of the ref transaction patch series. These series build on each other and needs to be applied in the order listed below. This is an update. rs/ref-transaction-0 --- Early part of the "ref transaction" topic. * rs/ref-transaction-0: refs.c: change ref_transaction_update() to do error checking and return status refs.c: remove the onerr argument to ref_transaction_commit update-ref: use err argument to get error from ref_transaction_commit refs.c: make update_ref_write update a strbuf on failure refs.c: make ref_update_reject_duplicates take a strbuf argument for errors refs.c: log_ref_write should try to return meaningful errno refs.c: make resolve_ref_unsafe set errno to something meaningful on error refs.c: commit_packed_refs to return a meaningful errno on failure refs.c: make remove_empty_directories always set errno to something sane refs.c: verify_lock should set errno to something meaningful refs.c: make sure log_ref_setup returns a meaningful errno refs.c: add an err argument to repack_without_refs lockfile.c: make lock_file return a meaningful errno on failurei lockfile.c: add a new public function unable_to_lock_message refs.c: add a strbuf argument to ref_transaction_commit for error logging refs.c: allow passing NULL to ref_transaction_free refs.c: constify the sha arguments for ref_transaction_create|delete|update refs.c: ref_transaction_commit should not free the transaction refs.c: remove ref_transaction_rollback Has been merged into next. ref-transaction-1 (2014-07-16) 20 commits - Second batch of ref transactions - refs.c: make delete_ref use a transaction - refs.c: make prune_ref use a transaction to delete the ref - refs.c: remove lock_ref_sha1 - refs.c: remove the update_ref_write function - refs.c: remove the update_ref_lock function - refs.c: make lock_ref_sha1 static - walker.c: use ref transaction for ref updates - fast-import.c: use a ref transaction when dumping tags - receive-pack.c: use a reference transaction for updating the refs - refs.c: change update_ref to use a transaction - branch.c: use ref transaction for all ref updates - fast-import.c: change update_branch to use ref transactions - sequencer.c: use ref transactions for all ref updates - commit.c: use ref transactions for updates - replace.c: use the ref transaction functions for updates - tag.c: use ref transactions when doing updates - refs.c: add transaction.status and track OPEN/CLOSED/ERROR - refs.c: make ref_transaction_begin take an err argument - refs.c: update ref_transaction_delete to check for error and return status - refs.c: change ref_transaction_create to do error checking and return status (this branch is used by rs/ref-transaction, rs/ref-transaction-multi, rs/ref-transaction-reflog and rs/ref-transaction-rename.) The second batch of the transactional ref update series. Has been merged into pu rs/ref-transaction (2014-07-17) 12 commits - - refs.c: fix handling of badly named refs - refs.c: make write_ref_sha1 static - fetch.c: change s_update_ref to use a ref transaction - refs.c: propagate any errno==ENOTDIR from _commit back to the callers - refs.c: pass a skip list to name_conflict_fn - refs.c: call lock_ref_sha1_basic directly from commit - refs.c: move the check for valid refname to lock_ref_sha1_basic - refs.c: pass NULL as *flags to read_ref_full - refs.c: pass the ref log message to _create/delete/update instead of _commit - refs.c: add an err argument to delete_ref_loose - wrapper.c: add a new function unlink_or_msg - wrapper.c: simplify warn_if_unremovable (this branch is used by rs/ref-transaction-multi, rs/ref-transaction-reflog and rs/ref-transaction-rename; uses rs/ref-transaction-1.) The third and final part of the basic ref-transaction work. Has been merged into pu. rs/ref-transaction-reflog (2014-07-23) 15 commits --- - refs.c: allow deleting refs with a broken sha1 - refs.c: remove lock_any_ref_for_update - refs.c: make unlock_ref/close_ref/commit_ref static - refs.c: rename log_ref_setup to create_reflog - reflog.c: use a reflog transaction when writing during expire - refs.c: allow multiple reflog updates during a single transaction - refs.c: only write reflog update if msg is non-NULL - refs.c: add a flag to allow reflog updates to truncate the log - refs.c: add a transaction function to append a reflog entry - lockfile.c: make hold_lock_file_for_append preserve meaningful errno - refs.c: add a function to append a reflog entry to a fd - refs.c: add a new update_type field to ref_update - refs.c: rename the transaction functions - refs
Re: [PATCH 7/7] Documentation: git-init: flesh out example
On Wed, Aug 06, 2014 at 10:41:10AM -0700, Junio C Hamano wrote: > Linus Arver writes: > > > On Tue, Aug 05, 2014 at 03:14:48PM -0700, Junio C Hamano wrote: > >> Linus Arver writes: > >> > >> > Signed-off-by: Linus Arver > >> > --- > >> > Documentation/git-init.txt | 6 -- > >> > 1 file changed, 4 insertions(+), 2 deletions(-) > >> > > >> > diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt > >> > index b94d165..16e9f9c 100644 > >> > --- a/Documentation/git-init.txt > >> > +++ b/Documentation/git-init.txt > >> > @@ -138,10 +138,12 @@ Start a new Git repository for an existing code > >> > base:: > >> > $ cd /path/to/my/codebase > >> > $ git init <1> > >> > $ git add . <2> > >> > +$ git commit<3> > >> > >> I agree it is a good discipline to make the initial "pristine" > >> import immediately after "git add ." without doing anything else. > >> Perhaps the description below wants to make it more explicit? > >> > > > > I could add a comment like the following: > > > > For new repositories, creating a commit immediately after "git add > > ." is good practice as it will cleanly separate any preexisting work > > (done under some other VCS, for example) from any new work done with > > git. > > > > Does this make sense? I am not sure how explicit you want it to be, or > > whether I captured what you wanted to be explained. > > I was thinking more along the lines of > > <3> Record the pristine state as the first commit in the history. > > which should suffice without becoming excessively verbose. Ah yes, I like the brevity. > > Actually, I would like to know if anything is special about the > > "root-commit"... > > As far as Git is concerned, they are just ordinary commits without > any parents. A commit in Git can have zero or more parents, so from > that "structural" point of view, they are not that special. > > They are considered special by users because they represent the > beginning of the project history. Thank you for the insight. I won't bother adding a blurb about "root-commit" and what it means because they are not that special, as you said so yourself. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 01/22] refs.c: create a public function for is_refname_available
On Fri, 2014-08-08 at 09:44 -0700, Ronnie Sahlberg wrote: > + * Check is a particular refname is available for creation. skip > contains s/Check is/Check that/' > + * a list of refnames to exclude from the refname collission tests. "collision" > + */ > +int is_refname_available(const char *refname, const char **skip, int > skipnum); > + > +/* -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/7] Documentation: git-init: list items facelift
No textual change. Signed-off-by: Linus Arver --- Documentation/git-init.txt | 49 ++ 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index f1f920e..c02ccd0 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -72,30 +72,37 @@ repository. When specified, the config variable "core.sharedRepository" is set so that files and directories under `$GIT_DIR` are created with the requested permissions. When not specified, Git will use permissions reported by umask(2). - ++ The option can have the following values, defaulting to 'group' if no value is given: ++ +-- +'umask' (or 'false'):: + +Use permissions reported by umask(2). The default, when `--shared` is not +specified. + +'group' (or 'true'):: - - 'umask' (or 'false'): Use permissions reported by umask(2). The default, - when `--shared` is not specified. - - - 'group' (or 'true'): Make the repository group-writable, (and g+sx, since - the git group may be not the primary group of all users). - This is used to loosen the permissions of an otherwise safe umask(2) value. - Note that the umask still applies to the other permission bits (e.g. if - umask is '0022', using 'group' will not remove read privileges from other - (non-group) users). See '0xxx' for how to exactly specify the repository - permissions. - - - 'all' (or 'world' or 'everybody'): Same as 'group', but make the repository - readable by all users. - - - '0xxx': '0xxx' is an octal number and each file will have mode '0xxx'. - '0xxx' will override users' umask(2) value (and not only loosen permissions - as 'group' and 'all' does). '0640' will create a repository which is - group-readable, but not group-writable or accessible to others. '0660' will - create a repo that is readable and writable to the current user and group, - but inaccessible to others. +Make the repository group-writable, (and g+sx, since the git group may be not +the primary group of all users). This is used to loosen the permissions of an +otherwise safe umask(2) value. Note that the umask still applies to the other +permission bits (e.g. if umask is '0022', using 'group' will not remove read +privileges from other (non-group) users). See '0xxx' for how to exactly specify +the repository permissions. + +'all' (or 'world' or 'everybody'):: + +Same as 'group', but make the repository readable by all users. + +'0xxx':: + +'0xxx' is an octal number and each file will have mode '0xxx'. '0xxx' will +override users' umask(2) value (and not only loosen permissions as 'group' and +'all' does). '0640' will create a repository which is group-readable, but not +group-writable or accessible to others. '0660' will create a repo that is +readable and writable to the current user and group, but inaccessible to others. +-- By default, the configuration flag `receive.denyNonFastForwards` is enabled in shared repositories, so that you cannot force a non fast-forwarding push -- 2.0.4 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/7] Documentation: git-init: typographical fixes
Use backticks when we quote something that the user should literally use. Signed-off-by: Linus Arver --- Documentation/git-init.txt | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index afd721e..f1f920e 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -43,7 +43,7 @@ OPTIONS -q:: --quiet:: -Only print error and warning messages, all other output will be suppressed. +Only print error and warning messages; all other output will be suppressed. --bare:: @@ -97,7 +97,7 @@ is given: create a repo that is readable and writable to the current user and group, but inaccessible to others. -By default, the configuration flag receive.denyNonFastForwards is enabled +By default, the configuration flag `receive.denyNonFastForwards` is enabled in shared repositories, so that you cannot force a non fast-forwarding push into it. @@ -106,14 +106,13 @@ line, the command is run inside the directory (possibly after creating it). -- - TEMPLATE DIRECTORY -- The template directory contains files and directories that will be copied to the `$GIT_DIR` after it is created. -The template directory used will (in order): +The template directory used will be (in order): - The argument given with the `--template` option. @@ -138,8 +137,8 @@ $ git init <1> $ git add . <2> + -<1> prepare /path/to/my/codebase/.git directory -<2> add all existing file to the index +<1> Create a /path/to/my/codebase/.git directory. +<2> Add all existing files to the index. GIT --- -- 2.0.4 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] lots of documentation fixes/rewordings in git-init(1)
Hello, Aside from the changes stemming from the discussion, I have also separated out some typographical changes from patches 3 and 7, and squashed them into patch 1. So, those commits are cleaner now. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 5/7] Documentation: git-init: reword parenthetical statements
Signed-off-by: Linus Arver --- Documentation/git-init.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index 3f4e46a..21e5ad9 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -108,8 +108,8 @@ By default, the configuration flag `receive.denyNonFastForwards` is enabled in shared repositories, so that you cannot force a non fast-forwarding push into it. -If you name a (possibly non-existent) directory at the end of the command -line, the command is run inside the directory (possibly after creating it). +If you provide a 'directory', the command is run inside it. If this directory +does not exist, it will be created. -- -- 2.0.4 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/7] Documentation: git-init: template directory: reword
Signed-off-by: Linus Arver --- Documentation/git-init.txt | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index c02ccd0..6ffe721 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -119,15 +119,15 @@ TEMPLATE DIRECTORY The template directory contains files and directories that will be copied to the `$GIT_DIR` after it is created. -The template directory used will be (in order): +The template directory will be one of the following (in order): - - The argument given with the `--template` option. + - the argument given with the `--template` option; - - The contents of the `$GIT_TEMPLATE_DIR` environment variable. + - the contents of the `$GIT_TEMPLATE_DIR` environment variable; - - The `init.templatedir` configuration variable. + - the `init.templatedir` configuration variable; or - - The default template directory: `/usr/share/git-core/templates`. + - the default template directory: `/usr/share/git-core/templates`. The default template directory includes some directory structure, some suggested "exclude patterns", and copies of sample "hook" files. -- 2.0.4 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 4/7] Documentation: git-init: --separate-git-dir: clarify
Use shorter sentences to describe what actually happens. We describe what the term "Git symbolic link" actually means. Also, we separate out the description of the behavioral change upon reinitialization into its own paragraph. Signed-off-by: Linus Arver --- Documentation/git-init.txt | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index 6ffe721..3f4e46a 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -57,12 +57,12 @@ DIRECTORY" section below.) --separate-git-dir=:: -Instead of initializing the repository where it is supposed to be, -place a filesytem-agnostic Git symbolic link there, pointing to the -specified path, and initialize a Git repository at the path. The -result is Git repository can be separated from working tree. If this -is reinitialization, the repository will be moved to the specified -path. +Instead of initializing the repository as a directory to either `$GIT_DIR` or +`./.git/`, create a text file there containing the path to the actual +repository. This file acts as filesystem-agnostic Git symbolic link to the +repository. ++ +If this is reinitialization, the repository will be moved to the specified path. --shared[=(false|true|umask|group|all|world|everybody|0xxx)]:: -- 2.0.4 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 6/7] Documentation: git-init: template directory: reword and cross-reference
Signed-off-by: Linus Arver --- Documentation/git-init.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index 21e5ad9..9f2c7d8 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -129,9 +129,8 @@ The template directory will be one of the following (in order): - the default template directory: `/usr/share/git-core/templates`. -The default template directory includes some directory structure, some -suggested "exclude patterns", and copies of sample "hook" files. -The suggested patterns and hook files are all modifiable and extensible. +The default template directory includes some directory structure, suggested +"exclude patterns" (see linkgit:gitignore[5]), and sample hook files (see linkgit:githooks[5]). EXAMPLES -- 2.0.4 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 7/7] Documentation: git-init: flesh out example
Add a third step `git commit` after adding files for the first time. Signed-off-by: Linus Arver --- Documentation/git-init.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index 9f2c7d8..369f889 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -141,10 +141,12 @@ Start a new Git repository for an existing code base:: $ cd /path/to/my/codebase $ git init <1> $ git add . <2> +$ git commit<3> + <1> Create a /path/to/my/codebase/.git directory. <2> Add all existing files to the index. +<3> Record the pristine state as the first commit in the history. GIT --- -- 2.0.4 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Rebase safely (Re: cherry picking and merge)
On Aug 6, 2014, at 10:11 PM, Nico Williams wrote: > Nah. Sun managed this for decades without a hitch, and for products > much larger than GCC. See above. Ok. Ah, ok, perfect. I see how that method of working would cure the cherry-pick and merge don’t work problem mentioned at the top of the thread. > Do some experiments based on the above hardcopy. If that doesn't > convince you that it works, oh well, I'll have given it a good try. Thank you for taking the time to diagram that as it appears to violate everyones how to use git guide. I see the workflow does an onto, which was the ‘fix’ people talked about on stack overflow, and I see just how things would work. If the old master branches are deleted and gc is run, then all the old references go away, and then the refs from email and bugzilla then don’t work. Did you guys ever remove them and then prune (or gc)? Now, the biggest issue, if that is recognized as `fixing’ the cherry-pick problem, then certainly the problem is understood to be a problem. If one recognized it as a problem, then one can envision cherry-pick and merge working together so that the problem doesn’t need fixing in the first place. And, if it doesn’t need fixing, then the cost of the solution isn’t needed either. The biggest problem with git, is that two features don’t work nicely together when they could; in this case, cherry-pick and merge). Because they don’t, it makes it hard for people to predict what will happen when they use it. This makes it more expensive to use and less suitable than a system that is more predictable. You improve git, by fixing the problem and making the features work nicely together and making it predicable. I still favor fixing the underlying problem with cherry-pick and merge not working. :-) That said, I see how to work around the bug with rebase, if I need to. I wish the top google hit were your guide and I wish I never saw all the other pages… I see now your position, and I see why all the guides are wrong, if you know just how to use rebase. I wish the git documentation were improved to say as the first sentence under cherry-pick, this feature sucks and doesn’t really work well, it can cause excess merge conflicts. rebase can be used to work around the bugs in cherry-pick for now. And under rebase, instead of saying what it said now, that how one can can trivially and effortlessly use git, instead of saying, Do not rebase commits that you have pushed to a public repository which I now see is wrong.-- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/8] mv: no "Huh?" to the user
Nguyễn Thái Ngọc Duy writes: > Although if we are frisky, this could do > >static NORETURN void die_builtin(const char *err, va_list params) >{ > - vreportf("fatal: ", err, params); > + vreportf("Huh? ", err, params); > exit(128); >} ;-) While at it we may want to remove the extra SP between dies and their opening parentheses. > Signed-off-by: Nguyễn Thái Ngọc Duy > --- > builtin/mv.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > > diff --git a/builtin/mv.c b/builtin/mv.c > index b892f63..a7e02c0 100644 > --- a/builtin/mv.c > +++ b/builtin/mv.c > @@ -135,7 +135,7 @@ int cmd_mv(int argc, const char **argv, const char > *prefix) > if (first >= 0) { > struct strbuf submodule_dotgit = STRBUF_INIT; > if (!S_ISGITLINK(active_cache[first]->ce_mode)) > - die (_("Huh? Directory %s is in index > and no submodule?"), src); > + die (_("Directory %s is in index and no > submodule?"), src); > if (!is_staging_gitmodules_ok()) > die (_("Please, stage your changes to > .gitmodules or stash them to proceed")); > strbuf_addf(&submodule_dotgit, "%s/.git", src); > @@ -153,8 +153,7 @@ int cmd_mv(int argc, const char **argv, const char > *prefix) > > first = cache_name_pos(src_w_slash, > len_w_slash); > if (first >= 0) > - die (_("Huh? %.*s is in index?"), > - len_w_slash, > src_w_slash); > + die (_("%.*s is in index"), > len_w_slash, src_w_slash); > > first = -1 - first; > for (last = first; last < active_nr; last++) { -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/8] mv: flatten error handling code block
Nguyễn Thái Ngọc Duy writes: > Signed-off-by: Nguyễn Thái Ngọc Duy > --- > builtin/mv.c | 35 +-- > 1 file changed, 17 insertions(+), 18 deletions(-) > > diff --git a/builtin/mv.c b/builtin/mv.c > index a7e02c0..5c6f58f 100644 > --- a/builtin/mv.c > +++ b/builtin/mv.c > @@ -58,6 +58,11 @@ static const char *add_slash(const char *path) > return path; > } > > +static void move_up_one(void *p, int nmemb, int size) > +{ > + memmove(p, (char*)p + size, nmemb * size); > +} > + > static struct lock_file lock_file; > #define SUBMODULE_WITH_GITDIR ((const char *)1) > > @@ -224,24 +229,18 @@ int cmd_mv(int argc, const char **argv, const char > *prefix) > else > string_list_insert(&src_for_dst, dst); > > - if (bad) { > - if (ignore_errors) { > - if (--argc > 0) { > - memmove(source + i, source + i + 1, > - (argc - i) * sizeof(char *)); > - memmove(destination + i, > - destination + i + 1, > - (argc - i) * sizeof(char *)); > - memmove(modes + i, modes + i + 1, > - (argc - i) * sizeof(enum > update_mode)); > - memmove(submodule_gitfile + i, > - submodule_gitfile + i + 1, > - (argc - i) * sizeof(char *)); > - i--; > - } > - } else > - die (_("%s, source=%s, destination=%s"), > - bad, src, dst); > + if (!bad) > + continue; > + if (!ignore_errors) > + die (_("%s, source=%s, destination=%s"), > + bad, src, dst); > + if (--argc > 0) { > + int n = argc - i; > + move_up_one(source + i, n, sizeof(*source)); > + move_up_one(destination + i, n, sizeof(*destination)); > + move_up_one(modes + i, n, sizeof(*modes)); > + move_up_one(submodule_gitfile + i, n, > sizeof(*submodule_gitfile)); > + i--; The resulting end-of-loop code structure certainly looks a lot better, even if the original memmove()s were left inline without the helper. The helper itself however looks a bit half-hearted. It may be more appropriate to go one step further to have a macro whose use looks like this, perhaps, to avoid the last remaining repetition? MOVE_UP_BY_ONE(source, i, n); > } > } -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 17/22] refs.c: add a backend method structure with transaction functions
On Fri, 2014-08-08 at 09:45 -0700, Ronnie Sahlberg wrote: > +struct ref_be refs_files = { > + .transaction_begin = files_transaction_begin, > + .transaction_update_sha1= files_transaction_update_sha1, > + .transaction_create_sha1= files_transaction_create_sha1, > + .transaction_delete_sha1= files_transaction_delete_sha1, > + .transaction_update_reflog = files_transaction_update_reflog, > + .transaction_commit = files_transaction_commit, > + .transaction_free = files_transaction_free, > +}; C99 designated initializers are unfortunately forbidden by CodingGuidelines. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Rebase safely (Re: cherry picking and merge)
On Fri, Aug 08, 2014 at 10:34:43AM -0700, Mike Stump wrote: > On Aug 6, 2014, at 10:11 PM, Nico Williams wrote: > > Nah. Sun managed this for decades without a hitch, and for products > > much larger than GCC. See above. > > Ok. Ah, ok, perfect. I see how that method of working would cure the > cherry-pick and merge don’t work problem mentioned at the top of the > thread. > > > Do some experiments based on the above hardcopy. If that doesn't > > convince you that it works, oh well, I'll have given it a good try. > > Thank you for taking the time to diagram that as it appears to violate > everyones how to use git guide. I see the workflow does an onto, > which was the ‘fix’ people talked about on stack overflow, and I see > just how things would work. There's nothing scary about --onto. You're saying "figure out which are my local commits (the ones on top of the previous upstream) and pick them onto the new upstream". We only need to do it manually (though it can be scripted[*]) because git doesn't track rebase history so that it can be done automatically. [*] And then there's Tony Finch's https://git.csx.cam.ac.uk/x/ucs/git/git-repub.git , which is kinda awesome! > If the old master branches are deleted and gc is run, then all the old > references go away, and then the refs from email and bugzilla then > don’t work. Did you guys ever remove them and then prune (or gc)? Product gates' repos and snapshots stuck around forever, though it was Teamware, and finding really old ones wasn't necessarily easy, particularly since their names didn't always reflect product names. Prominent project gate repos and their snapshots also stuck around forever. Lesser project gate repos tended to be as ephemeral as the project. > Now, the biggest issue, if that is recognized as `fixing’ the > cherry-pick problem, then certainly the problem is understood to be a > problem. If one recognized it as a problem, then one can envision Not really. This isn't about git. We followed a rebase-only workflow with VCSes that nominally didn't support rebase. We did it because it was easier on everyone and kept history in the upstream clean. We didn't do it because git has issues when combining merge and cherry-pick. > cherry-pick and merge working together so that the problem doesn’t > need fixing in the first place. And, if it doesn’t need fixing, then If you buy into the Sun model then this is all a non-issue. If you don't then I think you have other problems (because I have bought into the Sun model) :) > the cost of the solution isn’t needed either. The biggest problem > with git, is that two features don’t work nicely together when they > [...] The Sun model has no additional cost. It moves costs around so that the people dealing with conflicts are the downstreams, not the upstreams, and that's exactly as it should be. (Keep in mind that Solaris gates tended to have large numbers of commits on any given day, so it was quite common that one would have to rebase multiple times before successfully pushing. For large projects with long test cycles the gates would close to avoid the need to rebase and re-test.) > I still favor fixing the underlying problem with cherry-pick and merge > not working. :-) That said, I see how to work around the bug with > rebase, if I need to. IMO it could be done, but I can't help that. > I wish the top google hit were your guide and I wish I never saw all > the other pages… I see now your position, and I see why all the Me too! I should blog it. > guides are wrong, if you know just how to use rebase. I wish the git > documentation were improved to say as the first sentence under The Sun model is not the only way to use git though. > cherry-pick, this feature sucks and doesn’t really work well, it can > cause excess merge conflicts. rebase can be used to work around the > bugs in cherry-pick for now. And under rebase, instead of saying what > it said now, that how one can can trivially and effortlessly use git, > instead of saying, Do not rebase commits that you have pushed to a > public repository which I now see is wrong. I'm glad you understand the Sun model now. You should evaluate its applicability to your use case on its own merits. Don't use it just to workaround a problem in git; use it because it's good, or don't use it because it doesn't fit your team's needs. Nico -- -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 04/23] rebase -i: hide interactive command messages in verbose mode
Fabian Ruch writes: > @@ -923,6 +923,8 @@ EOF > ;; > esac > > +mkdir -p "$state_dir" || die "Could not create temporary $state_dir" > + > git var GIT_COMMITTER_IDENT >/dev/null || > die "You need to set your committer info first" > > @@ -938,7 +940,6 @@ then > fi > > orig_head=$(git rev-parse --verify HEAD) || die "No HEAD?" > -mkdir -p "$state_dir" || die "Could not create temporary $state_dir" > > : > "$state_dir"/interactive || die "Could not mark as interactive" > write_basic_state Why this change? I can't figure out how it relates to the output change. > @@ -873,9 +873,8 @@ test_expect_success 'running "git rebase -i --exec git > show HEAD"' ' > ( > FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" && > export FAKE_LINES && > - git rebase -i HEAD~2 >expect > + git rebase -i HEAD~2 >expected > ) && > - sed -e "1,9d" expect >expected && > test_cmp expected actual > ' Getting rid of these magic removals is a very nice change, thank you. -- Thomas Rast t...@thomasrast.ch -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 08/23] rebase -i: reword executes pre-commit hook on interim commit
Fabian Ruch writes: > Subject: Re: [PATCH v2 08/23] rebase -i: reword executes pre-commit hook on > interim commit I think the change makes sense, but can you reword the subjects that it describes the state after the commit (i.e. what you are doing), instead of before the commit? -- Thomas Rast t...@thomasrast.ch -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 23/23] rebase -i: enable options --signoff, --reset-author for pick, reword
Fabian Ruch writes: > @@ -634,21 +644,24 @@ do_replay () { > comment_for_reflog pick > > mark_action_done > - do_pick $sha1 || die_with_patch $sha1 "Could not apply $sha1... > $rest" > + eval do_pick $opts $sha1 \ > + || die_with_patch $sha1 "Could not apply $sha1... $rest" You had me a little puzzled at the switch to 'eval' here. That is necessary to match the quoting added in 20/23, not for any change in this commit. This commit is simply the first one to trigger this. Also, are you sure $sha1 does not require quoting through an eval? Please add tests to this patch. -- Thomas Rast t...@thomasrast.ch -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 20/23] rebase -i: parse to-do list command line options
Fabian Ruch writes: [...] > are not supported at the moment. Neither are options that contain > spaces because the shell expansion of `args` in `do_next` interprets > white space characters as argument separator, that is a command line > like > > pick --author "A U Thor" fa1afe1 Some change > > is parsed as the pick command > > pick --author > > and the commit hash > > "A > > which obviously results in an unknown revision error. For the sake of > completeness, in the example above the message title variable `rest` > is assigned the string 'U Thor" fa1afe1 Some change' (without the > single quotes). You could probably trim down the non-example a bit and instead give an example :-) > Print an error message for unknown or unsupported command line > options, which means an error for all specified options at the > moment. Can you add a test that verifies we catch an obvious unknown option (such as --unknown-option)? > Cleanly break the `do_next` loop by assigning the special > value 'unknown' to the local variable `command`, which triggers the > unknown command case in `do_cmd`. [...] > do_replay () { > command=$1 > - sha1=$2 > - rest=$3 > + shift > + > + opts= > + while test $# -gt 0 > + do > + case "$1" in > + -*) > + warn "Unknown option: $1" > + command=unknown > + ;; > + *) > + break > + ;; This seems a rather hacky solution to me. Doesn't this now print warning: Unknown option: --unknown-option warning: Unknown command: pick --unknown-option ? It shouldn't claim the command is unknown if the command itself was valid. Also, you speak of do_cmd above, but the unknown command handling seems to be part of do_replay? -- Thomas Rast t...@thomasrast.ch -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Update hard-coded header dependencies
The fall-back rules used when compilers don't support the -MMD switch to generate makefile rules based on #includes have been out of date since v1.7.12.1~22^2~8 (move git_version_string into version.c, 2012-06-02). Checked with 'make CHECK_HEADER_DEPENDENCIES=yes'. Signed-off-by: Jonathan Nieder --- Maybe it's worth switching to plain LIB_H += $(wildcard *.h) ? People using ancient compilers that never change headers wouldn't be hurt, people using modern compilers that do change headers also wouldn't be hurt, and we could stop pretending to maintain an up-to-date list. Makefile | 8 1 file changed, 8 insertions(+) diff --git a/Makefile b/Makefile index 2320de5..18f0fad 100644 --- a/Makefile +++ b/Makefile @@ -646,15 +646,19 @@ LIB_H += cache.h LIB_H += color.h LIB_H += column.h LIB_H += commit.h +LIB_H += commit-slab.h +LIB_H += compat/apple-common-crypto.h LIB_H += compat/bswap.h LIB_H += compat/mingw.h LIB_H += compat/obstack.h LIB_H += compat/poll/poll.h LIB_H += compat/precompose_utf8.h LIB_H += compat/terminal.h +LIB_H += compat/win32/alloca.h LIB_H += compat/win32/dirent.h LIB_H += compat/win32/pthread.h LIB_H += compat/win32/syslog.h +LIB_H += connect.h LIB_H += connected.h LIB_H += convert.h LIB_H += credential.h @@ -678,6 +682,7 @@ LIB_H += grep.h LIB_H += hashmap.h LIB_H += help.h LIB_H += http.h +LIB_H += khash.h LIB_H += kwset.h LIB_H += levenshtein.h LIB_H += line-log.h @@ -721,6 +726,7 @@ LIB_H += sha1-lookup.h LIB_H += shortlog.h LIB_H += sideband.h LIB_H += sigchain.h +LIB_H += split-index.h LIB_H += strbuf.h LIB_H += streaming.h LIB_H += string-list.h @@ -728,6 +734,7 @@ LIB_H += submodule.h LIB_H += tag.h LIB_H += tar.h LIB_H += thread-utils.h +LIB_H += trace.h LIB_H += transport.h LIB_H += tree-walk.h LIB_H += tree.h @@ -744,6 +751,7 @@ LIB_H += vcs-svn/repo_tree.h LIB_H += vcs-svn/sliding_window.h LIB_H += vcs-svn/svndiff.h LIB_H += vcs-svn/svndump.h +LIB_H += version.h LIB_H += walker.h LIB_H += wildmatch.h LIB_H += wt-status.h -- -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[ANNOUNCE] Git v2.1.0-rc2
A release candidate Git v2.1.0-rc2 is now available for testing at the usual places. The tarballs are found at: https://www.kernel.org/pub/software/scm/git/testing/ The following public repositories all have a copy of the 'v2.1.0-rc2' tag and the 'master' branch that the tag points at: url = https://kernel.googlesource.com/pub/scm/git/git url = git://repo.or.cz/alt-git.git url = https://code.google.com/p/git-core/ url = git://git.sourceforge.jp/gitroot/git-core/git.git url = git://git-core.git.sourceforge.net/gitroot/git-core/git-core url = https://github.com/gitster/git Git v2.1 Release Notes (draft) == Backward compatibility notes * The default value we give to the environment variable LESS has been changed from "FRSX" to "FRX", losing "S" (chop long lines instead of wrapping). Existing users who prefer not to see line-wrapped output may want to set $ git config core.pager "less -S" to restore the traditional behaviour. It is expected that people find output from most subcommands easier to read with the new default, except for "blame" which tends to produce really long lines. To override the new default only for "git blame", you can do this: $ git config pager.blame "less -S" * A few disused directories in contrib/ have been retired. Updates since v2.0 -- UI, Workflows & Features * Since the very beginning of Git, we gave the LESS environment a default value "FRSX" when we spawn "less" as the pager. "S" (chop long lines instead of wrapping) has been removed from this default set of options, because it is more or less a personal taste thing, as opposed to the others that have good justifications (i.e. "R" is very much justified because many kinds of output we produce are colored and "FX" is justified because output we produce is often shorter than a page). * The logic and data used to compute the display width needed for UTF-8 strings have been updated to match Unicode 7.0 better. * HTTP-based transports learned to better propagate the error messages from the webserver to the client coming over the HTTP transport. * The completion script for bash (in contrib/) has been updated to better handle aliases that define a complex sequence of commands. * The "core.preloadindex" configuration variable is enabled by default, allowing modern platforms to take advantage of their multiple cores. * "git clone" applies the "if cloning from a local disk, physically copy the repository using hardlinks, unless otherwise told not to with --no-local" optimization when the url.*.insteadOf mechanism rewrites a remote-repository "git clone $URL" into a clone from a local disk. * "git commit --date=" option learned more timestamp formats, including "--date=now". * The `core.commentChar` configuration variable is used to specify a custom comment character (other than the default "#") for the commit message editor. This can be set to `auto` to attempt to choose a different character that does not conflict with any that already starts a line in the message being edited, for cases like "git commit --amend". * "git format-patch" learned --signature-file= to add the contents of a file as a signature to the mail message it produces. * "git grep" learned the grep.fullname configuration variable to force "--full-name" to be the default. This may cause regressions for scripted users who do not expect this new behaviour. * "git imap-send" learned to ask the credential helper for auth material. * "git log" and friends now understand the value "auto" for the "log.decorate" configuration variable to enable the "--decorate" option automatically when the output is sent to tty. * "git merge" without an argument, even when there is an upstream defined for the current branch, refused to run until merge.defaultToUpstream is set to true. Flip the default of that configuration variable to true. * "git mergetool" learned to drive the vimdiff3 backend. * mergetool.prompt used to default to 'true', always asking "do you really want to run the tool on this path?". The default has been changed to 'false'. However, the prompt will still appear if mergetool used its autodetection system to guess which tool to use. Users who explicitly specify or configure a tool will no longer see the prompt by default. Strictly speaking, this is a backward incompatible change and users need to explicitly set the variable to 'true' if they want to be prompted to confirm running the tool on each path. * "git replace" learned the "--edit" subcommand to create a replacement by editing an existing object. * "git replace" learned a "--graft" option to rewrite the parents of a commit. * "git send-email" learned "--to-cover" and "--cc-cover" options, to tell it to copy To: an
What's cooking in git.git (Aug 2014, #02; Fri, 8)
Here are the topics that have been cooking. Commits prefixed with '-' are only in 'pu' (proposed updates) while commits prefixed with '+' are in 'next'. The second release candidate snapshot is out. Hopefully after a week of a calm pre-release "bugfix-only" period, we can do the 2.1 final late next week. You can find the changes described here in the integration branches of the repositories listed at http://git-blame.blogspot.com/p/git-public-repositories.html -- [Graduated to "master"] * ta/doc-config (2014-07-30) 1 commit (merged to 'next' on 2014-07-31 at ec577fa) + add documentation for writing config files * tf/maint-doc-push (2014-07-31) 1 commit (merged to 'next' on 2014-07-31 at 6a8ef70) + git-push: fix link in man page -- [New Topics] * tf/imap-send-create (2014-08-01) 3 commits - SQUASH??? varargs form of issue-imap-cmd is no longer used - imap-send: create target mailbox if it is missing - imap-send: clarify CRAM-MD5 vs LOGIN documentation Will merge to 'next' after dealing with the SQUASH??? fix-up. * bc/archive-pax-header-mode (2014-08-04) 1 commit - archive: honor tar.umask even for pax headers Implementations of "tar" that do not understand an extended pax header would extract the contents of it in a regular file; make sure the permission bits of this file follows the same tar.umask configuration setting. Will merge to 'next'. * bc/imap-send-doc (2014-08-05) 1 commit - imap-send doc: omit confusing "to use imap-send" modifier Will merge to 'next'. * jc/apply-ws-prefix (2014-08-07) 3 commits - apply: omit ws check for excluded paths - apply: hoist use_patch() helper for path exclusion up - apply: use the right attribute for paths in non-Git patches Applying a patch not generated by Git in a subdirectory used to check the whitespace breakage using the attributes for incorrect paths. Also whitespace checks were performed even for paths excluded via "git apply --exclude=" mechanism. Will merge to 'next'. * jk/command-line-config-empty-string (2014-08-05) 1 commit - config: teach "git -c" to recognize an empty string "git -c section.var command" and "git -c section.var= command" should pass the configuration differently (the former should be a boolean true, the latter should be an empty string). Will merge to 'next'. * jk/pack-bitmap (2014-08-04) 1 commit - pack-bitmap: do not use gcc packed attribute Will merge to 'next'. * jk/pretty-empty-format (2014-07-30) 3 commits - pretty: make empty userformats truly empty - pretty: treat "--format=" as an empty userformat - revision: drop useless string offset when parsing "--pretty" "git log --pretty/format=" with an empty format string did not mean the more obvious "No output whatsoever" but "Use default format", which was counterintuitive. Will merge to 'next'. * la/init-doc (2014-08-08) 7 commits - Documentation: git-init: flesh out example - Documentation: git-init: template directory: reword and cross-reference - Documentation: git-init: reword parenthetical statements - Documentation: git-init: --separate-git-dir: clarify - Documentation: git-init: template directory: reword - Documentation: git-init: list items facelift - Documentation: git-init: typographical fixes Will merge to 'next'. * lf/bundle-exclusion (2014-08-07) 1 commit - bundle: fix exclusion of annotated tags Will merge to 'next'. * mm/log-branch-desc-plug-leak (2014-08-07) 1 commit - builtin/log.c: fix minor memory leak Will merge to 'next'. * ta/config-set-1 (2014-08-07) 8 commits - add tests for `git_config_get_string_const()` - add a test for semantic errors in config files - rewrite git_config() to use the config-set API - config: add `git_die_config()` to the config-set API - change `git_config()` return value to void - add line number and file name info to `config_set` - config.c: fix accuracy of line number in errors - config.c: mark error and warnings strings for translation (this branch is used by ta/config-set-2; uses ta/config-set.) * ta/config-set-2 (2014-08-07) 11 commits - branch.c: replace `git_config()` with `git_config_get_string() - alias.c: replace `git_config()` with `git_config_get_string()` - imap-send.c: replace `git_config()` with `git_config_get_*()` family - pager.c: replace `git_config()` with `git_config_get_value()` - builtin/gc.c: replace `git_config()` with `git_config_get_*()` family - rerere.c: replace `git_config()` with `git_config_get_*()` family - fetchpack.c: replace `git_config()` with `git_config_get_*()` family - archive.c: replace `git_config()` with `git_config_get_bool()` family - read-cache.c: replace `git_config()` with `git_config_get_*()` family - http-backend.c: replace `git_config()` with `git_config_get_bool()` family - daemon.c: replace `git_config()` with `git_config_get_bool()` family (this branch uses ta/config-s
Re: What's cooking in git.git (Aug 2014, #02; Fri, 8)
On Sat, Aug 9, 2014 at 5:18 AM, Junio C Hamano wrote: > * nd/lock-paths-absolute (2014-08-01) 3 commits > - lockfile.c: store absolute path > - lockfile.c: remove PATH_MAX limit in resolve_symlink() > - lockfile.c: remove PATH_MAX limitation (except in resolve_symlink) > (this branch uses rs/strbuf-getcwd.) > > Will merge to 'next'. You may want to hold this back for a while until Michael has a chance to look and decides what to do with it and his mh/lockfile series. -- Duy -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Kedves Email felhasználói;
-- Kedves Email felhasználói; Túllépte a határt 23.432 tárolás az e-postafiók beállítva a WEB SERVICE / Adminisztrátor, és akkor sikerül a küldő és a bejövő üzenetek, amíg újra érvényesíti az e-mail címét. A szükséges eljárások nyújtottak be, az alábbi a véleménye, ellenőrizze kattintva az alábbi linkre és töltse ki az adatokat, hogy érvényesítse az e-mail címét. Kérjük, kattintson ide http://mailupdat.jigsy.com Hogy növelje az e-mail kvótát az e-mail. Figyelmeztetés !!! Ennek elmulasztása azt eredményezi, hogy korlátozott hozzáférést a postafiók. elmulasztotta frissíteni fiókjába számított három napon belül a frissítés értesítést, akkor figyelembe kell végleg. Tisztelettel, rendszer Administrator® -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [BUG] parse_object() does not behave as documented
Ping? Samuel Bronson writes: > [Hmm, nobody seems ot have commented on this analysis; maybe reposting > it with a subject containing [BUG] will help?] > > Samuel Bronson writes: > >> The following message is a courtesy copy of an article >> that has been posted to gmane.comp.version-control.git as well. >> >> Oh, I forgot to provide any analysis of the problem. Oops. >> >> It may be just as well, though; I was tired enough that I might have >> botched it in any case. So, have an analysis: >> >> While inflate errors are obviously NOT GOOD, and should perhaps be >> instantly fatal for most commands, git fsck is something of a special >> case because it is useful to have *it* report as many corrupt objects as >> possible in one run. >> >> Unfortunately, this is not currently the case, as shown by the provided >> testcase. >> >> The output for this testcase is: >> >> , >> | checking known breakage: >> | hash1= && >> | hash2=fffe && >> | mkdir -p .git/objects/ff && >> | echo not-zlib >$(sha1_file $hash1) && >> | test_when_finished "remove_object $hash1" && >> | echo not-zlib >$(sha1_file $hash2) && >> | test_when_finished "remove_object $hash2" && >> | >> | # Return value is not documented >> | test_might_fail git fsck 2>out && >> | cat out && echo == && >> | grep "$hash1.*corrupt" out && >> | grep "$hash2.*corrupt" out >> | >> | error: inflate: data stream error (incorrect header check) >> | error: unable to unpack header >> | error: inflate: data stream error (incorrect header check) >> | fatal: loose object (stored >> | in .git/objects/ff/ff) is >> | corrupt >> | == >> | fatal: loose object (stored >> | in .git/objects/ff/ff) is >> | corrupt >> | not ok 5 - fsck survives inflate errors # TODO known breakage >> ` >> >> If I flip it from expect_failure to expect_success and run the test with >> -i, then go into the trash directory and run "gdb ../../git-fsck", I can >> obtain this (thoroughly rehearsed & trimmed) gdb transcript: >> >> , >> | % gdb ../../git-fsck >> | GNU gdb (Debian 7.7.1-3) 7.7.1 >> ... >> | Reading symbols from ../../git-fsck...done. >> | (gdb) break error >> | Breakpoint 1 at 0x813d24c: file usage.c, line 143. >> | (gdb) break die >> | Breakpoint 2 at 0x813d152: file usage.c, line 94. >> | (gdb) run >> | Starting program: /home/naesten/hacking/git/git-fsck >> | [Thread debugging using libthread_db enabled] >> | Using host libthread_db library >> | "/lib/i386-linux-gnu/i686/cmov/libthread_db.so.1". >> | Checking object directories: 100% (256/256), done. >> | >> | Breakpoint 1, error (err=0x8182f7a "inflate: %s (%s)") at usage.c:143 >> | 143 { >> | (gdb) bt >> | #0 error (err=0x8182f7a "inflate: %s (%s)") at usage.c:143 >> | #1 0x081452ff in git_inflate (strm=0xbfffe6b8, flush=0) >> | at zlib.c:144 >> | #2 0x08125367 in unpack_sha1_header (stream=, >> | map=, mapsize=, >> | buffer=, bufsiz=) >> | at sha1_file.c:1515 >> | #3 0x08125546 in sha1_loose_object_info ( >> | sha1=sha1@entry=0x82659d4 '\377' , >> | oi=oi@entry=0xbfffe788) at sha1_file.c:2528 >> | #4 0x08126b2d in sha1_object_info_extended ( >> | sha1=0x82659d4 '\377' , oi=0xbfffe788, flags=1) >> | at sha1_file.c:2565 >> | #5 0x0812666f in sha1_object_info ( >> | sha1=0x82659d4 '\377' , sizep=0x0) >> | at sha1_file.c:2601 >> | #6 0x080f6941 in parse_object ( >> | sha1=0x82659d4 '\377' ) at object.c:247 >> | #7 0x080758ac in fsck_sha1 ( >> | sha1=sha1@entry=0x82659d4 '\377' ) >> | at builtin/fsck.c:333 >> ... >> | (gdb) c >> | Continuing. >> | error: inflate: data stream error (incorrect header check) >> | >> | Breakpoint 1, error (err=0x817c525 "unable to unpack %s header") >> | at usage.c:143 >> | 143 { >> | (gdb) bt >> | #0 error (err=0x817c525 "unable to unpack %s header") at usage.c:143 >> | #1 0x08125564 in sha1_loose_object_info ( >> | sha1=sha1@entry=0x82659d4 '\377' , >> | oi=oi@entry=0xbfffe788) at sha1_file.c:2529 >> | #2 0x08126b2d in sha1_object_info_extended ( >> | sha1=0x82659d4 '\377' , oi=0xbfffe788, flags=1) >> | at sha1_file.c:2565 >> | #3 0x0812666f in sha1_object_info ( >> | sha1=0x82659d4 '\377' , sizep=0x0) >> | at sha1_file.c:2601 >> | #4 0x080f6941 in parse_object ( >> | sha1=0x82659d4 '\377' ) at object.c:247 >> ... >> | (gdb) frame 4 >> | #4 0x080f6941 in parse_object ( >> | sha1=0x82659d4 '\377' ) at object.c:247 >> | warning: Source file is more recent than executable. >> | 247 sha1_object_info(sha1, NULL) == OBJ_BLOB)) { // <-- first error >> | (gdb) down >> | #3 0x0812666f in sha1_object_info ( >> | sha1
Re: [PATCH] Add failing test: "fsck survives inflate errors"
On Mon, Jul 21, 2014 at 3:43 AM, Samuel Bronson wrote: > So, given that parse_object()'s documentation is: > > --8<---cut here---start->8--- > /* > * Returns the object, having parsed it to find out what it is. > * > * Returns NULL if the object is missing or corrupt. > */ > --8<---cut here---end--->8--- > > it probably should not call read_sha1_file() on a corrupt object. > > Options for fixing this would appear to include: > > 1. Saving the result of sha1_object_info(sha1, NULL) to a variable and >returning early if the object is corrupt. (But what happens if there >is corruption far enough in that it isn't seen when trying to grab >the object header?) > > 2. Calling read_object() and giving our own error messages. > > 3. Making read_sha1_file_extended only *optionally* die; since it's >calling die() directly. We've been using die() quite freely (or at least used to) and there are many more cases that can trigger die() and parse_object() can do nothing about it. Adding a "gentle" flag to read_sha1_file_extended and pass it further down could be the first step. Patches welcome. -- Duy -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html