Reset sometimes updates mtime
I'm seeing some behaviour with git reset that I find odd. Basically if I do git fetch \ git reset --hard simple-tag-that-points-to-the-current-commit sometimes the reset will update the mtime of all files and directories in the repo and sometimes it will leave them alone. Changing it to git fetch \ git status \ git reset --hard simple-tag-that-points-to-the-current-commit Cause the mtime update to reliably not happen. Bad thing is that I am relying on the mtime updates not to happen if the files don't actually change. Is this an assumption I can safely make? If it is, then I'll debug further (e.g. I don't even know yet if the file gets rewritten or just touched, why the index gets updated as well etc.). -- Dennis Kaarsemaker http://www.kaarsemaker.net -- 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 v4] log: add log.follow config option
Matthieu Moy matthieu@grenoble-inp.fr writes: David Turner dtur...@twopensource.com writes: This version uses tweak, and also includes Matthieu Moy's suggested whitespace fix. This comment should come below the --- after the commit message (right before the diffstat). Otherwise, Junio will get this as the commit message when applying, and your actual commit message will be ignored. --- Many users prefer to always use --follow with logs. Rather than aliasing the command, an option might be more convenient for some. Junio C Hamano gits...@pobox.com suggested using the tweak functionality for this, which is much nicer than what I had before. I would avoid using what I had before in the commit message: readers of git log do not know what you had before. That, together with This version uses..., should go below the three-dash line after the real log message. compared to what I had before is a perfectly good thing to say to help reviewers there. OTOH, crediting Junio for the idea is good. I do not think I deserve anything more than a Helped-by on this particular one, if any. More importantly, the real log message part somewhat lacking, I think. The commit author is in no position to declare Many users prefer X as if it were a fact. But the author is in a very good position to explain: - why users might want to do X under what condition; - how the new feature helps them do so; and - how the implementation carefully avoids not doing unwanted things when inappropriate. all of which would give good justifications for the change. If I were David and sending this v4 patch, it would have looked like this. -- 8 -- From: David Turner dtur...@twopensource.com Date: Tue, 7 Jul 2015 21:29:34 -0400 Subject: [PATCH v4] log: add log.follow configuration variable People who work on projects with mostly linear history with frequent whole file renames may want to always use git log --follow when inspecting the life of the content that live in a single path. Teach the command to behave as if --follow was given from the command line when log.follow configuration variable is set *and* there is one (and only one) path on the command line. Signed-off-by: David Turner dtur...@twopensource.com --- * Changes from v3: - fixed whitespace breakage in test, pointed out by Matthieu - revert all changes to revision.c; instead use the existing opt-tweak() mechanism, suggested by Junio Documentation/git-log.txt | 6 ++ builtin/log.c | 16 diff.c| 5 +++-- diff.h| 1 + t/t4202-log.sh| 23 +++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 5692945..79bf4d4 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -184,6 +184,12 @@ log.date:: `--date` option.) Defaults to default, which means to write dates like `Sat May 8 19:35:34 2010 -0500`. +log.follow:: + If a single path is given to git log, it will act as + if the `--follow` option was also used. This has the same + limitations as `--follow`, i.e. it cannot be used to follow + multiple files and does not work well on non-linear history. + log.showRoot:: If `false`, `git log` and related commands will not treat the initial commit as a big creation event. Any root commits in diff --git a/builtin/log.c b/builtin/log.c index 8781049..d06248a 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -31,6 +31,7 @@ static const char *default_date_mode = NULL; static int default_abbrev_commit; static int default_show_root = 1; +static int default_follow; static int decoration_style; static int decoration_given; static int use_mailmap_config; @@ -102,6 +103,8 @@ static void cmd_log_init_defaults(struct rev_info *rev) { if (fmt_pretty) get_commit_format(fmt_pretty, rev); + if (default_follow) + DIFF_OPT_SET(rev-diffopt, DEFAULT_FOLLOW_RENAMES); rev-verbose_header = 1; DIFF_OPT_SET(rev-diffopt, RECURSIVE); rev-diffopt.stat_width = -1; /* use full terminal width */ @@ -390,6 +393,10 @@ static int git_log_config(const char *var, const char *value, void *cb) default_show_root = git_config_bool(var, value); return 0; } + if (!strcmp(var, log.follow)) { + default_follow = git_config_bool(var, value); + return 0; + } if (skip_prefix(var, color.decorate., slot_name)) return parse_decorate_color_config(var, slot_name, value); if (!strcmp(var, log.mailmap)) { @@ -618,6 +625,14 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix) return cmd_log_walk(rev); } +static void default_follow_tweak(struct rev_info *rev, +struct setup_revision_opt *opt) +{ +
Re: [PATCH v5 1/4] implement submodule config API for lookup of .gitmodules values
On Thu, Jul 09, 2015 at 02:09:01PM +0200, Heiko Voigt wrote: Instead of test-submodule-config.c to test this new module, it could be useful to implement these as extensions to rev-parse: git rev-parse --submodule-name [ref:]path git rev-parse --submodule-path [ref:]name git rev-parse --submodule-url [ref:]name git rev-parse --submodule-ignore [ref:]name git rev-parse --submodule-recurse [ref:]name Has this already been considered and rejected for some reason? No that has not been considered. But I am open to it if others agree that this is a sensible thing to do. We should be able to adapt the existing tests right? How does git-submodule access this information? It looks like it just hits git config -f .gitmodules directly. Perhaps whatever interface is designed should be suitable for its use here (and if there really is no more interesting interface needed, then why is git config not good enough for other callers?). Just my two cents as an observer who does not really work on submodules. Also, I'm not excited to see more options go into the kitchen-sink of rev-parse, but I cannot think of a better place (I would have said git submodule config or something, but that is a chicken-and-egg with the suggestion I made above :) ). -Peff -- 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] clone: Make use of the strip_suffix() helper method
On Thu, Jul 9, 2015 at 7:00 PM, Jeff King p...@peff.net wrote: If you wanted to get really fancy, I think you could put a ternary operator in the middle of the strip_suffix call. That makes it clear that len is set in all code paths, but I think some people find ternary operators unreadable. :) I like the idea about the ternary operator, will do. This one can also be simplified using xstrfmt to: Nice, will also do. Do we still need to cast len to an int to use it with %.* (it is defined by the standard as an int, not a size_t)? I think we're more on the safe side by keeping the cast, so I'll do that, too. -- Sebastian Schuberth -- 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] clone: Make use of the strip_suffix() helper method
Signed-off-by: Sebastian Schuberth sschube...@gmail.com --- builtin/clone.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index 00535d0..d35b2b9 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -147,6 +147,7 @@ static char *get_repo_path(const char *repo, int *is_bundle) static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) { const char *end = repo + strlen(repo), *start; + size_t len; char *dir; /* @@ -174,19 +175,17 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) * Strip .{bundle,git}. */ if (is_bundle) { - if (end - start 7 !strncmp(end - 7, .bundle, 7)) - end -= 7; + strip_suffix(start, .bundle, len); } else { - if (end - start 4 !strncmp(end - 4, .git, 4)) - end -= 4; + strip_suffix(start, .git, len); } if (is_bare) { struct strbuf result = STRBUF_INIT; - strbuf_addf(result, %.*s.git, (int)(end - start), start); + strbuf_addf(result, %.*s.git, len, start); dir = strbuf_detach(result, NULL); } else - dir = xstrndup(start, end - start); + dir = xstrndup(start, len); /* * Replace sequences of 'control' characters and whitespace * with one ascii space, remove leading and trailing spaces. --- https://github.com/git/git/pull/160
Re: [PATCH] clone: Make use of the strip_suffix() helper method
On Thu, Jul 09, 2015 at 03:33:46PM +, Sebastian Schuberth wrote: @@ -174,19 +175,17 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) * Strip .{bundle,git}. */ if (is_bundle) { - if (end - start 7 !strncmp(end - 7, .bundle, 7)) - end -= 7; + strip_suffix(start, .bundle, len); } else { - if (end - start 4 !strncmp(end - 4, .git, 4)) - end -= 4; + strip_suffix(start, .git, len); } Yay, always glad to see complicated string handling like this go away. As the resulting conditional blocks are one-liners, I think you can drop the curly braces, which will match our usual style: if (is_bundle) strip_suffix(start, .bundle, len); else strip_suffix(start, .git, len); If you wanted to get really fancy, I think you could put a ternary operator in the middle of the strip_suffix call. That makes it clear that len is set in all code paths, but I think some people find ternary operators unreadable. :) if (is_bare) { struct strbuf result = STRBUF_INIT; - strbuf_addf(result, %.*s.git, (int)(end - start), start); + strbuf_addf(result, %.*s.git, len, start); dir = strbuf_detach(result, NULL); This one can also be simplified using xstrfmt to: if (is_bare) dir = xstrfmt(%.*s.git, len, start); Do we still need to cast len to an int to use it with %.* (it is defined by the standard as an int, not a size_t)? -Peff -- 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] clone: Simplify string handling in guess_dir_name()
Signed-off-by: Sebastian Schuberth sschube...@gmail.com --- builtin/clone.c | 16 +++- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index 00535d0..afdc004 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -147,6 +147,7 @@ static char *get_repo_path(const char *repo, int *is_bundle) static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) { const char *end = repo + strlen(repo), *start; + size_t len; char *dir; /* @@ -173,20 +174,9 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) /* * Strip .{bundle,git}. */ - if (is_bundle) { - if (end - start 7 !strncmp(end - 7, .bundle, 7)) - end -= 7; - } else { - if (end - start 4 !strncmp(end - 4, .git, 4)) - end -= 4; - } + strip_suffix(start, is_bundle ? .bundle : .git , len); - if (is_bare) { - struct strbuf result = STRBUF_INIT; - strbuf_addf(result, %.*s.git, (int)(end - start), start); - dir = strbuf_detach(result, NULL); - } else - dir = xstrndup(start, end - start); + dir = is_bare ? xstrfmt(%.*s.git, (int)len, start) : xstrndup(start, len); /* * Replace sequences of 'control' characters and whitespace * with one ascii space, remove leading and trailing spaces. --- https://github.com/git/git/pull/160
Re: [PATCH v4] log: add log.follow config option
On Thu, 2015-07-09 at 10:23 -0700, Junio C Hamano wrote: snip If I were David and sending this v4 patch, it would have looked like this. -- 8 -- From: David Turner dtur...@twopensource.com Date: Tue, 7 Jul 2015 21:29:34 -0400 Subject: [PATCH v4] log: add log.follow configuration variable People who work on projects with mostly linear history with frequent whole file renames may want to always use git log --follow when inspecting the life of the content that live in a single path. Teach the command to behave as if --follow was given from the command line when log.follow configuration variable is set *and* there is one (and only one) path on the command line. Thanks. That version is much better. -- 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
Building git 2.4.5 on AIX 6.1 problems
I am trying to compile git 2.4.5 which I downloaded as a tar file on AIX 6.1. The machine has gcc installed. Having read through the INSTALL file, there appear to be several ways, either using configure, make, make install or just make, make install with prefix of where to install. Anyway whichever approach I try I end up with the same error. LINK git-credential-store ld: 0711-224 WARNING: Duplicate symbol: .bcopy ld: 0711-224 WARNING: Duplicate symbol: .memmove ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information. ld: 0711-317 ERROR: Undefined symbol: .trace_argv_printf_fl ld: 0711-317 ERROR: Undefined symbol: .trace_printf_key_fl ld: 0711-317 ERROR: Undefined symbol: .trace_want ld: 0711-317 ERROR: Undefined symbol: .trace_strbuf_fl ld: 0711-317 ERROR: Undefined symbol: .trace_disable ld: 0711-317 ERROR: Undefined symbol: .diff_can_quit_early ld: 0711-317 ERROR: Undefined symbol: diff_queued_diff ld: 0711-317 ERROR: Undefined symbol: .diff_setup ld: 0711-317 ERROR: Undefined symbol: .diff_setup_done ld: 0711-317 ERROR: Undefined symbol: .diffcore_std ld: 0711-317 ERROR: Undefined symbol: .diff_free_filepair ld: 0711-317 ERROR: Undefined symbol: .parse_long_opt ld: 0711-317 ERROR: Undefined symbol: .diff_get_color ld: 0711-317 ERROR: Undefined symbol: mime_boundary_leader ld: 0711-317 ERROR: Undefined symbol: .getnanotime ld: 0711-317 ERROR: Undefined symbol: .diff_flush ld: 0711-317 ERROR: Undefined symbol: .diff_line_prefix ld: 0711-317 ERROR: Undefined symbol: .diff_unique_abbrev ld: 0711-317 ERROR: Undefined symbol: .alloc_filespec ld: 0711-317 ERROR: Undefined symbol: .fill_filespec ld: 0711-317 ERROR: Undefined symbol: .fill_textconv ld: 0711-317 ERROR: Undefined symbol: .free_filespec ld: 0711-317 ERROR: Undefined symbol: .diff_unmodified_pair ld: 0711-317 ERROR: Undefined symbol: .diff_warn_rename_limit ld: 0711-317 ERROR: Undefined symbol: .parse_algorithm_value ld: 0711-317 ERROR: Undefined symbol: .parse_rename_score ld: 0711-317 ERROR: Undefined symbol: .diff_change ld: 0711-317 ERROR: Undefined symbol: .diff_unmerge ld: 0711-317 ERROR: Undefined symbol: .diff_addremove ld: 0711-317 ERROR: Undefined symbol: .diff_set_mnemonic_prefix ld: 0711-317 ERROR: Undefined symbol: .diffcore_fix_diff_index ld: 0711-317 ERROR: Undefined symbol: .diff_queue_is_empty ld: 0711-317 ERROR: Undefined symbol: .diff_populate_filespec ld: 0711-317 ERROR: Undefined symbol: .diff_q ld: 0711-317 ERROR: Undefined symbol: .diff_opt_parse ld: 0711-317 ERROR: Undefined symbol: .diff_flush_patch_id collect2: error: ld returned 8 exit status Makefile:1958: recipe for target 'git-credential-store' failed gmake: *** [git-credential-store] Error 1 The machine I am building on has built git in the past (not by me). I have downloaded the source for 2.1.0 and 1.9.2 and both of those have the same problem and the latter was built about 12 months ago. I had hoped the version of gcc was too old but I presume not. So possibly a problem with the environment as building as different user? But really need help as this is very frustrating and googling has not found anything that quite matches it. Regards, John -- 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] clone: Simplify string handling in guess_dir_name()
On Thu, Jul 9, 2015 at 8:05 PM, Junio C Hamano gits...@pobox.com wrote: Subject: Re: [PATCH v2] clone: Simplify string handling in guess_dir_name() We seem not to capitalize the first word on the subject line. Will change that. Content-Type: multipart/mixed; boundary==_Part_8_836493213.1436462597065 Please don't. This seems to come from submitgit, I've filed an issue about it: https://github.com/rtyley/submitgit/issues/17 What content type(s) would you accept? Only text/plain? - if (is_bare) { - struct strbuf result = STRBUF_INIT; - strbuf_addf(result, %.*s.git, (int)(end - start), start); - dir = strbuf_detach(result, NULL); - } else - dir = xstrndup(start, end - start); + dir = is_bare ? xstrfmt(%.*s.git, (int)len, start) : xstrndup(start, len); This however I had to read twice. I'd say if (is_bare) dir = xstrfmt(...); else dir = xstrndup(...); is much easier to read. That's what I had locally before. Will revert to that. -- Sebastian Schuberth -- 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] clone: Simplify string handling in guess_dir_name()
Sebastian Schuberth sschube...@gmail.com writes: On Thu, Jul 9, 2015 at 8:05 PM, Junio C Hamano gits...@pobox.com wrote: Content-Type: multipart/mixed; boundary==_Part_8_836493213.1436462597065 Please don't. This seems to come from submitgit, I've filed an issue about it: https://github.com/rtyley/submitgit/issues/17 What content type(s) would you accept? Only text/plain? I could take anything, even chicken scratches on a piece of paper, for a small change like this. But let's make sure we see text/plain out of submitgit, as the whole point of it is to allow people generate the common denominator format out of a commit pushed to GitHub. Thanks for letting them know. -- 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] clone: Simplify string handling in guess_dir_name()
Sebastian Schuberth sschube...@gmail.com writes: Subject: Re: [PATCH v2] clone: Simplify string handling in guess_dir_name() We seem not to capitalize the first word on the subject line. Content-Type: multipart/mixed; boundary==_Part_8_836493213.1436462597065 Please don't. Signed-off-by: Sebastian Schuberth sschube...@gmail.com --- builtin/clone.c | 16 +++- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index 00535d0..afdc004 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -147,6 +147,7 @@ static char *get_repo_path(const char *repo, int *is_bundle) static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) { const char *end = repo + strlen(repo), *start; + size_t len; char *dir; /* @@ -173,20 +174,9 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) /* * Strip .{bundle,git}. */ - if (is_bundle) { - if (end - start 7 !strncmp(end - 7, .bundle, 7)) - end -= 7; - } else { - if (end - start 4 !strncmp(end - 4, .git, 4)) - end -= 4; - } + strip_suffix(start, is_bundle ? .bundle : .git , len); This looks vastly nicer than the original. - if (is_bare) { - struct strbuf result = STRBUF_INIT; - strbuf_addf(result, %.*s.git, (int)(end - start), start); - dir = strbuf_detach(result, NULL); - } else - dir = xstrndup(start, end - start); + dir = is_bare ? xstrfmt(%.*s.git, (int)len, start) : xstrndup(start, len); This however I had to read twice. I'd say if (is_bare) dir = xstrfmt(...); else dir = xstrndup(...); is much easier to read. -- 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: Building git 2.4.5 on AIX 6.1 problems
John Norris j...@norricorp.f9.co.uk writes: I am trying to compile git 2.4.5 which I downloaded as a tar file on AIX 6.1. The machine has gcc installed. Having read through the INSTALL file, there appear to be several ways, either using configure, make, make install or just make, make install with prefix of where to install. Anyway whichever approach I try I end up with the same error. LINK git-credential-store ld: 0711-224 WARNING: Duplicate symbol: .bcopy ... But really need help as this is very frustrating and googling has not found anything that quite matches it. As ld: 0711-224 WARNING: Duplicate symbol: .bcopy seems to hit many similar issues across different piece of software, I have a suspicion that AIX folks (as opposed to Git folks) may have a lot better insight to the peculiarity of the platform. Running make with V=1 may show the exact command line that is invoked (it would begin with gcc ..., I think), which may help diagnosing the issue further. -- 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 v3] clone: Simplify string handling in guess_dir_name()
Signed-off-by: Sebastian Schuberth sschube...@gmail.com --- builtin/clone.c | 17 + 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index 00535d0..ebcb849 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -147,6 +147,7 @@ static char *get_repo_path(const char *repo, int *is_bundle) static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) { const char *end = repo + strlen(repo), *start; + size_t len; char *dir; /* @@ -173,19 +174,11 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) /* * Strip .{bundle,git}. */ - if (is_bundle) { - if (end - start 7 !strncmp(end - 7, .bundle, 7)) - end -= 7; - } else { - if (end - start 4 !strncmp(end - 4, .git, 4)) - end -= 4; - } + strip_suffix(start, is_bundle ? .bundle : .git , len); - if (is_bare) { - struct strbuf result = STRBUF_INIT; - strbuf_addf(result, %.*s.git, (int)(end - start), start); - dir = strbuf_detach(result, NULL); - } else + if (is_bare) + dir = xstrfmt(%.*s.git, (int)len, start); + else dir = xstrndup(start, end - start); /* * Replace sequences of 'control' characters and whitespace --- https://github.com/git/git/pull/160
[PATCH v4] clone: simplify string handling in guess_dir_name()
Signed-off-by: Sebastian Schuberth sschube...@gmail.com --- builtin/clone.c | 17 + 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index 00535d0..ebcb849 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -147,6 +147,7 @@ static char *get_repo_path(const char *repo, int *is_bundle) static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) { const char *end = repo + strlen(repo), *start; + size_t len; char *dir; /* @@ -173,19 +174,11 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) /* * Strip .{bundle,git}. */ - if (is_bundle) { - if (end - start 7 !strncmp(end - 7, .bundle, 7)) - end -= 7; - } else { - if (end - start 4 !strncmp(end - 4, .git, 4)) - end -= 4; - } + strip_suffix(start, is_bundle ? .bundle : .git , len); - if (is_bare) { - struct strbuf result = STRBUF_INIT; - strbuf_addf(result, %.*s.git, (int)(end - start), start); - dir = strbuf_detach(result, NULL); - } else + if (is_bare) + dir = xstrfmt(%.*s.git, (int)len, start); + else dir = xstrndup(start, end - start); /* * Replace sequences of 'control' characters and whitespace --- https://github.com/git/git/pull/160
Re: Reset sometimes updates mtime
Dennis Kaarsemaker den...@kaarsemaker.net writes: I'm seeing some behaviour with git reset that I find odd. Basically if I do git fetch \ git reset --hard simple-tag-that-points-to-the-current-commit sometimes the reset will update the mtime of all files and directories in the repo and sometimes it will leave them alone. Changing it to git fetch \ git status \ git reset --hard simple-tag-that-points-to-the-current-commit Cause the mtime update to reliably not happen. If my theory on what is happening is correct, I do not think there is any bug in what reset --hard is doing. My theory is that something is causing the stat info that is cached in your index and the lstat(2) return you get from your working tree files go out of sync. Even though you are not actively touching any working tree files (otherwise, you wouldn't be complaining about mtime changing in the first place), perhaps your build of Git records timestamps in NS but your filesystem and the operating system does not preserve nanosecond resolution of timestamps when it evicts inode data from the core, or something like that? If that is what is happening, I think that fetch is a red herring, but any operation that takes some time and/or hits filesystem reasonably hard would trigger it. And the reason why I say there is no bug in what reset --hard is doing here, if the above theory is correct, is because: - The user asked reset --hard to make sure that my working tree files are identical to those of HEAD; - reset --hard looks at lstat(2) return and the cached stat info in the index and find them not to match. It can do one of two things: (1) see if the user did something stupid, like touch file, that modifies only lstat(2) info without actually changing its contents, by reading from the working tree, reading HEAD:file from the object database, and comparing them, and overwrite the working tree file only when they do not match. or (2) the contents might happen to be the same, but the end result user desires to have is that the contents of the working tree file is the same as that from the HEAD, so overwrite it without wasting time reading two and compare before doing so. and it is perfectly reasonable to do the latter. After all, the whole point of having its cached lstat(2) data in the index is to so that we do not have to always compare the contents before deciding something has changed in the working tree. Running git update-index --refresh immediately before reset may alleviate the issue. git status has the same effect, only because it does update-index --refresh at the beginning of its processing, but it wastes a lot more time and resource doing other things. But unless/until you know _why_ the cached stat info in your index goes stale relative to what lstat(2) tells you, it would not solve it, because that magical thing (and my theory is cached data in your operating system that keeps a file timestamp with more precision than your underlying filesystem can represent is being flushed, and reading the file timestamp back from the disk has to truncate the nanoseconds part) can happen at any time between the --refresh and your reset. -- 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 v4] log: add log.follow config option
David Turner dtur...@twopensource.com writes: On Thu, 2015-07-09 at 10:23 -0700, Junio C Hamano wrote: snip If I were David and sending this v4 patch, it would have looked like this. -- 8 -- From: David Turner dtur...@twopensource.com Date: Tue, 7 Jul 2015 21:29:34 -0400 Subject: [PATCH v4] log: add log.follow configuration variable People who work on projects with mostly linear history with frequent whole file renames may want to always use git log --follow when inspecting the life of the content that live in a single path. Teach the command to behave as if --follow was given from the command line when log.follow configuration variable is set *and* there is one (and only one) path on the command line. Thanks. That version is much better. No, thank _you_; we should be thanking you for helping us improve the system ;-) -- 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 v3] notes: Allow committish expressions as notes ref
On Thu, Jul 9, 2015 at 4:48 AM, Mike Hommey m...@glandium.org wrote: init_notes() is the main point of entry to the notes API. It is an arbitrary restriction that all it allows as input is a strict ref name, when callers may want to give an arbitrary committish. However, some operations that require updating the notes tree require a strict ref name, because they wouldn't be able to update e.g. foo@{1}. So we allow committish expressions to be used in the case the notes tree is going to be used without write permissions, and to distinguish whether the notes tree is intended to be used for reads only, or will be updated, a flag is added. This has the side effect of enabling the use of committish as notes refs in commands allowing them, e.g. git log --notes=foo@{1}. Signed-off-by: Mike Hommey m...@glandium.org Reviewed-by: Johan Herland jo...@herland.net ...modulo some comments below. --- builtin/notes.c | 29 - notes-cache.c | 11 ++- notes-utils.c | 6 +++--- notes.c | 11 +++ notes.h | 10 +- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/builtin/notes.c b/builtin/notes.c index 63f95fc..0fc6e7a 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -285,7 +285,7 @@ static int notes_copy_from_stdin(int force, const char *rewrite_cmd) if (!c) return 0; } else { - init_notes(NULL, NULL, NULL, 0); + init_notes(NULL, NULL, NULL, NOTES_INIT_WRITABLE); t = default_notes_tree; } @@ -328,15 +328,18 @@ static int notes_copy_from_stdin(int force, const char *rewrite_cmd) return ret; } -static struct notes_tree *init_notes_check(const char *subcommand) +static struct notes_tree *init_notes_check(const char *subcommand, + int flags) { struct notes_tree *t; - init_notes(NULL, NULL, NULL, 0); + const char *ref; + init_notes(NULL, NULL, NULL, flags); t = default_notes_tree; - if (!starts_with(t-ref, refs/notes/)) + ref = (flags NOTES_INIT_WRITABLE) ? t-update_ref : t-ref; Hmm, AFAICS from the code in notes.c, when NOTES_INIT_WRITABLE is set, then t-ref == t-update_ref, which means the above line is redundant, and t-ref will work just as well. That said, it's also bad to depend on that fact from here, as the notes code might at some point change to make t-ref != t-update_ref (e.g. if we want to allow a notes tree which reads from one ref, but writes to another), so I guess the current code is good. + if (!starts_with(ref, refs/notes/)) die(Refusing to %s notes in %s (outside of refs/notes/), - subcommand, t-ref); + subcommand, ref); return t; } [...] diff --git a/notes.c b/notes.c index df08209..84f8a47 100644 --- a/notes.c +++ b/notes.c @@ -1007,13 +1007,16 @@ void init_notes(struct notes_tree *t, const char *notes_ref, t-first_non_note = NULL; t-prev_non_note = NULL; t-ref = xstrdup_or_null(notes_ref); + t-update_ref = (flags NOTES_INIT_WRITABLE) ? t-ref : NULL; This is the only place in notes.c that references t-update_ref. Which points to a latent design flaw in the notes API: struct notes_tree keeps track of the notes ref (previously t-ref, but now also t-update_ref), but it is actually never used by the core notes implementation (except for display purposes in format_note() and an error message in load_subtree()). I guess a better design would be to either (a) move the ref out of the API entirely, leaving notes.h/.c to only worry about reading and writing notes tree objects, and letting the caller deal with resolving and updatiung notes refs and commit objects. (b) move the ref handling _into_ the API, basically moving commit_notes() from notes-utils.h/.c into notes.h/.c Of these, I believe (a) is better, escpecially if we also provide a wrapper API (in notes-utils.h/.c?) around the inner/core API to deal with the commit/ref details. However, this is largely independent of your current effort, and belongs in a different patch (series). t-combine_notes = combine_notes; t-initialized = 1; t-dirty = 0; if (flags NOTES_INIT_EMPTY || !notes_ref || - read_ref(notes_ref, object_sha1)) + get_sha1_committish(notes_ref, object_sha1)) I believe this should be get_sha1_treeish() instead. The only place we use the result (object_sha1) is when calling get_tree_entry() below, which will peel to a tree object anyway, so there's no need to place the stricter commitish requirement on the caller (in the read-only case). As a bonus, you can also s/commitish/treeish/ in the commit subject line. Also, I do not immediately remember whether we support notes refs that point directly at tree
Re: Building git 2.4.5 on AIX 6.1 problems
On Fri, Jul 10, 2015 at 04:32:37AM +, John Norris wrote: But there are a few archive commands before I get to linking credentials-store. Is there something special about credentials store? Not really. It is just the first program alphabetically, so it comes first in the Makefile. You can try make git and you'll probably see similar problems linking git (or if you don't, then it is a sign our Makefile is broken for external programs versus the main git binary). And is the collect2 an AIX library or general library used by git? It's a gcc thing: https://gcc.gnu.org/onlinedocs/gccint/Collect2.html -Peff -- 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: Building git 2.4.5 on AIX 6.1 problems
John Norris j...@norricorp.f9.co.uk writes: But there are a few archive commands before I get to linking credentials-store. Is there something special about credentials store? And is the collect2 an AIX library or general library used by git? Wow, that's a blast from the past. My recollection is vague, as it has at least been 15 years since I had to hear that name causing trouble the last time ;-), but collect2 is a gcc thing that is used on a platform, where the native linker cannot be directly used to link gcc output with libraries, as ld replacement/wrapper. -- 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 v7 2/8] cherry-pick: treat CHERRY_PICK_HEAD and REVERT_HEAD as refs
On 07/10/2015 12:06 AM, Junio C Hamano wrote: David Turner dtur...@twopensource.com writes: OK, here's my current best idea: 1. A pseudoref is an all-caps file in $GIT_DIR/ that always contains at least a SHA1. CHERRY_PICK_HEAD and REVERT_HEAD are examples. Because HEAD might be a symbolic ref, it is not a pseudoref. Refs backends do not manage pseudorefs. Instead, when a pseudoref (an all-caps ref containing no slashes) is requested (e.g. git rev-parse FETCH_HEAD) the generic refs code checks for the existence of that file and if it exists, returns immediately without hitting the backend. The generic code will refuse to allow updates to pseudorefs. 2. The pluggable refs backend manages all refs other than HEAD. 3. The files backend always manages HEAD. This allows for a reflog and for HEAD to be a symbolic ref. The major complication here is ref transactions -- what if there's a transaction that wants to update e.g. both HEAD and refs/heads/master? An update to the current branch (e.g. git commit) does involve at least update to the reflog of HEAD, the current branch somewhere in refs/heads/ and its log, so it is not what if but is a norm [*1*]. The updating of symlink reflogs in general, and particularly that of HEAD, is not done very cleanly. You can see the code in `commit_ref_update()` (some of it helpfully commented to be a Special hack): * If a reference is modified through a symlink, the symlink is locked rather than the reference itself. * If a reference is modified directly, and HEAD points at it, then the HEAD reflog is amended without locking HEAD. Aside from the lack of proper locking, which could result in races with other processes, we also have the problem that the same reference that is being changed via one of these implicit updates could *also* be being changed directly in the same transaction. Such an update would evade the `ref_update_reject_duplicates()` check. Previously my thinking was that the locking should be done differently: when the transaction is being processed, extra ref_update records could be created for the extra reference(s) that have to be modified, then these could be handled more straightforwardly. So supposing that HEAD points at refs/heads/master, * An update of HEAD would be turned into a reflog update and also add a synthetic update to refs/heads/master. * An update of refs/heads/master would add a synthetic update to the HEAD reflog The first point would obviously apply to any updates via symbolic refs. The second one should too, thought this is a case that we currently punt on to avoid the need to do reverse symbolic ref lookups. It may be the case that this never happens; I have not actually audited the code to figure it out. If someone knows for sure that it does not happen, please say so. But assuming it does happen, here's my idea: If the refs backend is the files backend, we can simply treat HEAD like any other ref. If the refs backend is different, then the refs code needs to hold a files-backend transaction for HEAD, which it will commit immediately after the other transaction succeeds. We can stick a pointer to the extra transaction in the generic struct ref_transaction, which (as Michael Haggerty suggests) specific backends will extend. A failure to commit either transaction will be reported as a failure, and we'll give an additional inconsistent state warning if the main transaction succeeds but the HEAD transaction fails. Yeah, I was thinking along those lines, too. Thanks for clearly writing it down. What do other folks think? Me too ;-) I don't have an answer right now, and I have to get on an airplane in a few hours so I can't think hard about it at the moment. But let me also braindump another vague plan that I have had for a long time: overlayable reference storage schemes. Think of the way that loose refs are currently overlaid on top of packed refs. I think it might be useful to support overlaying more generally. In this particular case there could be a workspace-local reference storage that only handles HEAD and perhaps some of the other pseudoreferences. That could be overlaid onto loose reference storage (which would then only concern itself with references under refs/), which would in turn be overlaid onto packed refs. The workspace-local reference storage layer would have evil special-cased code for dealing with the references that live outside of refs/. A `ref_transaction_commit()` would be broken into phases: first each of the stacked backends would be asked to verify that the transaction is possible and acquire any necessary locks, then each backend would get the final commit command. This construct would make it easy for different backends to share the same implementation for HEAD (and potentially other workspace-local) references, by simply layering that one storage mechanism on top of their own. That would probably be overengineering if it were only used to
Re: Building git 2.4.5 on AIX 6.1 problems
Hi Junio, thank you for this - I will run make with V=1 as you suggested and try and talk to some IBM AIX people. But there are a few archive commands before I get to linking credentials-store. Is there something special about credentials store? And is the collect2 an AIX library or general library used by git? Regards, John -- 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 v4] notes: Allow treeish expressions as notes ref
init_notes() is the main point of entry to the notes API. It is an arbitrary restriction that all it allows as input is a strict ref name, when callers may want to give an arbitrary treeish. However, some operations that require updating the notes tree require a strict ref name, because they wouldn't be able to update e.g. foo@{1}. So we allow treeish expressions to be used in the case the notes tree is going to be used without write permissions, and to distinguish whether the notes tree is intended to be used for reads only, or will be updated, a flag is added. This has the side effect of enabling the use of treeish as notes refs in commands allowing them, e.g. git log --notes=foo@{1}. Signed-off-by: Mike Hommey m...@glandium.org Reviewed-by: Johan Herland jo...@herland.net --- builtin/notes.c | 29 - notes-cache.c | 11 ++- notes-utils.c | 6 +++--- notes.c | 11 +++ notes.h | 10 +- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/builtin/notes.c b/builtin/notes.c index 63f95fc..0fc6e7a 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -285,7 +285,7 @@ static int notes_copy_from_stdin(int force, const char *rewrite_cmd) if (!c) return 0; } else { - init_notes(NULL, NULL, NULL, 0); + init_notes(NULL, NULL, NULL, NOTES_INIT_WRITABLE); t = default_notes_tree; } @@ -328,15 +328,18 @@ static int notes_copy_from_stdin(int force, const char *rewrite_cmd) return ret; } -static struct notes_tree *init_notes_check(const char *subcommand) +static struct notes_tree *init_notes_check(const char *subcommand, + int flags) { struct notes_tree *t; - init_notes(NULL, NULL, NULL, 0); + const char *ref; + init_notes(NULL, NULL, NULL, flags); t = default_notes_tree; - if (!starts_with(t-ref, refs/notes/)) + ref = (flags NOTES_INIT_WRITABLE) ? t-update_ref : t-ref; + if (!starts_with(ref, refs/notes/)) die(Refusing to %s notes in %s (outside of refs/notes/), - subcommand, t-ref); + subcommand, ref); return t; } @@ -359,7 +362,7 @@ static int list(int argc, const char **argv, const char *prefix) usage_with_options(git_notes_list_usage, options); } - t = init_notes_check(list); + t = init_notes_check(list, 0); if (argc) { if (get_sha1(argv[0], object)) die(_(Failed to resolve '%s' as a valid ref.), argv[0]); @@ -419,7 +422,7 @@ static int add(int argc, const char **argv, const char *prefix) if (get_sha1(object_ref, object)) die(_(Failed to resolve '%s' as a valid ref.), object_ref); - t = init_notes_check(add); + t = init_notes_check(add, NOTES_INIT_WRITABLE); note = get_note(t, object); if (note) { @@ -510,7 +513,7 @@ static int copy(int argc, const char **argv, const char *prefix) if (get_sha1(object_ref, object)) die(_(Failed to resolve '%s' as a valid ref.), object_ref); - t = init_notes_check(copy); + t = init_notes_check(copy, NOTES_INIT_WRITABLE); note = get_note(t, object); if (note) { @@ -588,7 +591,7 @@ static int append_edit(int argc, const char **argv, const char *prefix) if (get_sha1(object_ref, object)) die(_(Failed to resolve '%s' as a valid ref.), object_ref); - t = init_notes_check(argv[0]); + t = init_notes_check(argv[0], NOTES_INIT_WRITABLE); note = get_note(t, object); prepare_note_data(object, d, edit ? note : NULL); @@ -651,7 +654,7 @@ static int show(int argc, const char **argv, const char *prefix) if (get_sha1(object_ref, object)) die(_(Failed to resolve '%s' as a valid ref.), object_ref); - t = init_notes_check(show); + t = init_notes_check(show, 0); note = get_note(t, object); if (!note) @@ -812,7 +815,7 @@ static int merge(int argc, const char **argv, const char *prefix) } } - t = init_notes_check(merge); + t = init_notes_check(merge, NOTES_INIT_WRITABLE); strbuf_addf(msg, notes: Merged notes from %s into %s, remote_ref.buf, default_notes_ref()); @@ -878,7 +881,7 @@ static int remove_cmd(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, git_notes_remove_usage, 0); - t = init_notes_check(remove); + t = init_notes_check(remove, NOTES_INIT_WRITABLE); if (!argc !from_stdin) { retval = remove_one_note(t, HEAD, flag); @@ -920,7 +923,7 @@ static int prune(int argc, const char **argv, const char *prefix)
Re: [PATCH v2] refs: loosen restrictions on wildcard '*' refspecs
On Wed, Jul 8, 2015 at 6:00 AM, Jacob Keller jacob.kel...@gmail.com wrote: This patch updates the check_refname_component logic in order to allow for a less strict refspec format in regards to REFNAME_REFSPEC_PATTERN. Previously the '*' could only replace a single full component, and could not replace arbitrary text. Now, refs such as `foo/bar*:foo/bar*` will be accepted. This allows for somewhat more flexibility in references and does not break any current users. The ref matching code already allows this but the check_refname_format did not. This patch also streamlines the code by making this new check part of check_refname_component instead of checking after we error during check_refname_format, which makes more sense with how we check other issues in refname components. Signed-off-by: Jacob Keller jacob.kel...@gmail.com Cc: Daniel Barkalow barka...@iabervon.iabervon.org Cc: Junio C Hamano gits...@pobox.com --- - v2 * update test suite Documentation/git-check-ref-format.txt | 4 ++-- refs.c | 39 +++--- refs.h | 4 ++-- t/t1402-check-ref-format.sh| 8 --- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt index fc02959..9044dfa 100644 --- a/Documentation/git-check-ref-format.txt +++ b/Documentation/git-check-ref-format.txt @@ -94,8 +94,8 @@ OPTIONS Interpret refname as a reference name pattern for a refspec (as used with remote repositories). If this option is enabled, refname is allowed to contain a single `*` - in place of a one full pathname component (e.g., - `foo/*/bar` but not `foo/bar*`). + in the refspec (e.g., `foo/bar*/baz` or `foo/bar*baz/` + but not `foo/bar*/baz*`). --normalize:: Normalize 'refname' by removing any leading slash (`/`) diff --git a/refs.c b/refs.c index 7ac05cf..8702644 100644 --- a/refs.c +++ b/refs.c @@ -20,11 +20,12 @@ struct ref_lock { * 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 + * 5: check for patterns to reject unless REFNAME_REFSPEC_PATTERN is set */ 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, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, @@ -71,11 +72,13 @@ static unsigned char refname_disposition[256] = { * - 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) + * - it ends with a /, or + * - it ends with .lock, or + * - it contains a \ (backslash), or + * - it contains a @{ portion, or + * - it contains a '*' unless REFNAME_REFSPEC_PATTERN is set */ -static int check_refname_component(const char *refname, int flags) +static int check_refname_component(const char *refname, int *flags) { const char *cp; char last = '\0'; @@ -96,6 +99,16 @@ static int check_refname_component(const char *refname, int flags) break; case 4: return -1; + case 5: + if (!(*flags REFNAME_REFSPEC_PATTERN)) + return -1; /* refspec can't be a pattern */ + + /* +* Unset the pattern flag so that we only accept a single glob for +* the entire refspec. +*/ + *flags = ~ REFNAME_REFSPEC_PATTERN; + break; } last = ch; } @@ -120,18 +133,10 @@ int check_refname_format(const char *refname, int flags) 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 { -
Re: Merge after rename
On Thu, Jul 9, 2015 at 1:44 PM, Phil Susi ps...@ubuntu.com wrote: I'm trying to cherry pick an old change from an old branch onto the current master, and since the old change, the directory structure was altered and the modified files were moved. Instead of detecting the new location of the file and applying the changes to it, git is re-adding the old file at the old location in its entirety. How can I get it to correctly notice the rename and merge the changes in at the file's new location? -- 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 Hi Phil, One way is to format-patch the original commit, and run it through a program like filterdiff, or edit the applied locations by hand. You might also be able to use the merge subtree option. https://git-scm.com/book/en/v1/Git-Tools-Subtree-Merging is where I would start. For example, I would try something like git cherry-pick -X subtree=path/to/strip -X subtree=path/to/add commit You might also have success with git cherry-pick --strategy=subtree which attempts to guess. Hopefully this helps! Regards, Jake -- 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 10/10] tag.c: implement '--merged' and '--no-merged' options
Using 'ref-filter' APIs implement the '--merged' and '--no-merged' options into 'tag.c'. The '--merged' option lets the user to only list tags merged into the named commit. The '--no-merged' option lets the user to only list tags not merged into the named commit. If no object is provided it assumes HEAD as the object. Add documentation and tests for the same. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- Documentation/git-tag.txt | 10 +- builtin/tag.c | 6 +- t/t7004-tag.sh| 27 +++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 16e396c..74ed157 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -14,7 +14,7 @@ SYNOPSIS 'git tag' -d tagname... 'git tag' [-n[num]] -l [--contains commit] [--points-at object] [--column[=options] | --no-column] [--sort=key] [--format=format] - [pattern...] + [(--merged | --no-merged) [commit]] [pattern...] 'git tag' -v tagname... DESCRIPTION @@ -169,6 +169,14 @@ This option is only applicable when listing tags without annotation lines. `%09` to `\t` (TAB) and `%0a` to `\n` (LF). The fields are same as those in `git for-each-ref`. +--merged [commit]:: + Only list tags whose tips are reachable from the + specified commit (HEAD if not specified). + +--no-merged [commit]:: + Only list tags whose tips are not reachable from the + specified commit (HEAD if not specified). + CONFIGURATION - diff --git a/builtin/tag.c b/builtin/tag.c index 601b293..abd42a0 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -23,7 +23,7 @@ static const char * const git_tag_usage[] = { N_(git tag [-a | -s | -u key-id] [-f] [-m msg | -F file] tagname [head]), N_(git tag -d tagname...), N_(git tag -l [-n[num]] [--contains commit] [--points-at object] - \n\t\t[pattern...]), + \n\t\t[--merged [commit]] [--no-merged [commit]] [pattern...]), N_(git tag -v tagname...), NULL }; @@ -350,6 +350,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPT_COLUMN(0, column, colopts, N_(show tag list in columns)), OPT_CONTAINS(filter.with_commit, N_(print only tags that contain the commit)), OPT_WITH(filter.with_commit, N_(print only tags that contain the commit)), + OPT_MERGED(filter, N_(print only tags that are merged)), + OPT_NO_MERGED(filter, N_(print only tags that are not merged)), OPT_CALLBACK(0 , sort, sorting_tail, N_(key), N_(field name to sort on), parse_opt_ref_sorting), { @@ -410,6 +412,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix) die(_(--contains option is only allowed with -l.)); if (filter.points_at.nr) die(_(--points-at option is only allowed with -l.)); + if (filter.merge_commit) + die(_(--merged and --no-merged option are only allowed with -l)); if (cmdmode == 'd') return for_each_tag_name(argv, delete_tag); if (cmdmode == 'v') diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index e8cebb6..873aad3 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1523,4 +1523,31 @@ test_expect_success '--format should list tags as per format given' ' test_cmp expect actual ' +test_expect_success 'setup --merged test tags' ' + git tag mergetest-1 HEAD~2 + git tag mergetest-2 HEAD~1 + git tag mergetest-3 HEAD +' + +test_expect_success '--merged cannot be used in non-list mode' ' + test_must_fail git tag --merged=mergetest-2 foo +' + +test_expect_success '--merged shows merged tags' ' + cat expect -\EOF + mergetest-1 + mergetest-2 + EOF + git tag -l --merged=mergetest-2 mergetest-* actual + test_cmp expect actual +' + +test_expect_success '--no-merged show unmerged tags' ' + cat expect -\EOF + mergetest-3 + EOF + git tag -l --no-merged=mergetest-2 mergetest-* actual + test_cmp expect actual +' + test_done -- 2.4.5 -- 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 08/10] tag.c: use 'ref-filter' APIs
Make 'tag.c' use 'ref-filter' APIs for iterating through refs sorting and printing of refs. This removes most of the code used in 'tag.c' replacing it with calls to the 'ref-filter' library. Make 'tag.c' use the 'filter_refs()' function provided by 'ref-filter' to filter out tags based on the options set. For printing tags we use 'show_ref_array_item()' function provided by 'ref-filter'. We improve the sorting option provided by 'tag.c' by using the sorting options provided by 'ref-filter'. This causes the test 'invalid sort parameter on command line' in t7004 to fail, as 'ref-filter' throws an error for all sorting fields which are incorrect. The test is changed to reflect the same. Modify documentation for the same. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- Documentation/git-tag.txt | 16 ++- builtin/tag.c | 343 ++ t/t7004-tag.sh| 8 +- 3 files changed, 50 insertions(+), 317 deletions(-) diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 4b04c2b..02fb363 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -13,7 +13,7 @@ SYNOPSIS tagname [commit | object] 'git tag' -d tagname... 'git tag' [-n[num]] -l [--contains commit] [--points-at object] - [--column[=options] | --no-column] [pattern...] + [--column[=options] | --no-column] [--sort=key] [pattern...] 'git tag' -v tagname... DESCRIPTION @@ -94,14 +94,16 @@ OPTIONS using fnmatch(3)). Multiple patterns may be given; if any of them matches, the tag is shown. ---sort=type:: - Sort in a specific order. Supported type is refname - (lexicographic order), version:refname or v:refname (tag +--sort=key:: + Sort based on the key given. Prefix `-` to sort in + descending order of the value. You may use the --sort=key option + multiple times, in which case the last key becomes the primary + key. Also supports version:refname or v:refname (tag names are treated as versions). The version:refname sort order can also be affected by the - versionsort.prereleaseSuffix configuration variable. Prepend - - to reverse sort order. When this option is not given, the - sort order defaults to the value configured for the 'tag.sort' + versionsort.prereleaseSuffix configuration variable. + The keys supported are the same as those in `git for-each-ref`. + Sort order defaults to the value configured for the 'tag.sort' variable if it exists, or lexicographic order otherwise. See linkgit:git-config[1]. diff --git a/builtin/tag.c b/builtin/tag.c index bbda0c6..36f8019 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -28,278 +28,34 @@ static const char * const git_tag_usage[] = { NULL }; -#define STRCMP_SORT 0 /* must be zero */ -#define VERCMP_SORT 1 -#define SORT_MASK 0x7fff -#define REVERSE_SORT0x8000 - -static int tag_sort; - static unsigned int colopts; -static int match_pattern(const char **patterns, const char *ref) -{ - /* no pattern means match everything */ - if (!*patterns) - return 1; - for (; *patterns; patterns++) - if (!wildmatch(*patterns, ref, 0, NULL)) - return 1; - return 0; -} - -/* - * This is currently duplicated in ref-filter.c, and will eventually be - * removed as we port tag.c to use the ref-filter APIs. - */ -static const unsigned char *match_points_at(const char *refname, - const unsigned char *sha1, - struct sha1_array *points_at) -{ - const unsigned char *tagged_sha1 = NULL; - struct object *obj; - - if (sha1_array_lookup(points_at, sha1) = 0) - return sha1; - obj = parse_object(sha1); - if (!obj) - die(_(malformed object at '%s'), refname); - if (obj-type == OBJ_TAG) - tagged_sha1 = ((struct tag *)obj)-tagged-sha1; - if (tagged_sha1 sha1_array_lookup(points_at, tagged_sha1) = 0) - return tagged_sha1; - return NULL; -} - -static int in_commit_list(const struct commit_list *want, struct commit *c) -{ - for (; want; want = want-next) - if (!hashcmp(want-item-object.sha1, c-object.sha1)) - return 1; - return 0; -} - -/* - * The entire code segment for supporting the --contains option has been - * copied over to ref-filter.{c,h}. This will be deleted evetually when - * we port tag.c to use ref-filter APIs. - */ -enum contains_result { - CONTAINS_UNKNOWN = -1, - CONTAINS_NO = 0, - CONTAINS_YES = 1 -}; - -/* - * Test whether the candidate or one of its parents is contained in the list. - * Do not recurse to find
[PATCH v2 09/10] tag.c: implement '--format' option
Implement the '--format' option provided by 'ref-filter'. This lets the user list tags as per desired format similar to the implementation in 'git for-each-ref'. Add tests and documentation for the same. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- Documentation/git-tag.txt | 16 +++- builtin/tag.c | 11 +++ t/t7004-tag.sh| 16 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 02fb363..16e396c 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -13,7 +13,8 @@ SYNOPSIS tagname [commit | object] 'git tag' -d tagname... 'git tag' [-n[num]] -l [--contains commit] [--points-at object] - [--column[=options] | --no-column] [--sort=key] [pattern...] + [--column[=options] | --no-column] [--sort=key] [--format=format] + [pattern...] 'git tag' -v tagname... DESCRIPTION @@ -155,6 +156,19 @@ This option is only applicable when listing tags without annotation lines. The object that the new tag will refer to, usually a commit. Defaults to HEAD. +format:: + A string that interpolates `%(fieldname)` from the + object pointed at by a ref being shown. If `fieldname` + is prefixed with an asterisk (`*`) and the ref points + at a tag object, the value for the field in the object + tag refers is used. When unspecified, defaults to + `%(objectname) SPC %(objecttype) TAB %(refname)`. + It also interpolates `%%` to `%`, and `%xx` where `xx` + are hex digits interpolates to character with hex code + `xx`; for example `%00` interpolates to `\0` (NUL), + `%09` to `\t` (TAB) and `%0a` to `\n` (LF). + The fields are same as those in `git for-each-ref`. + CONFIGURATION - diff --git a/builtin/tag.c b/builtin/tag.c index 36f8019..601b293 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -30,10 +30,9 @@ static const char * const git_tag_usage[] = { static unsigned int colopts; -static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting) +static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, const char *format) { struct ref_array array; - char *format; int i; memset(array, 0, sizeof(array)); @@ -43,7 +42,7 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting) if (filter-lines) format = %(refname:shortalign=16); - else + else if (!format) format = %(refname:short); verify_ref_format(format); @@ -325,6 +324,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) struct strbuf err = STRBUF_INIT; struct ref_filter filter; static struct ref_sorting *sorting = NULL, **sorting_tail = sorting; + const char *format = NULL; struct option options[] = { OPT_CMDMODE('l', list, cmdmode, N_(list tag names), 'l'), { OPTION_INTEGER, 'n', NULL, filter.lines, N_(n), @@ -356,6 +356,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPTION_CALLBACK, 0, points-at, filter.points_at, N_(object), N_(print only tags of the object), 0, parse_opt_object_name }, + OPT_STRING( 0 , format, format, N_(format), N_(format to use for the output)), OPT_END() }; @@ -395,8 +396,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix) copts.padding = 2; run_column_filter(colopts, copts); } + if (format (filter.lines != -1)) + die(_(--format and -n are incompatible)); filter.name_patterns = argv; - ret = list_tags(filter, sorting); + ret = list_tags(filter, sorting, format); if (column_active(colopts)) stop_column_filter(); return ret; diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 51a233f..e8cebb6 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1507,4 +1507,20 @@ EOF test_cmp expect actual ' +test_expect_success '--format cannot be used with -n' ' + test_must_fail git tag -l -n4 --format=%(refname) +' + +test_expect_success '--format should list tags as per format given' ' + cat expect -\EOF + foo1.10 + foo1.3 + foo1.6 + foo1.6-rc1 + foo1.6-rc2 + EOF + git tag -l --format=%(refname) foo* actual + test_cmp expect actual +' + test_done -- 2.4.5 -- 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 v8 01/11] t6302: for-each-ref tests for ref-filter APIs
Add a test suite for testing the ref-filter APIs used by for-each-ref. We just intialize the test suite for now. More tests will be added in the following patches as more options are added to for-each-ref. Based-on-patch-by: Jeff King p...@peff.net Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- t/t6302-for-each-ref-filter.sh | 26 ++ 1 file changed, 26 insertions(+) create mode 100755 t/t6302-for-each-ref-filter.sh diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh new file mode 100755 index 000..ae75116 --- /dev/null +++ b/t/t6302-for-each-ref-filter.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +test_description='test for-each-refs usage of ref-filter APIs' + +. ./test-lib.sh +. $TEST_DIRECTORY/lib-gpg.sh + +if ! test_have_prereq GPG +then + skip_all=skipping for-each-ref tests, GPG not available + test_done +fi + +test_expect_success 'setup some history and refs' ' + test_commit one + test_commit two + test_commit three + git checkout -b side + test_commit four + git tag -s -m A signed tag message signed-tag + git tag -s -m Annonated doubly double-tag signed-tag + git checkout master + git update-ref refs/odd/spot master +' + +test_done -- 2.4.5 -- 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 v4] log: add log.follow config option
David Turner dtur...@twopensource.com writes: This version uses tweak, and also includes Matthieu Moy's suggested whitespace fix. This comment should come below the --- after the commit message (right before the diffstat). Otherwise, Junio will get this as the commit message when applying, and your actual commit message will be ignored. --- Many users prefer to always use --follow with logs. Rather than aliasing the command, an option might be more convenient for some. Junio C Hamano gits...@pobox.com suggested using the tweak functionality for this, which is much nicer than what I had before. I would avoid using what I had before in the commit message: readers of git log do not know what you had before. OTOH, crediting Junio for the idea is good. Signed-off-by: David Turner dtur...@twopensource.com --- (This is the place for comments) Documentation/git-log.txt | 6 ++ builtin/log.c | 16 diff.c| 5 +++-- diff.h| 1 + t/t4202-log.sh| 23 +++ 5 files changed, 49 insertions(+), 2 deletions(-) -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- 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 v5 00/44] Make git-am a builtin
Paul Tan pyoka...@gmail.com writes: So the fix would be to remove the assert()s, as follows: What I pushed out tonight should have SQUASH??? (or fixup!) that splits this into appropriate steps in your series. Please check. Note that you do not have to say if the variable has something, then free it. free(NULL) is perfectly fine and we can read free(var); var = compute_new_value(); just fine. However, I am reluctant to blindly replace assert(!state-field) with free(state-field). Are there cases where we _must_ call a function that sets these fields at most once? On the other hand, assert() like this is more or less useless. assert(state-field); ... printf(%s, state-field); /* or other uses */ The caller must have filled the field can be seen by unconditional use of state-field without such an assert(). -- 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 v6 1/7] refs.c: add err arguments to reflog functions
On 07/08/2015 07:11 PM, Junio C Hamano wrote: Michael Haggerty mhag...@alum.mit.edu writes: I think your v7 of this patch goes too far, by turning a failure to write to the reflog into a failure of the whole transaction. The problem is that this failure comes too late, in the commit phase of the transaction. Aborting at this late stage can leave some references changed and others rolled back, violating the promise of atomicity. Yeah, that sounds problematic. The old code reported a failure to write the reflog to stderr but didn't fail the transaction. I think that behavior is more appropriate. The reflog is of lower importance than the references themselves. Junio, do you agree? That is actually a loaded question. Do I agree that the current (i.e. before this change) behaviour is more appropriate given the current choice of representation of refs and reflogs on the filesystem, treating a failure to update reflog as lower importance event and accept it as a limitation that it cannot abort the whole transaction atomically? Compared to leaving the repository in a half-updated state where some refs and their logs are updated already, other remaining proposed updates are ignored, and the transaction claims to have failed even though some things have already changed and we cannot rollback, I would say that is a better compromise to treat reflog update as a lower importance. Do I agree that reflog writing should stay to be best-effort in the longer term? Not really. If we are moving the ref API in the direction where we can plug a backend that is different from the traditional filesystem based one for storing refs, I think the backend should also be responsible for storing logs for the refs it stores, and if the backend wants to promise atomicity, then we should be able to fail the whole transaction when updates to refs could proceed but updates to the log of one of these updated refs cannot. So I do not agree to cast in stone the reflog is of lower importance as a general rule. Junio, You make a good distinction. I was describing a compromise that we have to make now due to the limitations of the current ref/reflog backend. But I agree 100% that a future storage backend that can do correct rollback of refs *and* reflogs can fail a transaction if the reflog updates cannot be committed. Thanks, Michael -- Michael Haggerty mhag...@alum.mit.edu -- 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] fast-import: Do less work when given from matches current branch head
When building a fast-import stream, it's easy to forget the fact that for non-merge commits happening on top of the current branch head, there is no need for a from command. That is corroborated by the fact that at least git-p4, hg-fast-export and felipec's git-remote-hg all unconditionally use a from command. Unfortunately, giving a from command always resets the branch tree, forcing it to be re-read, and in many cases, the pack is also closed and reopened through gfi_unpack_entry. Both are extra unwanted overhead, and the latter is particularly slow at least on OSX. So, avoid resetting the tree when it's unmodified, and avoid calling gfi_unpack_entry when the given mark points to the same commit as the current branch head. Signed-off-by: Mike Hommey m...@glandium.org --- fast-import.c | 29 + 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/fast-import.c b/fast-import.c index e78ca10..372d63a 100644 --- a/fast-import.c +++ b/fast-import.c @@ -2588,14 +2588,12 @@ static int parse_from(struct branch *b) { const char *from; struct branch *s; + unsigned char sha1[20]; if (!skip_prefix(command_buf.buf, from , from)) return 0; - if (b-branch_tree.tree) { - release_tree_content_recursive(b-branch_tree.tree); - b-branch_tree.tree = NULL; - } + hashcpy(sha1, b-branch_tree.versions[1].sha1); s = lookup_branch(from); if (b == s) @@ -2610,14 +2608,16 @@ static int parse_from(struct branch *b) struct object_entry *oe = find_mark(idnum); if (oe-type != OBJ_COMMIT) die(Mark :% PRIuMAX not a commit, idnum); - hashcpy(b-sha1, oe-idx.sha1); - if (oe-pack_id != MAX_PACK_ID) { - unsigned long size; - char *buf = gfi_unpack_entry(oe, size); - parse_from_commit(b, buf, size); - free(buf); - } else - parse_from_existing(b); + if (hashcmp(b-sha1, oe-idx.sha1)) { + hashcpy(b-sha1, oe-idx.sha1); + if (oe-pack_id != MAX_PACK_ID) { + unsigned long size; + char *buf = gfi_unpack_entry(oe, size); + parse_from_commit(b, buf, size); + free(buf); + } else + parse_from_existing(b); + } } else if (!get_sha1(from, b-sha1)) { parse_from_existing(b); if (is_null_sha1(b-sha1)) @@ -2626,6 +2626,11 @@ static int parse_from(struct branch *b) else die(Invalid ref name or SHA1 expression: %s, from); + if (b-branch_tree.tree hashcmp(sha1, b-branch_tree.versions[1].sha1)) { + release_tree_content_recursive(b-branch_tree.tree); + b-branch_tree.tree = NULL; + } + read_next_command(); return 1; } -- 2.4.3.2.gf0a024e.dirty -- 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 v5 1/4] implement submodule config API for lookup of .gitmodules values
On Wed, Jul 08, 2015 at 04:52:14PM -0400, Phil Hord wrote: On Mon, Jun 15, 2015 at 5:06 PM, Heiko Voigt hvo...@hvoigt.net wrote: In a superproject some commands need to interact with submodules. They need to query values from the .gitmodules file either from the worktree of from certain revisions. At the moment this is quite hard since a caller would need to read the .gitmodules file from the history and then parse the values. We want to provide an API for this so we have one place to get values from .gitmodules from any revision (including the worktree). The API is realized as a cache which allows us to lazily read .gitmodules configurations by commit into a runtime cache which can then be used to easily lookup values from it. Currently only the values for path or name are stored but it can be extended for any value needed. It is expected that .gitmodules files do not change often between commits. Thats why we lookup the .gitmodules sha1 from a commit and then either lookup an already parsed configuration or parse and cache an unknown one for each sha1. The cache is lazily build on demand for each requested commit. This cache can be used for all purposes which need knowledge about submodule configurations. Example use cases are: * Recursive submodule checkout needs to lookup a submodule name from its path when a submodule first appears. This needs be done before this configuration exists in the worktree. * The implementation of submodule support for 'git archive' needs to lookup the submodule name to generate the archive when given a revision that is not checked out. * 'git fetch' when given the --recurse-submodules=on-demand option (or configuration) needs to lookup submodule names by path from the database rather than reading from the worktree. For new submodule it needs to lookup the name from its path to allow cloning new submodules into the .git folder so they can be checked out without any network interaction when the user does a checkout of that revision. Signed-off-by: Heiko Voigt hvo...@hvoigt.net --- .gitignore | 1 + Documentation/technical/api-submodule-config.txt | 46 +++ Makefile | 2 + submodule-config.c | 445 +++ submodule-config.h | 27 ++ submodule.c | 1 + submodule.h | 1 + t/t7411-submodule-config.sh | 85 + test-submodule-config.c | 66 9 files changed, 674 insertions(+) create mode 100644 Documentation/technical/api-submodule-config.txt create mode 100644 submodule-config.c create mode 100644 submodule-config.h create mode 100755 t/t7411-submodule-config.sh create mode 100644 test-submodule-config.c Instead of test-submodule-config.c to test this new module, it could be useful to implement these as extensions to rev-parse: git rev-parse --submodule-name [ref:]path git rev-parse --submodule-path [ref:]name git rev-parse --submodule-url [ref:]name git rev-parse --submodule-ignore [ref:]name git rev-parse --submodule-recurse [ref:]name Has this already been considered and rejected for some reason? No that has not been considered. But I am open to it if others agree that this is a sensible thing to do. We should be able to adapt the existing tests right? Cheers Heiko -- 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 06/10] Documentation/tag: remove double occurance of pattern
On Thu, Jul 9, 2015 at 12:27 PM, Karthik Nayak karthik@gmail.com wrote: Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- Documentation/git-tag.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 034d10d..4b04c2b 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -14,7 +14,6 @@ SYNOPSIS 'git tag' -d tagname... 'git tag' [-n[num]] -l [--contains commit] [--points-at object] [--column[=options] | --no-column] [pattern...] - [pattern...] 'git tag' -v tagname... As this patch could be applied directly to master and to maint maybe you could send it at the top of this patch series or alone outside of this patch series. -- 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 00/10] Port tag.c to use ref-filter APIs
This is part of my GSoC project to unify git tag -l, git branch -l, git for-each-ref This patch series is continued from: http://article.gmane.org/gmane.comp.version-control.git/273569 The previous RFC version is here: http://thread.gmane.org/gmane.comp.version-control.git/272654 Changes in this version: * Cleanup Documentation/tag * Fixed grammatical errors * Fixed a small merge conflict * Other small changes Documentation/git-tag.txt | 39 ++--- builtin/for-each-ref.c| 3 +- builtin/tag.c | 368 ref-filter.c | 95 -- ref-filter.h | 7 ++- t/t7004-tag.sh| 51 +--- 6 files changed, 234 insertions(+), 329 deletions(-) -- Regards, Karthik Nayak -- 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 01/10] ref-filter: add %(refname:shortalign=X) option
Add support for %(refname:shortalign=X) where X is a number. This will print a shortened refname aligned to the left followed by spaces for a total length of X characters. If X is less than the shortened refname size, the entire shortened refname is printed. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- ref-filter.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/ref-filter.c b/ref-filter.c index dd0709d..3098497 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -10,6 +10,7 @@ #include quote.h #include ref-filter.h #include revision.h +#include utf8.h typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type; @@ -695,7 +696,23 @@ static void populate_value(struct ref_array_item *ref) int num_ours, num_theirs; formatp++; - if (!strcmp(formatp, short)) + if (starts_with(formatp, shortalign=)) { + const char *valp, *short_refname = NULL; + int val, len; + + skip_prefix(formatp, shortalign=, valp); + val = atoi(valp); + refname = short_refname = shorten_unambiguous_ref(refname, + warn_ambiguous_refs); + len = utf8_strwidth(refname); + if (val len) { + struct strbuf buf = STRBUF_INIT; + strbuf_addstr(buf, refname); + strbuf_addchars(buf, ' ', val - len); + free((char *)short_refname); + refname = strbuf_detach(buf, NULL); + } + } else if (!strcmp(formatp, short)) refname = shorten_unambiguous_ref(refname, warn_ambiguous_refs); else if (!strcmp(formatp, track) -- 2.4.5 -- 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 03/10] ref-filter: support printing N lines from tag annotation
In 'tag.c' we can print N lines from the annotation of the tag using the '-nnum' option. Copy code from 'tag.c' to 'ref-filter' and modify 'ref-filter' to support printing of N lines from the annotation of tags. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- builtin/for-each-ref.c | 2 +- builtin/tag.c | 4 ref-filter.c | 48 +++- ref-filter.h | 3 ++- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 40f343b..e4a4f8a 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -74,7 +74,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) if (!maxcount || array.nr maxcount) maxcount = array.nr; for (i = 0; i maxcount; i++) - show_ref_array_item(array.items[i], format, quote_style); + show_ref_array_item(array.items[i], format, quote_style, 0); ref_array_clear(array); return 0; } diff --git a/builtin/tag.c b/builtin/tag.c index 071d001..3b6a6cc 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -185,6 +185,10 @@ static enum contains_result contains(struct commit *candidate, return contains_test(candidate, want); } +/* + * Currently dupplicated in ref-filter, will eventually be removed as + * we port tag.c to use ref-filter APIs. + */ static void show_tag_lines(const struct object_id *oid, int lines) { int i; diff --git a/ref-filter.c b/ref-filter.c index e690177..1b088b1 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -1273,7 +1273,48 @@ static void emit(const char *cp, const char *ep) } } -void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style) +/* Print 'lines' no of lines of a given oid */ +static void show_tag_lines(const struct object_id *oid, int lines) +{ + int i; + unsigned long size; + enum object_type type; + char *buf, *sp, *eol; + size_t len; + + buf = read_sha1_file(oid-hash, type, size); + if (!buf) + die_errno(unable to read object %s, oid_to_hex(oid)); + if (type != OBJ_COMMIT type != OBJ_TAG) + goto free_return; + if (!size) + die(an empty %s object %s?, + typename(type), oid_to_hex(oid)); + + /* skip header */ + sp = strstr(buf, \n\n); + if (!sp) + goto free_return; + + /* only take up to lines lines, and strip the signature from a tag */ + if (type == OBJ_TAG) + size = parse_signature(buf, size); + for (i = 0, sp += 2; i lines sp buf + size; i++) { + if (i) + printf(\n); + eol = memchr(sp, '\n', size - (sp - buf)); + len = eol ? eol - sp : size - (sp - buf); + fwrite(sp, len, 1, stdout); + if (!eol) + break; + sp = eol + 1; + } +free_return: + free(buf); +} + +void show_ref_array_item(struct ref_array_item *info, const char *format, +int quote_style, unsigned int lines) { const char *cp, *sp, *ep; @@ -1299,6 +1340,11 @@ void show_ref_array_item(struct ref_array_item *info, const char *format, int qu resetv.s = color; print_value(resetv, quote_style); } + if (lines 0) { + struct object_id oid; + hashcpy(oid.hash, info-objectname); + show_tag_lines(oid, lines); + } putchar('\n'); } diff --git a/ref-filter.h b/ref-filter.h index 449ddb8..5247475 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -55,6 +55,7 @@ struct ref_filter { struct commit *merge_commit; unsigned int with_commit_tag_algo : 1; + unsigned int lines; }; struct ref_filter_cbdata { @@ -87,7 +88,7 @@ int verify_ref_format(const char *format); /* Sort the given ref_array as per the ref_sorting provided */ void ref_array_sort(struct ref_sorting *sort, struct ref_array *array); /* Print the ref using the given format and quote_style */ -void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style); +void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style, unsigned int lines); /* Callback function for parsing the sort option */ int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset); /* Default sort option based on refname */ -- 2.4.5 -- 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 05/10] ref-filter: add option to match literal pattern
Since 'ref-filter' only has an option to match path names add an option for regular pattern matching. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- builtin/for-each-ref.c | 1 + ref-filter.c | 25 - ref-filter.h | 3 ++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index e4a4f8a..3ad6a64 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -68,6 +68,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) git_config(git_default_config, NULL); filter.name_patterns = argv; + filter.match_as_path = 1; filter_refs(array, filter, FILTER_REFS_ALL | FILTER_REFS_INCLUDE_BROKEN); ref_array_sort(sorting, array); diff --git a/ref-filter.c b/ref-filter.c index 1516cd1..0e19f44 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -956,6 +956,20 @@ static int commit_contains(struct ref_filter *filter, struct commit *commit) /* * Return 1 if the refname matches one of the patterns, otherwise 0. + * A pattern can be a literal prefix (e.g. a refname refs/heads/master + * matches a pattern refs/heads/m) or a wildcard (e.g. the same ref + * matches refs/heads/m*,too). + */ +static int match_pattern(const char **patterns, const char *refname) +{ + for (; *patterns; patterns++) + if (!wildmatch(*patterns, refname, 0, NULL)) + return 1; + return 0; +} + +/* + * Return 1 if the refname matches one of the patterns, otherwise 0. * A pattern can be path prefix (e.g. a refname refs/heads/master * matches a pattern refs/heads/) or a wildcard (e.g. the same ref * matches refs/heads/m*,too). @@ -979,6 +993,15 @@ static int match_name_as_path(const char **pattern, const char *refname) return 0; } +static int filter_pattern_match(struct ref_filter *filter, const char *refname) +{ + if (!*filter-name_patterns) + return 1; + if (filter-match_as_path) + return match_name_as_path(filter-name_patterns, refname); + return match_pattern(filter-name_patterns, refname); +} + /* * Given a ref (sha1, refname), check if the ref belongs to the array * of sha1s. If the given ref is a tag, check if the given tag points @@ -1047,7 +1070,7 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid, return 0; } - if (*filter-name_patterns !match_name_as_path(filter-name_patterns, refname)) + if (!filter_pattern_match(filter, refname)) return 0; if (filter-points_at.nr !match_points_at(filter-points_at, oid-hash, refname)) diff --git a/ref-filter.h b/ref-filter.h index 5247475..633108c 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -54,7 +54,8 @@ struct ref_filter { } merge; struct commit *merge_commit; - unsigned int with_commit_tag_algo : 1; + unsigned int with_commit_tag_algo : 1, + match_as_path : 1; unsigned int lines; }; -- 2.4.5 -- 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 07/10] tag.c: use 'ref-filter' data structures
Make 'tag.c' use 'ref-filter' data structures and make changes to support the new data structures. This is a part of the process of porting 'tag.c' to use 'ref-filter' APIs. This is a temporary step before porting 'tag.c' to use 'ref-filter' completely. As this is a temporary step, most of the code introduced here will be removed when 'tag.c' is ported over to use 'ref-filter' APIs Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- builtin/tag.c | 106 +++--- 1 file changed, 57 insertions(+), 49 deletions(-) diff --git a/builtin/tag.c b/builtin/tag.c index 3b6a6cc..bbda0c6 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -17,6 +17,7 @@ #include gpg-interface.h #include sha1-array.h #include column.h +#include ref-filter.h static const char * const git_tag_usage[] = { N_(git tag [-a | -s | -u key-id] [-f] [-m msg | -F file] tagname [head]), @@ -34,15 +35,6 @@ static const char * const git_tag_usage[] = { static int tag_sort; -struct tag_filter { - const char **patterns; - int lines; - int sort; - struct string_list tags; - struct commit_list *with_commit; -}; - -static struct sha1_array points_at; static unsigned int colopts; static int match_pattern(const char **patterns, const char *ref) @@ -61,19 +53,20 @@ static int match_pattern(const char **patterns, const char *ref) * removed as we port tag.c to use the ref-filter APIs. */ static const unsigned char *match_points_at(const char *refname, - const unsigned char *sha1) + const unsigned char *sha1, + struct sha1_array *points_at) { const unsigned char *tagged_sha1 = NULL; struct object *obj; - if (sha1_array_lookup(points_at, sha1) = 0) + if (sha1_array_lookup(points_at, sha1) = 0) return sha1; obj = parse_object(sha1); if (!obj) die(_(malformed object at '%s'), refname); if (obj-type == OBJ_TAG) tagged_sha1 = ((struct tag *)obj)-tagged-sha1; - if (tagged_sha1 sha1_array_lookup(points_at, tagged_sha1) = 0) + if (tagged_sha1 sha1_array_lookup(points_at, tagged_sha1) = 0) return tagged_sha1; return NULL; } @@ -228,12 +221,24 @@ free_return: free(buf); } +static void ref_array_append(struct ref_array *array, const char *refname) +{ + size_t len = strlen(refname); + struct ref_array_item *ref = xcalloc(1, sizeof(struct ref_array_item) + len + 1); + memcpy(ref-refname, refname, len); + ref-refname[len] = '\0'; + REALLOC_ARRAY(array-items, array-nr + 1); + array-items[array-nr++] = ref; +} + static int show_reference(const char *refname, const struct object_id *oid, int flag, void *cb_data) { - struct tag_filter *filter = cb_data; + struct ref_filter_cbdata *data = cb_data; + struct ref_array *array = data-array; + struct ref_filter *filter = data-filter; - if (match_pattern(filter-patterns, refname)) { + if (match_pattern(filter-name_patterns, refname)) { if (filter-with_commit) { struct commit *commit; @@ -244,12 +249,12 @@ static int show_reference(const char *refname, const struct object_id *oid, return 0; } - if (points_at.nr !match_points_at(refname, oid-hash)) + if (filter-points_at.nr !match_points_at(refname, oid-hash, filter-points_at)) return 0; if (!filter-lines) { - if (filter-sort) - string_list_append(filter-tags, refname); + if (tag_sort) + ref_array_append(array, refname); else printf(%s\n, refname); return 0; @@ -264,36 +269,36 @@ static int show_reference(const char *refname, const struct object_id *oid, static int sort_by_version(const void *a_, const void *b_) { - const struct string_list_item *a = a_; - const struct string_list_item *b = b_; - return versioncmp(a-string, b-string); + const struct ref_array_item *a = *((struct ref_array_item **)a_); + const struct ref_array_item *b = *((struct ref_array_item **)b_); + return versioncmp(a-refname, b-refname); } -static int list_tags(const char **patterns, int lines, -struct commit_list *with_commit, int sort) +static int list_tags(struct ref_filter *filter, int sort) { - struct tag_filter filter; + struct ref_array array; + struct ref_filter_cbdata data; + +
[PATCH v2 04/10] ref-filter: add support to sort by version
Add support to sort by version using the v:refname and version:refname option. This is achieved by using the 'version_cmp()' function as the comparing function for qsort. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- ref-filter.c | 20 +--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index 1b088b1..1516cd1 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -11,8 +11,9 @@ #include ref-filter.h #include revision.h #include utf8.h +#include version.h -typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type; +typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME, FIELD_VER } cmp_type; static struct { const char *name; @@ -54,6 +55,8 @@ static struct { { flag }, { HEAD }, { color }, + { version, FIELD_VER }, + { v, FIELD_VER }, }; /* @@ -630,7 +633,9 @@ static void populate_value(struct ref_array_item *ref) name++; } - if (starts_with(name, refname)) + if (starts_with(name, refname) || + starts_with(name, version:) || + starts_with(name, v:)) refname = ref-refname; else if (starts_with(name, symref)) refname = ref-symref ? ref-symref : ; @@ -696,7 +701,13 @@ static void populate_value(struct ref_array_item *ref) int num_ours, num_theirs; formatp++; - if (starts_with(formatp, shortalign=)) { + if (starts_with(name, version) || starts_with(name, v)) { + if (strcmp(formatp, refname)) + die(unknown %.*s format %s, + (int)(formatp - name), name, formatp); + v-s = refname; + continue; + } else if (starts_with(formatp, shortalign=)) { const char *valp, *short_refname = NULL; int val, len; @@ -1176,6 +1187,9 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru case FIELD_STR: cmp = strcmp(va-s, vb-s); break; + case FIELD_VER: + cmp = versioncmp(va-s, vb-s); + break; default: if (va-ul vb-ul) cmp = -1; -- 2.4.5 -- 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 02/10] ref-filter: add option to filter only tags
Add an option in 'filter_refs()' to use 'for_each_tag_ref()' and filter refs. This type checking is done by adding a 'FILTER_REFS_TAGS' in 'ref-filter.h' Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- ref-filter.c | 2 ++ ref-filter.h | 1 + 2 files changed, 3 insertions(+) diff --git a/ref-filter.c b/ref-filter.c index 3098497..e690177 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -1152,6 +1152,8 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int ret = for_each_rawref(ref_filter_handler, ref_cbdata); else if (type FILTER_REFS_ALL) ret = for_each_ref(ref_filter_handler, ref_cbdata); + else if (type FILTER_REFS_TAGS) + ret = for_each_tag_ref(ref_filter_handler, ref_cbdata); else if (type) die(filter_refs: invalid type); diff --git a/ref-filter.h b/ref-filter.h index 6bf27d8..449ddb8 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -15,6 +15,7 @@ #define FILTER_REFS_INCLUDE_BROKEN 0x1 #define FILTER_REFS_ALL 0x2 +#define FILTER_REFS_TAGS 0x4 struct atom_value { const char *s; -- 2.4.5 -- 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 01/10] ref-filter: add %(refname:shortalign=X) option
Karthik Nayak karthik@gmail.com writes: Add support for %(refname:shortalign=X) where X is a number. This will print a shortened refname aligned to the left followed by spaces for a total length of X characters. If X is less than the shortened refname size, the entire shortened refname is printed. Not really an issue, but you're wrapping your text at ~60 characters. The common use is to wrap around 70 to 80. Using Emacs, auto-fill-mode or M-q does this automatically. If you use another text editor, it can probably do that for you too. Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- ref-filter.c | 19 ++- I think this would deserve a test and documentation. Even though your motivation is for an internal implementation, some users may want to use the feature in 'git for-each-ref --format=...'. 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/ref-filter.c b/ref-filter.c index dd0709d..3098497 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -10,6 +10,7 @@ #include quote.h #include ref-filter.h #include revision.h +#include utf8.h typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type; @@ -695,7 +696,23 @@ static void populate_value(struct ref_array_item *ref) int num_ours, num_theirs; formatp++; - if (!strcmp(formatp, short)) + if (starts_with(formatp, shortalign=)) { + const char *valp, *short_refname = NULL; + int val, len; + + skip_prefix(formatp, shortalign=, valp); + val = atoi(valp); You're silently accepting %(refname:shortalign=foo) and %(refname:shortalign=). I think it would be better to reject such cases explicitly. -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- 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 03/10] ref-filter: support printing N lines from tag annotation
Karthik Nayak karthik@gmail.com writes: In 'tag.c' we can print N lines from the annotation of the tag using the '-nnum' option. Not only annotation of the tag, but also from the commit message for lightweight tags. --- a/builtin/tag.c +++ b/builtin/tag.c @@ -185,6 +185,10 @@ static enum contains_result contains(struct commit *candidate, return contains_test(candidate, want); } +/* + * Currently dupplicated in ref-filter, will eventually be removed as dupplicated - duplicated. --- a/ref-filter.h +++ b/ref-filter.h @@ -55,6 +55,7 @@ struct ref_filter { struct commit *merge_commit; unsigned int with_commit_tag_algo : 1; + unsigned int lines; }; struct ref_filter_cbdata { @@ -87,7 +88,7 @@ int verify_ref_format(const char *format); /* Sort the given ref_array as per the ref_sorting provided */ void ref_array_sort(struct ref_sorting *sort, struct ref_array *array); /* Print the ref using the given format and quote_style */ -void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style); +void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style, unsigned int lines); I would add If lines 0, prints the first 'lines' no of lines of the object pointed to or so to the docstring. -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- 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/10] tag.c: use 'ref-filter' APIs
Karthik Nayak karthik@gmail.com writes: Documentation/git-tag.txt | 16 ++- builtin/tag.c | 343 ++ t/t7004-tag.sh| 8 +- This patch was sent with Thunderbird unlike the others in the series. It has some line wrapping which make it unapplicable. -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- 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/10] tag.c: use 'ref-filter' APIs
On Thu, Jul 9, 2015 at 6:18 PM, Matthieu Moy matthieu@grenoble-inp.fr wrote: Karthik Nayak karthik@gmail.com writes: Documentation/git-tag.txt | 16 ++- builtin/tag.c | 343 ++ t/t7004-tag.sh| 8 +- This patch was sent with Thunderbird unlike the others in the series. It has some line wrapping which make it unapplicable. -- Matthieu Moy http://www-verimag.imag.fr/~moy/ Yes, 'git send-email' started failing, hence 08/10, 09/10 and 10/10 were sent by thunderbird. I'm trying to figure out why. If anyone can help, this is what it's saying. [Net::SMTP::SSL] Connection closed at /usr/lib/git-core/git-send-email line 1320. fatal: 'send-email' appears to be a git command, but we were not able to execute it. Maybe git-send-email is broken? -- Regards, Karthik Nayak -- 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 06/10] Documentation/tag: remove double occurance of pattern
On Thu, Jul 9, 2015 at 5:49 PM, Christian Couder christian.cou...@gmail.com wrote: On Thu, Jul 9, 2015 at 12:27 PM, Karthik Nayak karthik@gmail.com wrote: Mentored-by: Christian Couder christian.cou...@gmail.com Mentored-by: Matthieu Moy matthieu@grenoble-inp.fr Signed-off-by: Karthik Nayak karthik@gmail.com --- Documentation/git-tag.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 034d10d..4b04c2b 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -14,7 +14,6 @@ SYNOPSIS 'git tag' -d tagname... 'git tag' [-n[num]] -l [--contains commit] [--points-at object] [--column[=options] | --no-column] [pattern...] - [pattern...] 'git tag' -v tagname... As this patch could be applied directly to master and to maint maybe you could send it at the top of this patch series or alone outside of this patch series. I'll do that :) -- Regards, Karthik Nayak -- 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/10] ref-filter: add support to sort by version
Karthik Nayak karthik@gmail.com writes: Add support to sort by version using the v:refname and version:refname option. This is achieved by using the 'version_cmp()' function as the comparing function for qsort. You should elaborate on why you need this. Given the context, I can guess that you will need this to implement tag, but for example I first wondered why you needed both version: and v:, but I guess it comes from the fact that 'git tag --sort' can take version:refname or v:refname. I think this deserves a test and documentation in for-each-ref.txt. As-is, the code is a bit hard to understand. I first saw you were allowing git for-each-ref --format '%(version:refname)' (which you are, but only as a side effect), and then understood that this was also allowing git for-each-ref --sort version:refname A test would have shown me this immediately. Some hints in the commit message would clearly have helped too. -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- 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 05/10] ref-filter: add option to match literal pattern
Karthik Nayak karthik@gmail.com writes: Since 'ref-filter' only has an option to match path names add an option for regular pattern matching. Here also, a hint on why this is needed would be welcome. --- a/ref-filter.c +++ b/ref-filter.c @@ -956,6 +956,20 @@ static int commit_contains(struct ref_filter *filter, struct commit *commit) /* * Return 1 if the refname matches one of the patterns, otherwise 0. + * A pattern can be a literal prefix (e.g. a refname refs/heads/master + * matches a pattern refs/heads/m) or a wildcard (e.g. the same ref + * matches refs/heads/m*,too). Missing space after , (same in the hunk context below) -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- 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/10] tag.c: use 'ref-filter' APIs
Karthik Nayak karthik@gmail.com writes: + s-atom = parse_ref_filter_atom(arg, arg+len); Spaces around +. -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- 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/10] tag.c: use 'ref-filter' APIs
Karthik Nayak karthik@gmail.com writes: If anyone can help, this is what it's saying. [Net::SMTP::SSL] Connection closed at Perhaps your SMTP server thought you were sending too many emails to too many people and closed the connection thinking you were a spammer. If you're having this kind of issues, it may make sense to run format-patch and send-email as two separate steps. This way, you can re-run send-email on the pieces which failed manually (adjusting --in-reply-to). -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- 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: git svn timezone issue?
On Do, 2015-07-09 at 15:28 +0200, Stefan Tatschner wrote: Hi, at work we use svn, so I used git svn to import that stuff to git. Now it seems that there are some timezone issues. git log shows + as timezone, while git svn log shows the correct timezone +0200. Ok, I just discovered the --localtime switch in the manpage. Sorry for the noise! Thanks, Stefan -- 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
git svn timezone issue?
Hi, at work we use svn, so I used git svn to import that stuff to git. Now it seems that there are some timezone issues. git log shows + as timezone, while git svn log shows the correct timezone +0200. $ git log -1 commit ceb8a8647e257d6caf2ad0ecc2298f8b269c9727 Author: John Doe j...@doe.com Date: Thu Jul 9 12:05:22 2015 + $ git svn log -1 --- r1967 | doe | 2015-07-09 14:05:22 +0200 (Do, 09 Jul 2015) | 2 lines $ git --version git version 2.4.5 $ git svn --version git-svn version 2.4.5 (svn 1.8.13) Any ideas? Thanks, Stefan -- 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] fast-import: Do less work when given from matches current branch head
Mike Hommey m...@glandium.org writes: Cc'ed a few people who appear at the top of shortlog --no-merges; I think the end result is not incorrect, but I want to hear second opinions on this one. I do not know Shawn still remembers this code, but what is under discussion seems to have come mostly from ea5e370a (fast-import: Support reusing 'from' and brown paper bag fix reset., 2007-02-12). if (!skip_prefix(command_buf.buf, from , from)) return 0; - if (b-branch_tree.tree) { - release_tree_content_recursive(b-branch_tree.tree); - b-branch_tree.tree = NULL; - } + hashcpy(sha1, b-branch_tree.versions[1].sha1); s = lookup_branch(from); if (b == s) The part that deals with a branch that is different from the current one is not visible in the context (i.e. when s = lookup_branch(from) returned a non-NULL result that is different from b) but it used to, and continues to with this patch, copy sha1 from branch_tree.sha1 and branch_tree.versions[] from sha1 and branch_tree.versions[1] of the specified branch. That codepath used to release the contents of branch_tree.tree when it did so, but it no longer does so after this patch because of the removal we see above. Does that mean the original code was doing a release that was unnecessary? Or does it mean this patch changes what happens on that codepath, namely (1) leaking resource, and/or (2) keeping a tree of the original 'b' that does not have anything to do with the tree of 's', preventing the later lazy-load code from reading the tree of 's' and instead of building on top of a wrong tree content? ... me goes and reads on ... @@ -2610,14 +2608,16 @@ static int parse_from(struct branch *b) struct object_entry *oe = find_mark(idnum); if (oe-type != OBJ_COMMIT) die(Mark :% PRIuMAX not a commit, idnum); - hashcpy(b-sha1, oe-idx.sha1); - if (oe-pack_id != MAX_PACK_ID) { - unsigned long size; - char *buf = gfi_unpack_entry(oe, size); - parse_from_commit(b, buf, size); - free(buf); - } else - parse_from_existing(b); + if (hashcmp(b-sha1, oe-idx.sha1)) { + hashcpy(b-sha1, oe-idx.sha1); + if (oe-pack_id != MAX_PACK_ID) { + unsigned long size; + char *buf = gfi_unpack_entry(oe, size); + parse_from_commit(b, buf, size); + free(buf); + } else + parse_from_existing(b); + } } else if (!get_sha1(from, b-sha1)) { parse_from_existing(b); if (is_null_sha1(b-sha1)) This part is straight-forward. @@ -2626,6 +2626,11 @@ static int parse_from(struct branch *b) else die(Invalid ref name or SHA1 expression: %s, from); + if (b-branch_tree.tree hashcmp(sha1, b-branch_tree.versions[1].sha1)) { + release_tree_content_recursive(b-branch_tree.tree); + b-branch_tree.tree = NULL; + } + This looks like an attempt to compensate for that what happens if (s != NULL s != b)? issue, and also for the surviving codepaths. As both parse_from_commit() and parse_from_existing() only touch branch_tree.versions[] and they do not seem to get affected if b-branch_tree.tree holds a stale and unrelated content, this looks OK to me from a cursory reading, but it does make me feel dirty that it has to put *b temporarily into an inconsistent state. -- 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
Merge after rename
I'm trying to cherry pick an old change from an old branch onto the current master, and since the old change, the directory structure was altered and the modified files were moved. Instead of detecting the new location of the file and applying the changes to it, git is re-adding the old file at the old location in its entirety. How can I get it to correctly notice the rename and merge the changes in at the file's new location? -- 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] check_and_freshen_file: fix reversed success-check
Am 08.07.2015 um 23:03 schrieb Johannes Sixt: Am 08.07.2015 um 20:33 schrieb Jeff King: ...or maybe in the utime() step there is actually a bug, and we report failure for no good reason. Ugh. Ah! That code is less than a year old. When I began to adopt a workflow requiring force-pushes lately, I wondered why I haven't seen these failures earlier, because I did do force pushes in the past, but not that frequently. I thought that I had just been lucky. But this would explain it. And, in fact, with this patch these particular failures are gone! Thank you so much! -- Hannes -- 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 v4] clone: simplify string handling in guess_dir_name()
Sebastian Schuberth sschube...@gmail.com writes: - if (is_bare) { - struct strbuf result = STRBUF_INIT; - strbuf_addf(result, %.*s.git, (int)(end - start), start); - dir = strbuf_detach(result, NULL); - } else + if (is_bare) + dir = xstrfmt(%.*s.git, (int)len, start); + else dir = xstrndup(start, end - start); The last one needs to be adjusted with s/end - start/len/. The last-minute rewrite without testing shows; your first two patches correctly used len ;-) No need to resend. Will locally tweak before queuing. Thanks. -- 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 v4] clone: simplify string handling in guess_dir_name()
On Thu, Jul 9, 2015 at 11:21 PM, Junio C Hamano gits...@pobox.com wrote: - if (is_bare) { - struct strbuf result = STRBUF_INIT; - strbuf_addf(result, %.*s.git, (int)(end - start), start); - dir = strbuf_detach(result, NULL); - } else + if (is_bare) + dir = xstrfmt(%.*s.git, (int)len, start); + else dir = xstrndup(start, end - start); The last one needs to be adjusted with s/end - start/len/. The last-minute rewrite without testing shows; your first two patches correctly used len ;-) Doh, you're right, sorry for that. No need to resend. Will locally tweak before queuing. Thanks! -- Sebastian Schuberth -- 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 v5 1/4] implement submodule config API for lookup of .gitmodules values
Am 09.07.2015 um 17:49 schrieb Jeff King: On Thu, Jul 09, 2015 at 02:09:01PM +0200, Heiko Voigt wrote: Instead of test-submodule-config.c to test this new module, it could be useful to implement these as extensions to rev-parse: git rev-parse --submodule-name [ref:]path git rev-parse --submodule-path [ref:]name git rev-parse --submodule-url [ref:]name git rev-parse --submodule-ignore [ref:]name git rev-parse --submodule-recurse [ref:]name Has this already been considered and rejected for some reason? No that has not been considered. But I am open to it if others agree that this is a sensible thing to do. We should be able to adapt the existing tests right? How does git-submodule access this information? It looks like it just hits git config -f .gitmodules directly. Perhaps whatever interface is designed should be suitable for its use here (and if there really is no more interesting interface needed, then why is git config not good enough for other callers?). The git-submodule script doesn't need this and is fine using plain old git config, as by the time it is run the .gitmodules file is already updated in the work tree. Heiko's series is about adding infrastructure to allow builtins like checkout and friends to access the configuration values from the .gitmodules file of the to-be-checked-out commit when run with --recurse-submodules. And yes, if we want to expose this functionality to users or scripts some day git config looks like the best place to do that to me too. -- 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 v5 1/4] implement submodule config API for lookup of .gitmodules values
Jens Lehmann jens.lehm...@web.de writes: How does git-submodule access this information? It looks like it just hits git config -f .gitmodules directly. Perhaps whatever interface is designed should be suitable for its use here (and if there really is no more interesting interface needed, then why is git config not good enough for other callers?). The git-submodule script doesn't need this and is fine using plain old git config, as by the time it is run the .gitmodules file is already updated in the work tree. Heiko's series is about adding infrastructure to allow builtins like checkout and friends to access the configuration values from the .gitmodules file of the to-be-checked-out commit when run with --recurse-submodules. And yes, if we want to expose this functionality to users or scripts some day git config looks like the best place to do that to me too. Did you mean git submodule config? -- 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] fast-import: Do less work when given from matches current branch head
Mike Hommey m...@glandium.org writes: Does that mean the original code was doing a release that was unnecessary? Or does it mean this patch changes what happens on that codepath, namely (1) leaking resource, and/or (2) keeping a tree of the original 'b' that does not have anything to do with the tree of 's', preventing the later lazy-load code from reading the tree of 's' and instead of building on top of a wrong tree content? I guess the question is whether branch_tree.tree can be in a state that doesn't match that of branch_tree.versions[1].sha1. If not, then if s and b have the same branch_tree.versions[1].sha1 for some reason, then keeping the old branch_tree.tree makes no practical difference from resetting it. Except it skips the busy-work. Perhaps my comment was misleading. I _think_ the state at the end of this function (i.e. the latter hunk you added to the function makes the above issue I raised go away). It just made me feel uneasy to leave branch_tree.tree and branch_tree.versions[] in an inconsistent state inside this function, while it calls a few helper functions (hence my comment on the fact that they do not seem to be affected by this inconsistency). -- 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] fast-import: Do less work when given from matches current branch head
Junio C Hamano gits...@pobox.com writes: Mike Hommey m...@glandium.org writes: Does that mean the original code was doing a release that was unnecessary? Or does it mean this patch changes what happens on that codepath, namely (1) leaking resource, and/or (2) keeping a tree of the original 'b' that does not have anything to do with the tree of 's', preventing the later lazy-load code from reading the tree of 's' and instead of building on top of a wrong tree content? I guess the question is whether branch_tree.tree can be in a state that doesn't match that of branch_tree.versions[1].sha1. If not, then if s and b have the same branch_tree.versions[1].sha1 for some reason, then keeping the old branch_tree.tree makes no practical difference from resetting it. Except it skips the busy-work. Perhaps my comment was misleading. I _think_ the state at the end of this function (i.e. the latter hunk you added to the function makes the above issue I raised go away). It just made me feel s/this function (/this function is good (/; uneasy to leave branch_tree.tree and branch_tree.versions[] in an inconsistent state inside this function, while it calls a few helper functions (hence my comment on the fact that they do not seem to be affected by this inconsistency). -- 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] check_and_freshen_file: fix reversed success-check
On Thu, Jul 09, 2015 at 10:51:50PM +0200, Johannes Sixt wrote: Ah! That code is less than a year old. When I began to adopt a workflow requiring force-pushes lately, I wondered why I haven't seen these failures earlier, because I did do force pushes in the past, but not that frequently. I thought that I had just been lucky. But this would explain it. And, in fact, with this patch these particular failures are gone! Thank you so much! Great, thanks for testing. You can temper your appreciation by noticing that I introduced the bug in the first place. ;) -Peff -- 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 v8 1/7] refs.c: add err arguments to reflog functions
Add an err argument to log_ref_setup that can explain the reason for a failure. This then eliminates the need to manage errno through this function since we can just add strerror(errno) to the err string when meaningful. No callers relied on errno from this function for anything else than the error message. Also add err arguments to private functions write_ref_to_lockfile, log_ref_write_1, commit_ref_update. This again eliminates the need to manage errno in these functions. Some error messages are slightly reordered. Update of a patch by Ronnie Sahlberg. Signed-off-by: Ronnie Sahlberg sahlb...@google.com Signed-off-by: David Turner dtur...@twopensource.com --- builtin/checkout.c | 8 ++-- refs.c | 127 +++-- refs.h | 4 +- 3 files changed, 81 insertions(+), 58 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index c018ab3..93f63d3 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -624,16 +624,18 @@ static void update_refs_for_switch(const struct checkout_opts *opts, struct strbuf log_file = STRBUF_INIT; int ret; const char *ref_name; + struct strbuf err = STRBUF_INIT; ref_name = mkpath(refs/heads/%s, opts-new_orphan_branch); temp = log_all_ref_updates; log_all_ref_updates = 1; - ret = log_ref_setup(ref_name, log_file); + ret = log_ref_setup(ref_name, log_file, err); log_all_ref_updates = temp; strbuf_release(log_file); if (ret) { - fprintf(stderr, _(Can not do reflog for '%s'\n), - opts-new_orphan_branch); + fprintf(stderr, _(Can not do reflog for '%s'. %s\n), + opts-new_orphan_branch, err.buf); + strbuf_release(err); return; } } diff --git a/refs.c b/refs.c index fb568d7..03e7505 100644 --- a/refs.c +++ b/refs.c @@ -2975,9 +2975,11 @@ static int rename_ref_available(const char *oldname, const char *newname) return ret; } -static int write_ref_to_lockfile(struct ref_lock *lock, const unsigned char *sha1); +static int write_ref_to_lockfile(struct ref_lock *lock, +const unsigned char *sha1, struct strbuf *err); static int commit_ref_update(struct ref_lock *lock, -const unsigned char *sha1, const char *logmsg); +const unsigned char *sha1, const char *logmsg, +struct strbuf *err); int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg) { @@ -3038,9 +3040,10 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms } hashcpy(lock-old_oid.hash, orig_sha1); - if (write_ref_to_lockfile(lock, orig_sha1) || - commit_ref_update(lock, orig_sha1, logmsg)) { - error(unable to write current sha1 into %s, newrefname); + if (write_ref_to_lockfile(lock, orig_sha1, err) || + commit_ref_update(lock, orig_sha1, logmsg, err)) { + error(unable to write current sha1 into %s: %s, newrefname, err.buf); + strbuf_release(err); goto rollback; } @@ -3056,9 +3059,11 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms flag = log_all_ref_updates; log_all_ref_updates = 0; - if (write_ref_to_lockfile(lock, orig_sha1) || - commit_ref_update(lock, orig_sha1, NULL)) - error(unable to write current sha1 into %s, oldrefname); + if (write_ref_to_lockfile(lock, orig_sha1, err) || + commit_ref_update(lock, orig_sha1, NULL, err)) { + error(unable to write current sha1 into %s: %s, oldrefname, err.buf); + strbuf_release(err); + } log_all_ref_updates = flag; rollbacklog: @@ -3113,8 +3118,8 @@ static int copy_msg(char *buf, const char *msg) return cp - buf; } -/* This function must set a meaningful errno on failure */ -int log_ref_setup(const char *refname, struct strbuf *sb_logfile) +/* This function will fill in *err and return -1 on failure */ +int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err) { int logfd, oflags = O_APPEND | O_WRONLY; char *logfile; @@ -3129,9 +3134,8 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile)
[PATCH v8 2/7] refs: Break out check for reflog autocreation
This is just for clarity. Signed-off-by: David Turner dtur...@twopensource.com --- refs.c | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/refs.c b/refs.c index 03e7505..903b401 100644 --- a/refs.c +++ b/refs.c @@ -3118,6 +3118,16 @@ static int copy_msg(char *buf, const char *msg) return cp - buf; } +static int should_autocreate_reflog(const char *refname) +{ + if (!log_all_ref_updates) + return 0; + return starts_with(refname, refs/heads/) || + starts_with(refname, refs/remotes/) || + starts_with(refname, refs/notes/) || + !strcmp(refname, HEAD); +} + /* This function will fill in *err and return -1 on failure */ int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err) { @@ -3128,11 +3138,7 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf logfile = sb_logfile-buf; /* make sure the rest of the function can't change logfile */ sb_logfile = NULL; - if (log_all_ref_updates - (starts_with(refname, refs/heads/) || -starts_with(refname, refs/remotes/) || -starts_with(refname, refs/notes/) || -!strcmp(refname, HEAD))) { + if (should_autocreate_reflog(refname)) { if (safe_create_leading_directories(logfile) 0) { strbuf_addf(err, unable to create directory for %s. %s, logfile, strerror(errno)); -- 2.0.5.499.g01f6352.dirty-twtrsrc -- 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 v8 0/7] ref backend preamble
The current state of the discussion on alternate ref backends is that we're going to continue to store pseudorefs (e.g. CHERRY_PICK_HEAD) as files in $GIT_DIR. So this re-roll of the refs backend preamble doesn't do anything to pseudorefs. It just does reflog stuff. In addition, this version removes the over-aggressive die() on reflog update failure from v7. It adds the REF_FORCE_CREATE_REFLOG flag, as Michael Haggerty suggested. And it fixes commit message or two, as suggested. I believe this addresses all comments I've seen on v7. This addresses Johannes Sixt's concerns too, by removing the offending code. -- 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 v8 3/7] refs: new public ref function: safe_create_reflog
The safe_create_reflog function creates a reflog, if it does not already exist. The log_ref_setup function becomes private and gains a force_create parameter to force the creation of a reflog even if log_all_ref_updates is false or the refname is not one of the special refnames. The new parameter also reduces the need to store, modify, and restore the log_all_ref_updates global before reflog creation. In a moment, we will use this to add reflog creation commands to git-reflog. Signed-off-by: David Turner dtur...@twopensource.com --- builtin/checkout.c | 16 ++-- refs.c | 24 refs.h | 2 +- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 93f63d3..9923fd5 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -620,24 +620,20 @@ static void update_refs_for_switch(const struct checkout_opts *opts, if (opts-new_branch) { if (opts-new_orphan_branch) { if (opts-new_branch_log !log_all_ref_updates) { - int temp; - struct strbuf log_file = STRBUF_INIT; int ret; - const char *ref_name; + char *refname; struct strbuf err = STRBUF_INIT; - ref_name = mkpath(refs/heads/%s, opts-new_orphan_branch); - temp = log_all_ref_updates; - log_all_ref_updates = 1; - ret = log_ref_setup(ref_name, log_file, err); - log_all_ref_updates = temp; - strbuf_release(log_file); + refname = mkpathdup(refs/heads/%s, opts-new_orphan_branch); + ret = safe_create_reflog(refname, err, 1); + free(refname); if (ret) { - fprintf(stderr, _(Can not do reflog for '%s'. %s\n), + fprintf(stderr, _(can not do reflog for '%s'. %s\n), opts-new_orphan_branch, err.buf); strbuf_release(err); return; } + strbuf_release(err); } } else diff --git a/refs.c b/refs.c index 903b401..4857f0b 100644 --- a/refs.c +++ b/refs.c @@ -3128,8 +3128,13 @@ static int should_autocreate_reflog(const char *refname) !strcmp(refname, HEAD); } -/* This function will fill in *err and return -1 on failure */ -int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err) +/* + * Create a reflog for a ref. If force_create = 0, the reflog will + * only be created for certain refs (those for which + * should_autocreate_reflog returns non-zero. Otherwise, create it + * regardless of the ref name. Fill in *err and return -1 on failure. + */ +static int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err, int force_create) { int logfd, oflags = O_APPEND | O_WRONLY; char *logfile; @@ -3138,7 +3143,7 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf logfile = sb_logfile-buf; /* make sure the rest of the function can't change logfile */ sb_logfile = NULL; - if (should_autocreate_reflog(refname)) { + if (force_create || should_autocreate_reflog(refname)) { if (safe_create_leading_directories(logfile) 0) { strbuf_addf(err, unable to create directory for %s. %s, logfile, strerror(errno)); @@ -3173,6 +3178,17 @@ int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf return 0; } + +int safe_create_reflog(const char *refname, struct strbuf *err, int force_create) +{ + int ret; + struct strbuf sb = STRBUF_INIT; + + ret = log_ref_setup(refname, sb, err, force_create); + strbuf_release(sb); + return ret; +} + static int log_ref_write_fd(int fd, const unsigned char *old_sha1, const unsigned char *new_sha1, const char *committer, const char *msg) @@ -3209,7 +3225,7 @@ static int log_ref_write_1(const char *refname, const unsigned char *old_sha1, if (log_all_ref_updates 0) log_all_ref_updates = !is_bare_repository(); - result = log_ref_setup(refname, sb_log_file, err); + result = log_ref_setup(refname, sb_log_file, err, 0); if (result) return result; diff --git a/refs.h b/refs.h index debdefc..3b90e16
[PATCH v8 4/7] git-reflog: add exists command
Theis are necessary because alternate ref backends might store reflogs somewhere other than .git/logs. Code that now directly manipulates .git/logs should instead go through git-reflog. Signed-off-by: David Turner dtur...@twopensource.com --- Documentation/git-reflog.txt | 4 builtin/reflog.c | 33 - t/t1411-reflog-show.sh | 5 + 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt index 5e7908e..4b08fc7 100644 --- a/Documentation/git-reflog.txt +++ b/Documentation/git-reflog.txt @@ -23,6 +23,7 @@ depending on the subcommand: [--dry-run] [--verbose] [--all | refs...] 'git reflog delete' [--rewrite] [--updateref] [--dry-run] [--verbose] ref@\{specifier\}... +'git reflog exists' ref Reference logs, or reflogs, record when the tips of branches and other references were updated in the local repository. Reflogs are @@ -52,6 +53,9 @@ argument must be an _exact_ entry (e.g. `git reflog delete master@{2}`). This subcommand is also typically not used directly by end users. +The exists subcommand checks whether a ref has a reflog. It exists +with zero status if the reflog exists, and non-zero status if it does +not. OPTIONS --- diff --git a/builtin/reflog.c b/builtin/reflog.c index c2eb8ff..7ed0e85 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -13,6 +13,8 @@ static const char reflog_expire_usage[] = git reflog expire [--expire=time] [--expire-unreachable=time] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all] refs...; static const char reflog_delete_usage[] = git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] refs...; +static const char reflog_exists_usage[] = +git reflog exists ref; static unsigned long default_reflog_expire; static unsigned long default_reflog_expire_unreachable; @@ -699,12 +701,38 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix) return status; } +static int cmd_reflog_exists(int argc, const char **argv, const char *prefix) +{ + int i, start = 0; + + for (i = 1; i argc; i++) { + const char *arg = argv[i]; + if (!strcmp(arg, --)) { + i++; + break; + } + else if (arg[0] == '-') + usage(reflog_exists_usage); + else + break; + } + + start = i; + + if (argc - start != 1) + usage(reflog_exists_usage); + + if (check_refname_format(argv[start], REFNAME_ALLOW_ONELEVEL)) + die(invalid ref format: %s, argv[start]); + return !reflog_exists(argv[start]); +} + /* * main reflog */ static const char reflog_usage[] = -git reflog [ show | expire | delete ]; +git reflog [ show | expire | delete | exists ]; int cmd_reflog(int argc, const char **argv, const char *prefix) { @@ -724,5 +752,8 @@ int cmd_reflog(int argc, const char **argv, const char *prefix) if (!strcmp(argv[1], delete)) return cmd_reflog_delete(argc - 1, argv + 1, prefix); + if (!strcmp(argv[1], exists)) + return cmd_reflog_exists(argc - 1, argv + 1, prefix); + return cmd_log_reflog(argc, argv, prefix); } diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh index 6f47c0d..3eb4f10 100755 --- a/t/t1411-reflog-show.sh +++ b/t/t1411-reflog-show.sh @@ -166,4 +166,9 @@ test_expect_success 'git log -g -p shows diffs vs. parents' ' test_cmp expect actual ' +test_expect_success 'reflog exists works' ' + git reflog exists refs/heads/master + ! git reflog exists refs/heads/nonexistent +' + test_done -- 2.0.5.499.g01f6352.dirty-twtrsrc -- 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 v8 6/7] update-ref and tag: add --create-reflog arg
Allow the creation of a ref (e.g. stash) with a reflog already in place. For most refs (e.g. those under refs/heads), this happens automatically, but for others, we need this option. Currently, git does this by pre-creating the reflog, but alternate ref backends might store reflogs somewhere other than .git/logs. Code that now directly manipulates .git/logs should instead use git plumbing commands. I also added --create-reflog to git tag, just for completeness. In a moment, we will use this argument to make git stash work with alternate ref backends. Signed-off-by: David Turner dtur...@twopensource.com --- Documentation/git-tag.txt| 5 - Documentation/git-update-ref.txt | 5 - builtin/tag.c| 5 - builtin/update-ref.c | 14 +++--- t/t1400-update-ref.sh| 38 ++ t/t7004-tag.sh | 14 +- 6 files changed, 74 insertions(+), 7 deletions(-) diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 034d10d..2312980 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -13,7 +13,7 @@ SYNOPSIS tagname [commit | object] 'git tag' -d tagname... 'git tag' [-n[num]] -l [--contains commit] [--points-at object] - [--column[=options] | --no-column] [pattern...] + [--column[=options] | --no-column] [--create-reflog] [pattern...] [pattern...] 'git tag' -v tagname... @@ -143,6 +143,9 @@ This option is only applicable when listing tags without annotation lines. all, 'whitespace' removes just leading/trailing whitespace lines and 'strip' removes both whitespace and commentary. +--create-reflog:: + Create a reflog for the tag. + tagname:: The name of the tag to create, delete, or describe. The new tag name must pass all checks defined by diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt index c8f5ae5..969bfab 100644 --- a/Documentation/git-update-ref.txt +++ b/Documentation/git-update-ref.txt @@ -8,7 +8,7 @@ git-update-ref - Update the object name stored in a ref safely SYNOPSIS [verse] -'git update-ref' [-m reason] (-d ref [oldvalue] | [--no-deref] ref newvalue [oldvalue] | --stdin [-z]) +'git update-ref' [-m reason] (-d ref [oldvalue] | [--no-deref] [--create-reflog] ref newvalue [oldvalue] | --stdin [-z]) DESCRIPTION --- @@ -67,6 +67,9 @@ performs all modifications together. Specify commands of the form: verify SP ref [SP oldvalue] LF option SP opt LF +With `--create-reflog`, update-ref will create a reflog for each ref +even if one would not ordinarily be created. + Quote fields containing whitespace as if they were strings in C source code; i.e., surrounded by double-quotes and with backslash escapes. Use 40 0 characters or the empty string to specify a zero value. To diff --git a/builtin/tag.c b/builtin/tag.c index 5f6cdc5..a99 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -579,6 +579,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) struct create_tag_options opt; char *cleanup_arg = NULL; int annotate = 0, force = 0, lines = -1; + int create_reflog = 0; int cmdmode = 0; const char *msgfile = NULL, *keyid = NULL; struct msg_arg msg = { 0, STRBUF_INIT }; @@ -605,6 +606,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPT_STRING('u', local-user, keyid, N_(key-id), N_(use another key to sign the tag)), OPT__FORCE(force, N_(replace the tag if exists)), + OPT_BOOL(0, create-reflog, create_reflog, N_(create_reflog)), OPT_GROUP(N_(Tag listing options)), OPT_COLUMN(0, column, colopts, N_(show tag list in columns)), @@ -733,7 +735,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix) transaction = ref_transaction_begin(err); if (!transaction || ref_transaction_update(transaction, ref.buf, object, prev, - 0, NULL, err) || + create_reflog ? REF_FORCE_CREATE_REFLOG : 0, + NULL, err) || ref_transaction_commit(transaction, err)) die(%s, err.buf); ref_transaction_free(transaction); diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 6763cf1..d9646ef 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -14,6 +14,7 @@ static const char * const git_update_ref_usage[] = { static char line_termination = '\n'; static int update_flags; +int create_reflog_flag; static const char *msg; /* @@ -200,7 +201,8 @@ static const char *parse_cmd_update(struct ref_transaction *transaction, if (ref_transaction_update(transaction, refname, new_sha1, have_old ?
[PATCH v8 7/7] git-stash: use update-ref --create-reflog instead of creating files
This is in support of alternate ref backends which don't necessarily store reflogs as files. Signed-off-by: David Turner dtur...@twopensource.com --- git-stash.sh | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/git-stash.sh b/git-stash.sh index 8e9e2cd..1d5ba7a 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -183,9 +183,7 @@ store_stash () { stash_msg=Created via \git stash store\. fi - # Make sure the reflog for stash is kept. - : $(git rev-parse --git-path logs/$ref_stash) - git update-ref -m $stash_msg $ref_stash $w_commit + git update-ref --create-reflog -m $stash_msg $ref_stash $w_commit ret=$? test $ret != 0 test -z $quiet die $(eval_gettext Cannot update \$ref_stash with \$w_commit) @@ -262,7 +260,7 @@ save_stash () { say $(gettext No local changes to save) exit 0 fi - test -f $(git rev-parse --git-path logs/$ref_stash) || + git reflog exists $ref_stash || clear_stash || die $(gettext Cannot initialize stash) create_stash $stash_msg $untracked -- 2.0.5.499.g01f6352.dirty-twtrsrc -- 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 v8 5/7] refs: add REF_FORCE_CREATE_REFLOG flag
Add a flag to allow forcing the creation of a reflog even if the ref name and core.logAllRefUpdates setting would not ordinarily cause ref creation. In a moment, we will use this to add options to git tag and git update-ref to force reflog creation. Signed-off-by: David Turner dtur...@twopensource.com --- refs.c | 34 +- refs.h | 1 + 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/refs.c b/refs.c index 4857f0b..06c62c8 100644 --- a/refs.c +++ b/refs.c @@ -63,6 +63,11 @@ static unsigned char refname_disposition[256] = { #define REF_NEEDS_COMMIT 0x20 /* + * 0x40 is REF_FORCE_CREATE_REFLOG, so skip it if you're adding a + * value to ref_update::flags + */ + +/* * 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 @@ -2979,7 +2984,7 @@ static int write_ref_to_lockfile(struct ref_lock *lock, const unsigned char *sha1, struct strbuf *err); static int commit_ref_update(struct ref_lock *lock, const unsigned char *sha1, const char *logmsg, -struct strbuf *err); +int flags, struct strbuf *err); int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg) { @@ -3041,7 +3046,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms hashcpy(lock-old_oid.hash, orig_sha1); if (write_ref_to_lockfile(lock, orig_sha1, err) || - commit_ref_update(lock, orig_sha1, logmsg, err)) { + commit_ref_update(lock, orig_sha1, logmsg, 0, err)) { error(unable to write current sha1 into %s: %s, newrefname, err.buf); strbuf_release(err); goto rollback; @@ -3060,7 +3065,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms flag = log_all_ref_updates; log_all_ref_updates = 0; if (write_ref_to_lockfile(lock, orig_sha1, err) || - commit_ref_update(lock, orig_sha1, NULL, err)) { + commit_ref_update(lock, orig_sha1, NULL, 0, err)) { error(unable to write current sha1 into %s: %s, oldrefname, err.buf); strbuf_release(err); } @@ -3217,7 +3222,8 @@ static int log_ref_write_fd(int fd, const unsigned char *old_sha1, static int log_ref_write_1(const char *refname, const unsigned char *old_sha1, const unsigned char *new_sha1, const char *msg, - struct strbuf *sb_log_file, struct strbuf *err) + struct strbuf *sb_log_file, int flags, + struct strbuf *err) { int logfd, result, oflags = O_APPEND | O_WRONLY; char *log_file; @@ -3225,7 +3231,7 @@ static int log_ref_write_1(const char *refname, const unsigned char *old_sha1, if (log_all_ref_updates 0) log_all_ref_updates = !is_bare_repository(); - result = log_ref_setup(refname, sb_log_file, err, 0); + result = log_ref_setup(refname, sb_log_file, err, flags REF_FORCE_CREATE_REFLOG); if (result) return result; @@ -3254,10 +3260,11 @@ static int log_ref_write_1(const char *refname, const unsigned char *old_sha1, static int log_ref_write(const char *refname, const unsigned char *old_sha1, const unsigned char *new_sha1, const char *msg, -struct strbuf *err) +int flags, struct strbuf *err) { struct strbuf sb = STRBUF_INIT; - int ret = log_ref_write_1(refname, old_sha1, new_sha1, msg, sb, err); + int ret = log_ref_write_1(refname, old_sha1, new_sha1, msg, sb, flags, + err); strbuf_release(sb); return ret; } @@ -3313,12 +3320,12 @@ static int write_ref_to_lockfile(struct ref_lock *lock, */ static int commit_ref_update(struct ref_lock *lock, const unsigned char *sha1, const char *logmsg, -struct strbuf *err) +int flags, struct strbuf *err) { clear_loose_ref_cache(ref_cache); - if (log_ref_write(lock-ref_name, lock-old_oid.hash, sha1, logmsg, err) 0 || + if (log_ref_write(lock-ref_name, lock-old_oid.hash, sha1, logmsg, flags, err) 0 || (strcmp(lock-ref_name, lock-orig_ref_name) -log_ref_write(lock-orig_ref_name, lock-old_oid.hash, sha1, logmsg, err) 0)) { +log_ref_write(lock-orig_ref_name, lock-old_oid.hash, sha1, logmsg, flags, err) 0)) { char *old_msg = strbuf_detach(err, NULL); strbuf_addf(err, Cannot update the ref '%s': '%s', lock-ref_name, old_msg); @@ -3348,7 +3355,7 @@ static int
Re: [PATCH v2 9/9] diffcore-pickaxe: support case insensitive match on non-ascii
On Wed, Jul 8, 2015 at 6:38 AM, Nguyễn Thái Ngọc Duy pclo...@gmail.com wrote: Similar to the grep -F -i case, we can't use kws on icase search outside ascii range, quote we quote the string and pass it to regcomp s/quote we quote/so we quote/ (or something) as a basic regexp and let regex engine deal with case sensitivity. The new test is put in t7812 instead of t4209-log-pickaxe because lib-gettext.sh might cause problems elsewhere, probably.. Noticed-by: Plamen Totev plamen.to...@abv.bg Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com -- 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 v7 2/8] cherry-pick: treat CHERRY_PICK_HEAD and REVERT_HEAD as refs
David Turner dtur...@twopensource.com writes: OK, here's my current best idea: 1. A pseudoref is an all-caps file in $GIT_DIR/ that always contains at least a SHA1. CHERRY_PICK_HEAD and REVERT_HEAD are examples. Because HEAD might be a symbolic ref, it is not a pseudoref. Refs backends do not manage pseudorefs. Instead, when a pseudoref (an all-caps ref containing no slashes) is requested (e.g. git rev-parse FETCH_HEAD) the generic refs code checks for the existence of that file and if it exists, returns immediately without hitting the backend. The generic code will refuse to allow updates to pseudorefs. 2. The pluggable refs backend manages all refs other than HEAD. 3. The files backend always manages HEAD. This allows for a reflog and for HEAD to be a symbolic ref. The major complication here is ref transactions -- what if there's a transaction that wants to update e.g. both HEAD and refs/heads/master? An update to the current branch (e.g. git commit) does involve at least update to the reflog of HEAD, the current branch somewhere in refs/heads/ and its log, so it is not what if but is a norm [*1*]. It may be the case that this never happens; I have not actually audited the code to figure it out. If someone knows for sure that it does not happen, please say so. But assuming it does happen, here's my idea: If the refs backend is the files backend, we can simply treat HEAD like any other ref. If the refs backend is different, then the refs code needs to hold a files-backend transaction for HEAD, which it will commit immediately after the other transaction succeeds. We can stick a pointer to the extra transaction in the generic struct ref_transaction, which (as Michael Haggerty suggests) specific backends will extend. A failure to commit either transaction will be reported as a failure, and we'll give an additional inconsistent state warning if the main transaction succeeds but the HEAD transaction fails. Yeah, I was thinking along those lines, too. Thanks for clearly writing it down. What do other folks think? Me too ;-) [Footnote] *1* But that is not a complaint; I do not have a better idea myself either. -- 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 v7 2/8] cherry-pick: treat CHERRY_PICK_HEAD and REVERT_HEAD as refs
On Wed, 2015-07-08 at 22:55 -0700, Junio C Hamano wrote: David Turner dtur...@twopensource.com writes: I didn't see this until after I had sent my previous message. I think the multiple working trees argument is strong enough that I will change the code (and tests). Not just code, but we probably should step back a bit and clearly define what we are trying to achieve. I _think_ what we want are: - Everything under refs/* and their associated logs would be handed off to the pluggable ref backend when one is in use. - All ref-like things with one-level ALL_CAPS names are per working tree. - They do not participate in prunable? reachability computation. - They (typically) do not want logs. Except HEAD definitely does. - Each may have extra information specific to it. - You can however read an object name off of them. One possible and straight-forward implementation to achieve ref-like things with one-level ALL_CAPS names are per working tree is to declare that they will not be handed off to the backend, but will always be implemented as files immediately under $GIT_DIR/. But note that there is no fundamental reason we have to do it that way; an alternative would be to allow backends to store these things per working tree, but then the interface to drive backends need to tell them which working tree we are working from. Unlike branches, HEAD must be per working tree; the pluggable ref backend needs to be able handle HEAD when you introduce it. I actually punted on this in my implementation, because at the time, git-new-workdir was only in contrib. But since the new worktree stuff, multiple worktrees have first-class support, so I'll have to update the code to handle it. So from that point of view, multiple working tree is *not* a valid argument why they *have* to be implemented as files under $GIT_DIR/. If you plan to let the pluggable ref backend to handle HEAD, you must have a solution for per working tree ref-like things anyway. OK, here's my current best idea: 1. A pseudoref is an all-caps file in $GIT_DIR/ that always contains at least a SHA1. CHERRY_PICK_HEAD and REVERT_HEAD are examples. Because HEAD might be a symbolic ref, it is not a pseudoref. Refs backends do not manage pseudorefs. Instead, when a pseudoref (an all-caps ref containing no slashes) is requested (e.g. git rev-parse FETCH_HEAD) the generic refs code checks for the existence of that file and if it exists, returns immediately without hitting the backend. The generic code will refuse to allow updates to pseudorefs. 2. The pluggable refs backend manages all refs other than HEAD. 3. The files backend always manages HEAD. This allows for a reflog and for HEAD to be a symbolic ref. The major complication here is ref transactions -- what if there's a transaction that wants to update e.g. both HEAD and refs/heads/master? It may be the case that this never happens; I have not actually audited the code to figure it out. If someone knows for sure that it does not happen, please say so. But assuming it does happen, here's my idea: If the refs backend is the files backend, we can simply treat HEAD like any other ref. If the refs backend is different, then the refs code needs to hold a files-backend transaction for HEAD, which it will commit immediately after the other transaction succeeds. We can stick a pointer to the extra transaction in the generic struct ref_transaction, which (as Michael Haggerty suggests) specific backends will extend. A failure to commit either transaction will be reported as a failure, and we'll give an additional inconsistent state warning if the main transaction succeeds but the HEAD transaction fails. I don't love this idea -- it seems like kind of a hack. But it's the best I can come up with. What do other folks think? As to J6t's no excessive plumbing invocations, I think the right approach is to have a single git prompt--helper command that does what the current script does to compute $r. we want to keep peeking into files under $GIT_DIR/ alone is not a valid enough reason to constrain us (I am fine if the solution we find appropriate for the 'multiple working trees' and other issues ends up being we solve it by having them as files in $GIT_DIR for other reasons, though). Agree. -- 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] fast-import: Do less work when given from matches current branch head
On Thu, Jul 09, 2015 at 01:37:02PM -0700, Junio C Hamano wrote: Mike Hommey m...@glandium.org writes: Cc'ed a few people who appear at the top of shortlog --no-merges; I think the end result is not incorrect, but I want to hear second opinions on this one. I do not know Shawn still remembers this code, but what is under discussion seems to have come mostly from ea5e370a (fast-import: Support reusing 'from' and brown paper bag fix reset., 2007-02-12). if (!skip_prefix(command_buf.buf, from , from)) return 0; - if (b-branch_tree.tree) { - release_tree_content_recursive(b-branch_tree.tree); - b-branch_tree.tree = NULL; - } + hashcpy(sha1, b-branch_tree.versions[1].sha1); s = lookup_branch(from); if (b == s) The part that deals with a branch that is different from the current one is not visible in the context (i.e. when s = lookup_branch(from) returned a non-NULL result that is different from b) but it used to, and continues to with this patch, copy sha1 from branch_tree.sha1 and branch_tree.versions[] from sha1 and branch_tree.versions[1] of the specified branch. That codepath used to release the contents of branch_tree.tree when it did so, but it no longer does so after this patch because of the removal we see above. Does that mean the original code was doing a release that was unnecessary? Or does it mean this patch changes what happens on that codepath, namely (1) leaking resource, and/or (2) keeping a tree of the original 'b' that does not have anything to do with the tree of 's', preventing the later lazy-load code from reading the tree of 's' and instead of building on top of a wrong tree content? I guess the question is whether branch_tree.tree can be in a state that doesn't match that of branch_tree.versions[1].sha1. If not, then if s and b have the same branch_tree.versions[1].sha1 for some reason, then keeping the old branch_tree.tree makes no practical difference from resetting it. Except it skips the busy-work. Mike -- 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