Reset sometimes updates mtime

2015-07-09 Thread Dennis Kaarsemaker
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

2015-07-09 Thread Junio C Hamano
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

2015-07-09 Thread 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?).

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

2015-07-09 Thread Sebastian Schuberth
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

2015-07-09 Thread Sebastian Schuberth
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

2015-07-09 Thread Jeff King
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()

2015-07-09 Thread Sebastian Schuberth
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

2015-07-09 Thread David Turner
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

2015-07-09 Thread John Norris



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()

2015-07-09 Thread Sebastian Schuberth
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()

2015-07-09 Thread Junio C Hamano
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()

2015-07-09 Thread Junio C Hamano
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

2015-07-09 Thread Junio C Hamano
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()

2015-07-09 Thread Sebastian Schuberth
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()

2015-07-09 Thread Sebastian Schuberth
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

2015-07-09 Thread Junio C Hamano
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

2015-07-09 Thread Junio C Hamano
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

2015-07-09 Thread Johan Herland
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

2015-07-09 Thread Jeff King
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

2015-07-09 Thread Junio C Hamano
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

2015-07-09 Thread Michael Haggerty
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

2015-07-09 Thread John Norris

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

2015-07-09 Thread Mike Hommey
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

2015-07-09 Thread Jacob Keller
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

2015-07-09 Thread Jacob Keller
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

2015-07-09 Thread Karthik Nayak

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

2015-07-09 Thread Karthik Nayak

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

2015-07-09 Thread Karthik Nayak

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

2015-07-09 Thread Karthik Nayak
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

2015-07-09 Thread Matthieu Moy
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

2015-07-09 Thread Junio C Hamano
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

2015-07-09 Thread Michael Haggerty
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

2015-07-09 Thread Mike Hommey
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

2015-07-09 Thread Heiko Voigt
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

2015-07-09 Thread Christian Couder
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

2015-07-09 Thread Karthik Nayak
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

2015-07-09 Thread Karthik Nayak
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

2015-07-09 Thread Karthik Nayak
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

2015-07-09 Thread Karthik Nayak
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

2015-07-09 Thread Karthik Nayak
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

2015-07-09 Thread Karthik Nayak
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

2015-07-09 Thread Karthik Nayak
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

2015-07-09 Thread Matthieu Moy
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

2015-07-09 Thread Matthieu Moy
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

2015-07-09 Thread Matthieu Moy
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

2015-07-09 Thread Karthik Nayak
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

2015-07-09 Thread Karthik Nayak
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

2015-07-09 Thread Matthieu Moy
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

2015-07-09 Thread Matthieu Moy
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

2015-07-09 Thread Matthieu Moy
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

2015-07-09 Thread Matthieu Moy
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?

2015-07-09 Thread Stefan Tatschner
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?

2015-07-09 Thread Stefan Tatschner
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

2015-07-09 Thread Junio C Hamano
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

2015-07-09 Thread Phil Susi
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

2015-07-09 Thread Johannes Sixt

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()

2015-07-09 Thread Junio C Hamano
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()

2015-07-09 Thread Sebastian Schuberth
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

2015-07-09 Thread Jens Lehmann

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

2015-07-09 Thread Junio C Hamano
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

2015-07-09 Thread Junio C Hamano
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

2015-07-09 Thread Junio C Hamano
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

2015-07-09 Thread Jeff King
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

2015-07-09 Thread David Turner
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

2015-07-09 Thread David Turner
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

2015-07-09 Thread David Turner
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

2015-07-09 Thread David Turner
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

2015-07-09 Thread David Turner
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

2015-07-09 Thread David Turner
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

2015-07-09 Thread David Turner
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

2015-07-09 Thread David Turner
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

2015-07-09 Thread Eric Sunshine
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

2015-07-09 Thread Junio C Hamano
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

2015-07-09 Thread David Turner
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

2015-07-09 Thread Mike Hommey
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