Re: git-draw - draws nearly the full content of a tiny git repository as a graph

2014-02-03 Thread Stefan Näwe
Am 29.01.2014 22:21, schrieb Flo:
 I just want to present a small tool I wrote. I use it at work to have
 a tool visualizing the Git basic concepts and data structures which
 are really really really simple (Linus' words). That helps me
 teaching my colleagues about Git and answering their questions when
 Git did not behave as they expected.
 
 https://github.com/sensorflo/git-draw/wiki

This looks really promising!

Stefan
-- 

/dev/random says: Famous last words - Jesus Christ: Father, beam me up.
python -c print 
'73746566616e2e6e616577654061746c61732d656c656b74726f6e696b2e636f6d'.decode('hex')
--
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: Running make rpm fails on a CentOS 6.3 machine

2014-02-03 Thread Erez Zilber
On Sun, Feb 2, 2014 at 11:07 PM, Todd Zullinger t...@pobox.com wrote:
 Hi Erez,


 Erez Zilber wrote:

 Thanks. I will try to use the rpm from Todd's build. BTW - if I want to
 create such a build on Fedora that will create el6 packages (e.g.
 git-1.8.5.3-2.el6.x86_64.rpm), what's the procedure?


 Something like this (this is from memory):

 # Install fedpkg
 $ yum install fedpkg

Thanks. Just making sure - I need to do all of this on a fedora
machine, not a RHEL/CentOS machine, right?

Erez
--
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] userdiff: update Ada patterns

2014-02-03 Thread Adrian Johnson
On 03/02/14 10:05, Jeff King wrote:
 On Sun, Feb 02, 2014 at 09:21:56PM +1030, Adrian Johnson wrote:
 - Fix bug in word regex for numbers
 - |[0-9][-+0-9#_.eE]
 + |[-+0-9#_.eE]+
 
 This makes E or _ a number. Is that right?
 
 I think the intent of the original was starts with a digit, and then
 has one or more of these other things after it. You do not describe the
 bug, but I guess it would be that it does not match obvious things like
 5. Should it be zero or more instead, like:
 
   [0-9][-+0-9#_.eE]*

Yes, the original was missing the '*' at the end. 

I changed it to be similar to the number regexes used by the other builtin
patterns which are of the form '[-+0-9#_.eE]+'.

 
 ? Also, should -/+ be hoisted to the front?
 
   [-+]?[0-9][0-9#_.eE]*

The other builtins don't do this. But it is probably better to have
[-+]?[0-9] at the front.

 Again, I am just guessing, as I am not familiar enough with Ada.

Ada numbers have the form:

- integers and reals eg 123, 1.23, 1e-2 ('.' can not be first)
- a '_' may be used between digits to improve readability eg 123_456
- base n (2 = n = 16) is of the form n#digits# eg 16#FFEF#
- base n numbers can include a radix point and/or an exponent
  eg 16#FF12.8#e-2
- Ada is case insensitive

After having another look I noticed it was missing the hex characters.
The new number regex I am proposing is:

[-+]?[0-9][0-9#_.aAbBcCdDeEfF]*([eE][+-]?[0-9_]+)?

I kept exponents containing a +/- sign separate from the digits
to prevent things like '1+2' from matching. I'll send an updated patch.

 
 -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
 

--
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] userdiff: update Ada patterns

2014-02-03 Thread Adrian Johnson
- Allow extra space in is new and is separate
- Fix bug in word regex for numbers

Signed-off-by: Adrian Johnson ajohn...@redneon.com
---
 t/t4034/ada/expect | 2 +-
 userdiff.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/t/t4034/ada/expect b/t/t4034/ada/expect
index be2376e..a682d28 100644
--- a/t/t4034/ada/expect
+++ b/t/t4034/ada/expect
@@ -4,7 +4,7 @@
 BOLD+++ b/postRESET
 CYAN@@ -1,13 +1,13 @@RESET
 Ada.Text_IO.Put_Line(Hello WorldRED!RESETGREEN?RESET);
-1 1eRED-RESET10 16#FE12#E2 3.141_592 'REDxRESETGREENyRESET'
+1 RED1e-10RESETGREEN1e10RESET 16#FE12#E2 3.141_592 
'REDxRESETGREENyRESET'
 REDaRESETGREENxRESET+REDb aRESETGREENy xRESET-REDbRESET
 REDaRESETGREENyRESET
 GREENxRESET*REDb aRESETGREENy xRESET/REDbRESET
diff --git a/userdiff.c b/userdiff.c
index ea43a03..10b61ec 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -15,13 +15,13 @@ static int drivers_alloc;
  word_regex |[^[:space:]]|[\xc0-\xff][\x80-\xbf]+ }
 static struct userdiff_driver builtin_drivers[] = {
 IPATTERN(ada,
-!^(.*[ \t])?(is new|renames|is separate)([ \t].*)?$\n
+!^(.*[ \t])?(is[ \t]+new|renames|is[ \t]+separate)([ \t].*)?$\n
 !^[ \t]*with[ \t].*$\n
 ^[ \t]*((procedure|function)[ \t]+.*)$\n
 ^[ \t]*((package|protected|task)[ \t]+.*)$,
 /* -- */
 [a-zA-Z][a-zA-Z0-9_]*
-|[0-9][-+0-9#_.eE]
+|[-+]?[0-9][0-9#_.aAbBcCdDeEfF]*([eE][+-]?[0-9_]+)?
 |=|\\.\\.|\\*\\*|:=|/=|=|=|||),
 IPATTERN(fortran,
 !^([C*]|[ \t]*!)\n
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/8] `log -c` speedup (part 2)

2014-02-03 Thread Kirill Smelkov
Hello up there,

I'm still trying to speedup combined-diff to be not so slow, to be able to
realistically use it in my readonly filesystem for git archives.

In the first part[1], we optimized paths intersections, but combined-diff still
remained slow, because internally it was computing huge diffs, even for small,
or empty output.

This time, here goes paths scanning rework, which results in significant
combine-diff speedup. Please apply.

Thanks beforehand,
Kirill

P.S. the code depends on ks/diff-c-with-diff-order

[1] http://permalink.gmane.org/gmane.comp.version-control.git/240713


Kirill Smelkov (8):
  fixup! combine_diff: simplify intersect_paths() further
  tests: add checking that combine-diff emits only correct paths
  tree-diff: no need to manually verify that there is no mode change for
a path
  tree-diff: no need to pass match to skip_uninteresting()
  combine-diff: move show_log_first logic/action out of paths scanning
  combine-diff: Move changed-paths scanning logic into its own function
  combine-diff: Fast changed-to-all-parents paths scanning
  combine-diff: bail out early, if num_paths=0

 combine-diff.c | 215 +++-
 diff.c |   1 +
 diff.h |   6 +
 t/t4057-diff-combined-paths.sh | 106 ++
 tree-diff.c| 442 +++--
 5 files changed, 696 insertions(+), 74 deletions(-)
 create mode 100755 t/t4057-diff-combined-paths.sh

-- 
1.9.rc1.181.g641f458

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/8] fixup! combine_diff: simplify intersect_paths() further

2014-02-03 Thread Kirill Smelkov
That cleanup patch is good, but I've found a bug in it. In the item removal
code

 +  /* p-path not in q-queue[]; drop it */
 +  struct combine_diff_path *next = p-next;
 +
 +  if ((*tail = next) != NULL)
 +  tail = next-next;
 +  free(p);
continue;

*tail = next

is right, but

tail = next-next

is wrong, because it will lead to skipping the element after removed
one. Proof:

tailp
  | |
  | |
  v v
 +-+   +--+-+   +--+-+   +--+-+
 | |   |  | |   |  | |   |  | |
 |o---|  |o---|  |o---|  |o---
 |0|   | 1| |   | 2| |   | 3| |
 +-+   +--+-+   +--+-+   +--+-+

suppose, we are removing element 1. p-next points to 2, after

*tail = next

0 points to 2, which != NULL. After

tail = next-next

tail points to 2-next.

On the next cycle iteration, after

p = *tail

we'll have

p = *2-next = 3

so 2 was skipped, oops.

I've actually hit the bug - when generating combine-diff, for merges with
should-be empty `log -c` output, every second path was present in the diff.
That, by the way, means we need to extend combine-diff tests somewhat.

Signed-off-by: Kirill Smelkov k...@mns.spb.ru
---
 combine-diff.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/combine-diff.c b/combine-diff.c
index 0809e79..a03147c 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -58,8 +58,7 @@ static struct combine_diff_path *intersect_paths(struct 
combine_diff_path *curr,
/* p-path not in q-queue[]; drop it */
struct combine_diff_path *next = p-next;
 
-   if ((*tail = next) != NULL)
-   tail = next-next;
+   *tail = next;
free(p);
continue;
}
-- 
1.9.rc1.181.g641f458

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 6/8] combine-diff: Move changed-paths scanning logic into its own function

2014-02-03 Thread Kirill Smelkov
Move code for finding paths for which diff(commit,parent_i) is not-empty
for all parents to separate function - at present we have generic (and
slow) code for this job, which translates 1 n-parent problem to n
1-parent problems and then intersect results, and will be adding another
limited, but faster, paths scanning implementation in the next patch.

Signed-off-by: Kirill Smelkov k...@mns.spb.ru
---
 combine-diff.c | 79 ++
 1 file changed, 52 insertions(+), 27 deletions(-)

diff --git a/combine-diff.c b/combine-diff.c
index 272931f..427a7c1 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -1303,6 +1303,50 @@ static const char *path_path(void *obj)
return path-path;
 }
 
+
+/* find set of paths that every parent touches */
+static struct combine_diff_path *find_paths(const unsigned char *sha1,
+   const struct sha1_array *parents, struct diff_options *opt)
+{
+   struct combine_diff_path *paths = NULL;
+   int i, num_parent = parents-nr;
+
+   int output_format = opt-output_format;
+   const char *orderfile = opt-orderfile;
+
+   opt-output_format = DIFF_FORMAT_NO_OUTPUT;
+   /* tell diff_tree to emit paths in sorted (=tree) order */
+   opt-orderfile = NULL;
+
+   for (i = 0; i  num_parent; i++) {
+   /* show stat against the first parent even
+* when doing combined diff.
+*/
+   int stat_opt = (output_format 
+   (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT));
+   if (i == 0  stat_opt)
+   opt-output_format = stat_opt;
+   else
+   opt-output_format = DIFF_FORMAT_NO_OUTPUT;
+   diff_tree_sha1(parents-sha1[i], sha1, , opt);
+   diffcore_std(opt);
+   paths = intersect_paths(paths, i, num_parent);
+
+   /* if showing diff, show it in requested order */
+   if (opt-output_format != DIFF_FORMAT_NO_OUTPUT 
+   orderfile) {
+   diffcore_order(orderfile);
+   }
+
+   diff_flush(opt);
+   }
+
+   opt-output_format = output_format;
+   opt-orderfile = orderfile;
+   return paths;
+}
+
+
 void diff_tree_combined(const unsigned char *sha1,
const struct sha1_array *parents,
int dense,
@@ -1310,7 +1354,7 @@ void diff_tree_combined(const unsigned char *sha1,
 {
struct diff_options *opt = rev-diffopt;
struct diff_options diffopts;
-   struct combine_diff_path *p, *paths = NULL;
+   struct combine_diff_path *p, *paths;
int i, num_paths, needsep, show_log_first, num_parent = parents-nr;
 
/* nothing to do, if no parents */
@@ -1329,35 +1373,16 @@ void diff_tree_combined(const unsigned char *sha1,
 
diffopts = *opt;
copy_pathspec(diffopts.pathspec, opt-pathspec);
-   diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
DIFF_OPT_SET(diffopts, RECURSIVE);
DIFF_OPT_CLR(diffopts, ALLOW_EXTERNAL);
-   /* tell diff_tree to emit paths in sorted (=tree) order */
-   diffopts.orderfile = NULL;
 
-   /* find set of paths that everybody touches */
-   for (i = 0; i  num_parent; i++) {
-   /* show stat against the first parent even
-* when doing combined diff.
-*/
-   int stat_opt = (opt-output_format 
-   (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT));
-   if (i == 0  stat_opt)
-   diffopts.output_format = stat_opt;
-   else
-   diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
-   diff_tree_sha1(parents-sha1[i], sha1, , diffopts);
-   diffcore_std(diffopts);
-   paths = intersect_paths(paths, i, num_parent);
-
-   /* if showing diff, show it in requested order */
-   if (diffopts.output_format != DIFF_FORMAT_NO_OUTPUT 
-   opt-orderfile) {
-   diffcore_order(opt-orderfile);
-   }
-
-   diff_flush(diffopts);
-   }
+   /* find set of paths that everybody touches
+*
+* NOTE find_paths() also handles --stat, as it computes
+* diff(sha1,parent_i) for all i to do the job, specifically
+* for parent0.
+*/
+   paths = find_paths(sha1, parents, diffopts);
 
/* find out number of surviving paths */
for (num_paths = 0, p = paths; p; p = p-next)
-- 
1.9.rc1.181.g641f458

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/8] tree-diff: no need to manually verify that there is no mode change for a path

2014-02-03 Thread Kirill Smelkov
Because if there is, such two tree entries would never be compared as
equal - the code in base_name_compare() explicitly compares modes, if
there is a change for dir bit, even for equal paths, entries would
compare as different.

The code I'm removing here is from 2005 April 262e82b4 (Fix diff-tree
recursion), which pre-dates base_name_compare() introduction in 958ba6c9
(Introduce base_name_compare() helper function) by a month.

Signed-off-by: Kirill Smelkov k...@mns.spb.ru
---
 tree-diff.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/tree-diff.c b/tree-diff.c
index 456660c..c2c67fd 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -23,6 +23,10 @@ static int compare_tree_entry(struct tree_desc *t1, struct 
tree_desc *t2,
 
pathlen1 = tree_entry_len(t1-entry);
pathlen2 = tree_entry_len(t2-entry);
+
+   /* NOTE files and directories *always* compare differently, event when
+* having the same name.
+*/
cmp = base_name_compare(path1, pathlen1, mode1, path2, pathlen2, mode2);
if (cmp  0) {
show_entry(opt, -, t1, base);
@@ -35,16 +39,6 @@ static int compare_tree_entry(struct tree_desc *t1, struct 
tree_desc *t2,
if (!DIFF_OPT_TST(opt, FIND_COPIES_HARDER)  !hashcmp(sha1, sha2)  
mode1 == mode2)
return 0;
 
-   /*
-* If the filemode has changed to/from a directory from/to a regular
-* file, we need to consider it a remove and an add.
-*/
-   if (S_ISDIR(mode1) != S_ISDIR(mode2)) {
-   show_entry(opt, -, t1, base);
-   show_entry(opt, +, t2, base);
-   return 0;
-   }
-
strbuf_add(base, path1, pathlen1);
if (DIFF_OPT_TST(opt, RECURSIVE)  S_ISDIR(mode1)) {
if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) {
-- 
1.9.rc1.181.g641f458

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 8/8] combine-diff: bail out early, if num_paths=0

2014-02-03 Thread Kirill Smelkov
That simplifies the code - instead of repeated checking for
num_paths !=0, let's verify it once, and return if it is, and
free following code from repeated ifs.

Signed-off-by: Kirill Smelkov k...@mns.spb.ru
---
 combine-diff.c | 52 +++-
 1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/combine-diff.c b/combine-diff.c
index 3e3f328..c1f481f 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -1459,12 +1459,18 @@ void diff_tree_combined(const unsigned char *sha1,
}
}
 
+   free_pathspec(diffopts.pathspec);
+
/* find out number of surviving paths */
for (num_paths = 0, p = paths; p; p = p-next)
num_paths++;
 
+   /* nothing to do, if no paths */
+   if (!num_paths)
+   return;
+
/* order paths according to diffcore_order */
-   if (opt-orderfile  num_paths) {
+   if (opt-orderfile) {
struct obj_order *o;
 
o = xmalloc(sizeof(*o) * num_paths);
@@ -1483,28 +1489,26 @@ void diff_tree_combined(const unsigned char *sha1,
}
 
 
-   if (num_paths) {
-   if (opt-output_format  (DIFF_FORMAT_RAW |
- DIFF_FORMAT_NAME |
- DIFF_FORMAT_NAME_STATUS)) {
-   for (p = paths; p; p = p-next)
-   show_raw_diff(p, num_parent, rev);
-   needsep = 1;
-   }
-   else if (opt-output_format 
-(DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT))
-   needsep = 1;
-   else if (opt-output_format  DIFF_FORMAT_CALLBACK)
-   handle_combined_callback(opt, paths, num_parent, 
num_paths);
-
-   if (opt-output_format  DIFF_FORMAT_PATCH) {
-   if (needsep)
-   printf(%s%c, diff_line_prefix(opt),
-  opt-line_termination);
-   for (p = paths; p; p = p-next)
-   show_patch_diff(p, num_parent, dense,
-   0, rev);
-   }
+   if (opt-output_format  (DIFF_FORMAT_RAW |
+ DIFF_FORMAT_NAME |
+ DIFF_FORMAT_NAME_STATUS)) {
+   for (p = paths; p; p = p-next)
+   show_raw_diff(p, num_parent, rev);
+   needsep = 1;
+   }
+   else if (opt-output_format 
+(DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT))
+   needsep = 1;
+   else if (opt-output_format  DIFF_FORMAT_CALLBACK)
+   handle_combined_callback(opt, paths, num_parent, num_paths);
+
+   if (opt-output_format  DIFF_FORMAT_PATCH) {
+   if (needsep)
+   printf(%s%c, diff_line_prefix(opt),
+  opt-line_termination);
+   for (p = paths; p; p = p-next)
+   show_patch_diff(p, num_parent, dense,
+   0, rev);
}
 
/* Clean things up */
@@ -1513,8 +1517,6 @@ void diff_tree_combined(const unsigned char *sha1,
paths = paths-next;
free(tmp);
}
-
-   free_pathspec(diffopts.pathspec);
 }
 
 void diff_tree_combined_merge(const struct commit *commit, int dense,
-- 
1.9.rc1.181.g641f458

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/8] tree-diff: no need to pass match to skip_uninteresting()

2014-02-03 Thread Kirill Smelkov
It is neither used there as input, nor the output written through it, is
used outside.

Signed-off-by: Kirill Smelkov k...@mns.spb.ru
---
 tree-diff.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/tree-diff.c b/tree-diff.c
index c2c67fd..f7b3ade 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -108,13 +108,14 @@ static void show_entry(struct diff_options *opt, const 
char *prefix,
 }
 
 static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
-  struct diff_options *opt,
-  enum interesting *match)
+  struct diff_options *opt)
 {
+   enum interesting match;
+
while (t-size) {
-   *match = tree_entry_interesting(t-entry, base, 0, 
opt-pathspec);
-   if (*match) {
-   if (*match == all_entries_not_interesting)
+   match = tree_entry_interesting(t-entry, base, 0, 
opt-pathspec);
+   if (match) {
+   if (match == all_entries_not_interesting)
t-size = 0;
break;
}
@@ -127,8 +128,6 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
 {
struct strbuf base;
int baselen = strlen(base_str);
-   enum interesting t1_match = entry_not_interesting;
-   enum interesting t2_match = entry_not_interesting;
 
/* Enable recursion indefinitely */
opt-pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE);
@@ -140,8 +139,8 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
if (diff_can_quit_early(opt))
break;
if (opt-pathspec.nr) {
-   skip_uninteresting(t1, base, opt, t1_match);
-   skip_uninteresting(t2, base, opt, t2_match);
+   skip_uninteresting(t1, base, opt);
+   skip_uninteresting(t2, base, opt);
}
if (!t1-size) {
if (!t2-size)
-- 
1.9.rc1.181.g641f458

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/8] combine-diff: move show_log_first logic/action out of paths scanning

2014-02-03 Thread Kirill Smelkov
Judging from sample outputs and tests nothing changes in diff -c output,
and this change will help later patches, when we'll be refactoring paths
scanning into its own function with several variants - the
show_log_first logic / code will stay common to all of them.

NOTE: only now we have to take care to explicitly not show anything if
parents array is empty, as in fact there are some clients in Git code,
which calls diff_tree_combined() in such a way.

Signed-off-by: Kirill Smelkov k...@mns.spb.ru
---
 combine-diff.c | 24 ++--
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/combine-diff.c b/combine-diff.c
index a03147c..272931f 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -1313,6 +1313,20 @@ void diff_tree_combined(const unsigned char *sha1,
struct combine_diff_path *p, *paths = NULL;
int i, num_paths, needsep, show_log_first, num_parent = parents-nr;
 
+   /* nothing to do, if no parents */
+   if (!num_parent)
+   return;
+
+   show_log_first = !!rev-loginfo  !rev-no_commit_id;
+   needsep = 0;
+   if (show_log_first) {
+   show_log(rev);
+
+   if (rev-verbose_header  opt-output_format)
+   printf(%s%c, diff_line_prefix(opt),
+  opt-line_termination);
+   }
+
diffopts = *opt;
copy_pathspec(diffopts.pathspec, opt-pathspec);
diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
@@ -1321,8 +1335,6 @@ void diff_tree_combined(const unsigned char *sha1,
/* tell diff_tree to emit paths in sorted (=tree) order */
diffopts.orderfile = NULL;
 
-   show_log_first = !!rev-loginfo  !rev-no_commit_id;
-   needsep = 0;
/* find set of paths that everybody touches */
for (i = 0; i  num_parent; i++) {
/* show stat against the first parent even
@@ -1338,14 +1350,6 @@ void diff_tree_combined(const unsigned char *sha1,
diffcore_std(diffopts);
paths = intersect_paths(paths, i, num_parent);
 
-   if (show_log_first  i == 0) {
-   show_log(rev);
-
-   if (rev-verbose_header  opt-output_format)
-   printf(%s%c, diff_line_prefix(opt),
-  opt-line_termination);
-   }
-
/* if showing diff, show it in requested order */
if (diffopts.output_format != DIFF_FORMAT_NO_OUTPUT 
opt-orderfile) {
-- 
1.9.rc1.181.g641f458

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 7/8] combine-diff: Fast changed-to-all-parents paths scanning

2014-02-03 Thread Kirill Smelkov
As was recently shown (c839f1bd combine-diff: optimize
combine_diff_path sets intersection), combine-diff runs very slowly. In
that commit we optimized paths sets intersection, but that accounted
only for ~ 25% of the slowness, and as my tracing showed, for linux.git
v3.10..v3.11, for merges a lot of time is spent computing
diff(commit,commit^2) just to only then intersect that huge diff to
almost small set of files from diff(commit,commit^1).

That's because at present, to compute combine-diff, for first finding
paths, that every parent touches, we use the following combine-diff
property/definition:

D(A,P1...Pn) = D(A,P1) ^ ... ^ D(A,Pn)  (w.r.t. paths)

where

D(A,P1...Pn) is combined diff between commit A, and parents Pi

and

D(A,Pi) is usual two-tree diff Pi..A

So if any of that D(A,Pi) is huge, tracting 1 n-parent combine-diff as n
1-parent diffs and intersecting results will be slow.

And usually, for linux.git and other topic-based workflows, that
D(A,P2) is huge, because, if merge-base of A and P2, is several dozens
of merges (from A, via first parent) below, that D(A,P2) will be diffing
sum of merges from several subsystems to 1 subsystem.

The solution is to avoid computing n 1-parent diffs, and to find
changed-to-all-parents paths via scanning A's and all Pi's trees
simultaneously, at each step comparing their entries, and based on that
comparison, populate paths result, and deduce we could *skip*
*recursing* into subdirectories, if at least for 1 parent, sha1 of that
dir tree is the same as in A. That would save us from doing significant
amount of needless work.

Such approach is very similar to what diff_tree() does, only there we
deal with scanning only 2 trees simultaneously, and for n+1 tree, the
logic is a bit more complex:

D(A,X1...Xn) calculation scheme
---

D(A,X1...Xn) = D(A,X1) ^ ... ^ D(A,Xn)   (regarding resulting paths set)

 D(A,Xj) - diff between A..Xj
 D(A,X1...Xn)- combined diff from A to parents X1,...,Xn

We start from all trees, which are sorted, and compare their entries in
lock-step:

  A X1   Xn
  - --
 |a|   |x1| |xn|
 |-|   |--| ... |--|  i = argmin(x1...xn)
 | |   |  | |  |
 |-|   |--| |--|
 |.|   |. | |. |
  . ..
  . ..

at any time there could be 3 cases:

 1)  a  xi;
 2)  a  xi;
 3)  a = xi.

Schematic deduction of what every case means, and what to do, follows:

1)  a  xi  -  ∀j a ∉ Xj  -  +a ∈ D(A,Xj)  -  D += +a;  a↓

2)  a  xi

2.1) ∃j: xj  xi  -  -xi ∉ D(A,Xj)  -  D += ø;  ∀ xk=xi  xk↓
2.2) ∀j  xj = xi  -  xj ∉ A  -  -xj ∈ D(A,Xj)  -  D += -xi;  ∀j 
xj↓

3)  a = xi

3.1) ∃j: xj  xi  -  +a ∈ D(A,Xj)  -  only xk=xi remains to 
investigate
3.2) xj = xi  -  investigate δ(a,xj)
 |
 |
 v

3.1+3.2) looking at δ(a,xk) ∀k: xk=xi - if all != ø  -

  ⎧δ(a,xk)  - if xk=xi
 -  D += ⎨
  ⎩+a - if xkxi

in any case a↓  ∀ xk=xi  xk↓

~

For comparison, here is how diff_tree() works:

D(A,B) calculation scheme
-

A B
- -
   |a|   |b|a  b   -  a ∉ B   -   D(A,B) +=  +aa↓
   |-|   |-|a  b   -  b ∉ A   -   D(A,B) +=  -bb↓
   | |   | |a = b   -  investigate δ(a,b)a↓ b↓
   |-|   |-|
   |.|   |.|
. .
. .

For now there is a limitation however - for simple scan to work, we have
to know in advance, a user had not asked for finding rename/copies
detection. At present, if he/she has, we fallback to calling old n
1-parent diffs code. I think that restriction, at least in theory,
could be lifted. I propose we have fast code for at least common case,
and move on incrementally.

Another similar limitation, is that if diffcore transforms which
filter-out paths, are active, we also fallback to old code. The reason
here is pure technical - all transforms expect to find paths in
diff_filepair's queue, which applies only to 1-parent case. If needed,
The solution here would be to generalize diff_filepair to
combine_diff_path everywhere, and do not differentiate between plain and
combined diffs (all diffs will be combined with diff(A,B) being
combined diff with only 1 parent), but again, let's move on
incrementally.

I consciously placed trees-scanning code in tree-diff.c, foreseeing diff
and combine-diff merge, and because that code is very similar to
diff_tree - to keep similar codes near.

Timings for `git log --raw --no-abbrev --no-renames` without `-c` (git log)
and with `-c` (git log -c) and with `-c --merges` (git log -c --merges)
before and after the patch are as follows:

linux.git v3.10..v3.11

log log -c log -c 

[PATCH 2/8] tests: add checking that combine-diff emits only correct paths

2014-02-03 Thread Kirill Smelkov
where correct paths stands for paths that are different to all
parents.

Up until now, we were testing combined diff only on one file, or on
several files which were all different (t4038-diff-combined.sh).

As recent thinko in simplify intersect_paths() further showed, and
also, since we are going to rework code for finding paths different to
all parents, lets write at least basic tests.

Signed-off-by: Kirill Smelkov k...@mns.spb.ru
---
 t/t4057-diff-combined-paths.sh | 106 +
 1 file changed, 106 insertions(+)
 create mode 100755 t/t4057-diff-combined-paths.sh

diff --git a/t/t4057-diff-combined-paths.sh b/t/t4057-diff-combined-paths.sh
new file mode 100755
index 000..e6e457d
--- /dev/null
+++ b/t/t4057-diff-combined-paths.sh
@@ -0,0 +1,106 @@
+#!/bin/sh
+
+test_description='combined diff show only paths that are different to all 
parents'
+
+. ./test-lib.sh
+
+# verify that diffc.expect matches output of
+# `git diff -c --name-only HEAD HEAD^ HEAD^2`
+diffc_verify() {
+   git diff -c --name-only HEAD HEAD^ HEAD^2 diffc.actual 
+   test_cmp diffc.expect diffc.actual
+}
+
+test_expect_success 'trivial merge - combine-diff empty' '
+   for i in `test_seq 1 9`
+   do
+   echo $i $i.txt 
+   git add $i.txt
+   done 
+   git commit -m init 
+   git checkout -b side 
+   for i in `test_seq 2 9`
+   do
+   echo $i/2 $i.txt
+   done 
+   git commit -a -m side 2-9 
+   git checkout master 
+   echo 1/2 1.txt 
+   git commit -a -m master 1 
+   git merge side 
+   diffc.expect 
+   diffc_verify
+'
+
+
+test_expect_success 'only one trully conflicting path' '
+   git checkout side 
+   for i in `test_seq 2 9`
+   do
+   echo $i/3 $i.txt
+   done 
+   echo 4side 4.txt 
+   git commit -a -m side 2-9 +4 
+   git checkout master 
+   for i in `test_seq 1 9`
+   do
+   echo $i/3 $i.txt
+   done 
+   echo 4master 4.txt 
+   git commit -a -m master 1-9 +4 
+   test_must_fail git merge side 
+   cat -\EOF 4.txt 
+   4
+   4/2
+   4/3
+   4master
+   4side
+   EOF
+   git add 4.txt 
+   git commit -m merge side (2) 
+   echo 4.txt diffc.expect 
+   diffc_verify
+'
+
+test_expect_success 'merge introduces new file' '
+   git checkout side 
+   for i in `test_seq 5 9`
+   do
+   echo $i/4 $i.txt
+   done 
+   git commit -a -m side 5-9 
+   git checkout master 
+   for i in `test_seq 1 3`
+   do
+   echo $i/4 $i.txt
+   done 
+   git commit -a -m master 1-3 +4hello 
+   git merge side 
+   echo Hello World 4hello.txt 
+   git add 4hello.txt 
+   git commit --amend 
+   echo 4hello.txt diffc.expect 
+   diffc_verify
+'
+
+test_expect_success 'merge removed a file' '
+   git checkout side 
+   for i in `test_seq 5 9`
+   do
+   echo $i/5 $i.txt
+   done 
+   git commit -a -m side 5-9 
+   git checkout master 
+   for i in `test_seq 1 3`
+   do
+   echo $i/4 $i.txt
+   done 
+   git commit -a -m master 1-3 
+   git merge side 
+   git rm 4.txt 
+   git commit --amend 
+   echo 4.txt diffc.expect 
+   diffc_verify
+'
+
+test_done
-- 
1.9.rc1.181.g641f458

--
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 5/5] setup: Don't dereference in-tree symlinks for absolute paths

2014-02-03 Thread Martin Erik Werner
On Mon, Feb 03, 2014 at 11:15:57AM +0700, Duy Nguyen wrote:
 On Sun, Feb 2, 2014 at 11:35 PM, Martin Erik Werner
 martinerikwer...@gmail.com wrote:
  diff --git a/setup.c b/setup.c
  index a2e60ab..230505c 100644
  --- a/setup.c
  +++ b/setup.c
  @@ -86,11 +86,23 @@ char *prefix_path_gently(const char *prefix, int len,
  const char *orig = path;
  char *sanitized;
  if (is_absolute_path(orig)) {
  -   const char *temp = real_path(path);
  -   sanitized = xmalloc(len + strlen(temp) + 1);
  -   strcpy(sanitized, temp);
  +   char *npath;
  +
  +   npath = xmalloc(strlen(path) + 1);
  if (remaining_prefix)
  *remaining_prefix = 0;
  +   if (normalize_path_copy_len(npath, path, remaining_prefix)) 
  {
  +   free(npath);
  +   return NULL;
  +   }
  +   if (abspath_part_inside_repo(npath)) {
  +   free(npath);
  +   return NULL;
  +   }
  +
  +   sanitized = xmalloc(strlen(npath) + 1);
  +   strcpy(sanitized, npath);
  +   free(npath);
 
 We could replace these three lines with sanitized = npath;. But it's
 not a big deal imo. The rest of the series looks good.
 
 Reviewed-by: Duy Nguyen pclo...@gmail.com
 
  } else {
  sanitized = xmalloc(len + strlen(path) + 1);
  if (len)
 -- 
 Duy

Thank you for reviewing! And thanks Torsten and Junio Likewise. (And
thanks Richard for initial triggering and brief discussion of the bug :)

Hmm, yeah I don't really know what to prefer out of a. Two mallocs with
only a minimal one returned or 2. Single, potentially non-minimal, malloc
returned, if it makes little difference, for simplicity the latter seems nicer.

Then it seems like one could get rid of npath completely:

diff --git a/setup.c b/setup.c
index 230505c..dd120cd 100644
--- a/setup.c
+++ b/setup.c
@@ -88,21 +88,17 @@ char *prefix_path_gently(const char *prefix, int len,
if (is_absolute_path(orig)) {
char *npath;
 
-   npath = xmalloc(strlen(path) + 1);
+   sanitized = xmalloc(strlen(path) + 1);
if (remaining_prefix)
*remaining_prefix = 0;
-   if (normalize_path_copy_len(npath, path, remaining_prefix)) {
-   free(npath);
+   if (normalize_path_copy_len(sanitized, path, remaining_prefix)) 
{
+   free(sanitized);
return NULL;
}
-   if (abspath_part_inside_repo(npath)) {
-   free(npath);
+   if (abspath_part_inside_repo(sanitized)) {
+   free(sanitized);
return NULL;
}
-
-   sanitized = xmalloc(strlen(npath) + 1);
-   strcpy(sanitized, npath);
-   free(npath);
} else {
sanitized = xmalloc(len + strlen(path) + 1);
if (len)

at the cost of 'sanitized' always being the length of path, regardless
if it's shorter, or even a NUL string.

--
Martin Erik Werner martinerikwer...@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: Running make rpm fails on a CentOS 6.3 machine

2014-02-03 Thread Todd Zullinger

Erez Zilber wrote:
Thanks. Just making sure - I need to do all of this on a fedora 
machine, not a RHEL/CentOS machine, right?


Nope.  An el6 box makes a fine mock host for el6 and (usually) fedora 
targets (though the mock package in EPEL doesn't always have config 
files for the very latest fedora release).  The builder I use for my 
packages on el6 is an el6 host.


--
ToddOpenPGP - KeyID: 0xBEAF0CE3 | URL: www.pobox.com/~tmz/pgp
~~
Don't look for me in daylight where robots all assemble.  You'll find
me in my dark world, in my smoke-filled temple.



pgpbG1cPqoleK.pgp
Description: PGP signature


Re: Running make rpm fails on a CentOS 6.3 machine

2014-02-03 Thread Martin Langhoff
On Sun, Feb 2, 2014 at 4:07 PM, Todd Zullinger t...@pobox.com wrote:
 # Install fedpkg
 $ yum install fedpkg

fedpkg is amazing. I (ab)use it (and the associated build machinery)
for lots of private package builds.

 # Create an el6 srpm
 $ fedpkg --dist el6 srpm

here I just say fedpkg --dist el6 mockbuild and it makes the srpm
and the binaries in mock. Automagic.

 /var/lib/mock/epel-6-x86_64/result/.

with mockbuild the packages appear in a subdir of where I'm working.


m
-- 
 martin.langh...@gmail.com
 -  ask interesting questions
 - don't get distracted with shiny stuff  - working code first
 ~ http://docs.moodle.org/en/User:Martin_Langhoff
--
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: Running make rpm fails on a CentOS 6.3 machine

2014-02-03 Thread Todd Zullinger

Martin Langhoff wrote:
# Create an el6 srpm 
$ fedpkg --dist el6 srpm


here I just say fedpkg --dist el6 mockbuild and it makes the srpm 
and the binaries in mock. Automagic.


Heh, and I thought I mentioning that, but since I never use it I 
didn't want to have to test it before including it and sending anyone 
down a rabbit hole. :)



/var/lib/mock/epel-6-x86_64/result/.


with mockbuild the packages appear in a subdir of where I'm working.


Cool.  I'll have to make more use of that now.  Thanks Martin!

--
ToddOpenPGP - KeyID: 0xBEAF0CE3 | URL: www.pobox.com/~tmz/pgp
~~
I have to decide between two equally frightening options.  If I wanted
to do that, I'd vote.
-- Duckman



pgpqtDEW1t_0G.pgp
Description: PGP signature


Re: A few contributor's questions

2014-02-03 Thread Andreas Ericsson
On 2014-01-31 14:04, David Kastrup wrote:
 
 I'm still in the process of finishing the rewrite of the builtin/blame.c
 internals.  Now there are various questions regarding the final patch
 proposals and commit messages.
 
 Point 1) signing off implies that I'm fine with the licensing of the
 file. builtin/blame.c merely states
 
 /*
  * Blame
  *
  * Copyright (c) 2006, Junio C Hamano
  */
 
 which obviously will not match the authorship of my contributions.
 Since Junio has given blanket permission to reuse his Git contributions
 under other licenses (see
 URL:https://github.com/libgit2/libgit2/blob/development/git.git-authors#L58)
 that I am not going to license my work under, the first commit in the
 respective series would replace this header with
 

It's a long time since I wrote that document.

Does this mean you're not willing to relicense your contributions with
the license used by libgit2? That's what the document is supposed to
mean and it's what I asked on the mailing list when requesting
permission.

The libgit2 license used as of today is still the license that people
agreed to relicense their contributions under. It can be found here:
https://github.com/libgit2/libgit2/blob/development/.HEADER

I'm mostly adding it here for the sake of clarity in case people find
this in the future and wonder what all the fuzz was about.

-- 
Andreas Ericsson   andreas.erics...@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225  Fax: +46 8-230231

Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.
--
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.c: always honor the filename case

2014-02-03 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 [+cc Joshua Jensen, who wrote 50906e0]

 On Sun, Feb 02, 2014 at 07:13:04AM -0600, Reuben Hawkins wrote:

 fast-import should not use strncmp_icase.

 I am not sure of that. My gut feeling is that core.ignorecase is
 completely about the _filesystem_, and that git should generally be
 case-sensitive internally.

I agree; if squashing mixed cases into a single canonical one is
desired in one use case (like Joshua described in $gmane/200597),
that should have been done as an optional feature, not by default
(ideally, it should probably be done in a filter between exporters
and the fast-import, I would think).

 [1] I am mostly trying to connect people on various sides of the
 discussion here. So take my gut feeling above with a grain of
 salt, as it does not come from experience nor thinking too hard
 about the issue.

Thanks; that is exactly what is expected of project elders ;-)
--
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: A few contributor's questions

2014-02-03 Thread David Kastrup
Andreas Ericsson a...@op5.se writes:

 On 2014-01-31 14:04, David Kastrup wrote:
 
 I'm still in the process of finishing the rewrite of the builtin/blame.c
 internals.  Now there are various questions regarding the final patch
 proposals and commit messages.
 
 Point 1) signing off implies that I'm fine with the licensing of the
 file. builtin/blame.c merely states
 
 /*
  * Blame
  *
  * Copyright (c) 2006, Junio C Hamano
  */
 
 which obviously will not match the authorship of my contributions.
 Since Junio has given blanket permission to reuse his Git contributions
 under other licenses (see
 URL:https://github.com/libgit2/libgit2/blob/development/git.git-authors#L58)
 that I am not going to license my work under, the first commit in the
 respective series would replace this header with

 It's a long time since I wrote that document.

 Does this mean you're not willing to relicense your contributions with
 the license used by libgit2? That's what the document is supposed to
 mean and it's what I asked on the mailing list when requesting
 permission.

I make a living from writing Free Software.  It should hardly come as a
surprise that I will not hand libgit2 users like Microsoft or GitHub
software for unrestricted use in proprietary products without getting
recompensated.  They make money from their products without sharing
their code back.

So I'm not going to relicense my work under the libgit2 license
_without_ _recompensation_, for use by companies that don't license
their work without recompensation.  It would be grossly unfair towards
those people who actually pay me for writing GPLed software (mostly GNU
LilyPond).  Of course I regularly report what I worked on, and I expect
a temporary drop in my funding corresponding to the lack of
LilyPond-related activities.  So there is an actual cost for me to bear,
and I will not bear it myself in order to support proprietary
derivatives.

So the price tag for letting the finished git-blame work (I've found a
few more optimizations making it more worthwhile) get relicensed under
the libgit2 licensing scheme would be in the order of €1.  It would
take a rather good salaried programmer to reproduce what I'm doing right
now for the same price tag, and since my work will be available in Git
proper under the GPLv2 before anybody has to make any decision, there is
no uncertainty about exactly what people will be getting.

If there is going to be significant use of the git-blame functionality
by libgit2, I claim that the gain in efficiency (and programming time)
would more than offset the cost.

And if there isn't going to be significant use of that functionality,
it's not important whether it's in libgit2 or not.

 The libgit2 license used as of today is still the license that people
 agreed to relicense their contributions under. It can be found here:
 https://github.com/libgit2/libgit2/blob/development/.HEADER

That's actually the license on some files.  The overall license
statement in
URL:https://github.com/libgit2/libgit2/blob/development/COPYING
suggests that the libgit2 code base encompasses quite more components.
Some of those are mentioned as being licensed under the Apache 2.0
license, incompatible to GPLv2 according to
URL:https://www.apache.org/licenses/GPL-compatibility.html.  Since the
GPL requires licensing of a work _as_ _a_ _whole_, it's not really all
too obvious to me whether any part but the linking/unmodified-binary
exception will actually be effective.

But that's pure speculation on my part (I am obviously not a lawyer) and
no skin off my nose if somebody wants to invest the price for releasing
under whatever licensing scheme libgit2 happens to use.  If libgit2 or a
variant of it reverts to unmodified GPLv2 (or later) at any point of
time, they are free to just take what is there without having to
negotiate with me (or anybody else), anyway.

And of course, calling the git executable and letting it do the work
will also remain an option.  That's likely what the simple git web
services do anyway.  git blame is usually disabled in web interfaces
for performance reasons, and I'm afraid that even a factor of 3--4 in
speed (which is what I'm getting with uglier real-world cases) is not
going to change that.

 I'm mostly adding it here for the sake of clarity in case people find
 this in the future and wonder what all the fuzz was about.

It's probably easy to notice that I can make a lot of fuzz about small
things.  It's probably less annoying when I do it in code rather than in
prose...

-- 
David Kastrup
--
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: Creating own hierarchies under $GITDIR/refs ?

2014-02-03 Thread Andreas Schwab
David Kastrup d...@gnu.org writes:

 Are there some measures one can take/configure in the parent repository
 such that (named or all) additional directories inside of $GITDIR/refs
 would get cloned along with the rest?

$ git config --add remote.orgin.fetch '+refs/notes/*:refs/notes/*'

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
And now for something completely different.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 9/9] pull: add the --gpg-sign option.

2014-02-03 Thread Junio C Hamano
brian m. carlson sand...@crustytoothpaste.net writes:

 ...  It also happens to fix the issue where the help
 text is improperly quoted.  With your suggested fix, it is now quoted
 (ugly, but quoted):

I do not see anything ugly about the output below.  Of course you
could do -S'brian ...', but both look sensible.

   Stopped at aba3d3ff83b59627adbdafe1b334a46ed5b7ec17... am: add the 
 --gpg-sign option
   You can amend the commit now, with
   
   git commit --amend  '-Sbrian m. carlson sand...@crustytoothpaste.net'

 Since I expect most users are going to use -S, either because they have
 a key specifically specified in .gitconfig, or because the default key
 is the right thing anyway, I don't see this as a huge problem.  I think
 I'll probably end up fixing it anyway and then send out the reroll.
--
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: Running make rpm fails on a CentOS 6.3 machine

2014-02-03 Thread Junio C Hamano
Todd Zullinger t...@pobox.com writes:

 I know the Fedora/EPEL spec file and what's in git.git have grown
 apart a good bit, unfortunately.  That's the cost of having a spec
 file that is meant to work across a very wide array of RPM-based
 systems, I guess.  The Fedora/EPEL spec file is fairly specific to the
 Fedora/EPEL build tools (mock is the primary build tool).

Hmph.

Once it gets to the point where our spec file is so out of sync
with anybody's RPM based distribution in the real world, I suspect
that removing and not shipping it in tree might be more helpful to
the users.  Or at least have a set of pointers, one for each major
RPM based distribution, where to obtain spec file more tailored for
their platform, at the beginning of it, or something.

Have we already reached that point?  Does anybody still use it?
--
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: splitting a commit that adds new files

2014-02-03 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 [1] I _do_ use reset -p when splitting commits, but I do not think it
 is useful here. I use it for oops, I staged this change, but it
 actually belongs in the next commit. Undo my staging, but leave the
 changes in the working tree for the next one.

Sure.  I thought that was exactly what Duy was attempting to do when
he splitted a commit into two (or more).
--
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] userdiff: update Ada patterns

2014-02-03 Thread George Spelvin
Looking at the grammar at http://www.adahome.com/rm95/rm9x-P.html
and http://www.adaic.org/resources/add_content/standards/05rm/html/RM-2-4.html
I see the following restrictions apply:

- A number must begin and end with a digit.  There must be at least one
  digit on either side of each underscore and decimal point.
- There may be at most one decimal point in a number.
- The base must be between 2 and 16, inclusive.

[-+]?(
[0-9](_?[0-9])*([.][0-9](_?[0-9])*)?|

([2-9]|1[0-6])#[0-9a-fA-F](_?[0-9a-fA-F])*([.][0-9a-fA-F](_?[0-9a-fA-F])*)?#
)([eE][+-]?[0-9](_?[0-9])*)?

If you want a slightly smaller version, we can drop the only one decimal
point rule and get

[-+]?(
[0-9]([._]?[0-9])*|
([2-9]|1[0-6])#[0-9a-fA-F]([._]?[0-9a-fA-F])*#
)([eE][+-]?[0-9](_?[0-9])*)?

Ideally, for a based number, the range of acceptable digits would
depend on the base.  Which is possible for a finite-state machine since
the number of bases is finite, but laeds to a bit of a state explosion.
Here's an approximation that separates bases 2-9 and 10-16:

[-+]?(
[0-9](_?[0-9])*([.][0-9](_?[0-9])*)?|
[2-9]#[0-8](_?[0-8])*([.][0-8](_?[0-8])*)?#|
1[0-6]#[0-9a-fA-F](_?[0-9a-fA-F])*([.][0-9a-fA-F](_?[0-9a-fA-F])*)?#
)([eE][+-]?[0-9](_?[0-9])*)?

because I think that this is overdoing it:

[-+]?(
[0-9](_?[0-9])*([.][0-9](_?[0-9])*)?|
2#[0-1](_?[0-1])*([.][0-1](_?[0-1])*)?#|
3#[0-2](_?[0-2])*([.][0-2](_?[0-2])*)?#|
4#[0-3](_?[0-3])*([.][0-3](_?[0-3])*)?#|
5#[0-4](_?[0-4])*([.][0-4](_?[0-4])*)?#|
6#[0-5](_?[0-5])*([.][0-5](_?[0-5])*)?#|
7#[0-5](_?[0-5])*([.][0-5](_?[0-5])*)?#|
8#[0-7](_?[0-7])*([.][0-7](_?[0-7])*)?#|
9#[0-8](_?[0-8])*([.][0-8](_?[0-8])*)?#|
10#[0-9](_?[0-9])*([.][0-9](_?[0-9])*)?#|
11#[0-9aA](_?[0-9aA])*([.][0-9aA](_?[0-9aA])*)?#|
12#[0-9abAB](_?[0-9abAB])*([.][0-9abAB](_?[0-9abAB])*)?#|
13#[0-9a-cA-C](_?[0-9a-cA-C])*([.][0-9a-cA-C](_?[0-9a-cA-C])*)?#|
14#[0-9a-dA-D](_?[0-9a-dA-D])*([.][0-9a-dA-D](_?[0-9a-dA-D])*)?#|
15#[0-9a-eA-E](_?[0-9a-eA-E])*([.][0-9a-eA-E](_?[0-9a-eA-E])*)?#|
16#[0-9a-fA-F](_?[0-9a-fA-F])*([.][0-9a-fA-F](_?[0-9a-fA-F])*)?#|
)([eE][+-]?[0-9](_?[0-9])*)?

Another point is that Ada doesn't actually include leading + or -
signs in the syntax for number, but rather makes them unary operators.
This means that spaces are allowed, and whether you want to include them
in the number pattern is a judgement call.
--
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/5] t0060: Add test for manipulating symlinks via absolute paths

2014-02-03 Thread Junio C Hamano
Martin Erik Werner martinerikwer...@gmail.com writes:

 When symlinks in the working tree are manipulated using the absolute
 path, git dereferences them, and tries to manipulate the link target
 instead.

The above may a very good description of the root cause, but
can we have description of a symptom that is visible by end-users
that is caused by the bug being fixed with the series here, by
ending the above like so:

... link target instead.  This causes git foo bar to
misbehave in this and that way.

Testing the low-level underlying machinery like this patch does is
not wrong per-se, but I suspect that this series was triggered by
somebody noticing breakage in a end-user command git foo $path
with $path being a full pathname to an in-tree symbolic link.  It
wouldn't be like somebody who was bored and ran test-path-utils
for fun noticed the root cause without realizing how the fix would
affect the behaviour that would be visible to end-users, right?

Can we have that git foo $path to the testsuite as well?  That is
the breakage we do not want to repeat in the future by regressing.

I am guessing foo is add, but I wasn't closely following the
progression of the series.

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


[PATCH 0/5] git-blame: further performance preview

2014-02-03 Thread David Kastrup
Ok, I'm progressing rather like molasses with getting -M and -C
options back to work.  In the mean time, here is another performance
preview without them.  The main patch in the middle has basically
gotten some formatting/style fixes as opposed to last time round and
one small bug fix (concerning incremental output).

It still contains a significant amount of dead code: this series is
not supposed to be merged, it's just supposed to be exciting to see
how it performs.

There are two simple performance patches on top of the main patch, the
first of which offers somewhat significant savings in I/O time (which
was quite unaffected by the main rewrite so far).  The gist of that
patch makes convenient use of the changed data layout to avoid
discarding blob data predictably required again right away.

It's likely that this is not the only opportunity to save performance
by better data management.

The second performance patch is not likely to measurably affect
overall performance.  Avoiding irrelevant iterations might make
debugging more pleasant, however.

David Kastrup (5):
  builtin/blame.c: struct blame_entry does not need a prev link
  Eliminate same_suspect function in builtin/blame.c
  builtin/blame.c: large-scale rewrite
  Performance improvement: don't drop origin blobs that are going to get
tested next.
  Avoid queuing commits multiple times for the same origin

 builtin/blame.c | 595 +++-
 1 file changed, 371 insertions(+), 224 deletions(-)

-- 
1.8.3.2
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/5] builtin/blame.c: struct blame_entry does not need a prev link

2014-02-03 Thread David Kastrup
Signed-off-by: David Kastrup d...@gnu.org
---
 builtin/blame.c | 13 ++---
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index e44a6bb..2195595 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -197,7 +197,6 @@ static void drop_origin_blob(struct origin *o)
  * scoreboard structure, sorted by the target line number.
  */
 struct blame_entry {
-   struct blame_entry *prev;
struct blame_entry *next;
 
/* the first line of this group in the final image;
@@ -282,8 +281,6 @@ static void coalesce(struct scoreboard *sb)
ent-s_lno + ent-num_lines == next-s_lno) {
ent-num_lines += next-num_lines;
ent-next = next-next;
-   if (ent-next)
-   ent-next-prev = ent;
origin_decref(next-suspect);
free(next);
ent-score = 0;
@@ -534,7 +531,7 @@ static void add_blame_entry(struct scoreboard *sb, struct 
blame_entry *e)
prev = ent;
 
/* prev, if not NULL, is the last one that is below e */
-   e-prev = prev;
+
if (prev) {
e-next = prev-next;
prev-next = e;
@@ -543,8 +540,6 @@ static void add_blame_entry(struct scoreboard *sb, struct 
blame_entry *e)
e-next = sb-ent;
sb-ent = e;
}
-   if (e-next)
-   e-next-prev = e;
 }
 
 /*
@@ -555,14 +550,12 @@ static void add_blame_entry(struct scoreboard *sb, struct 
blame_entry *e)
  */
 static void dup_entry(struct blame_entry *dst, struct blame_entry *src)
 {
-   struct blame_entry *p, *n;
+   struct blame_entry *n;
 
-   p = dst-prev;
n = dst-next;
origin_incref(src-suspect);
origin_decref(dst-suspect);
memcpy(dst, src, sizeof(*src));
-   dst-prev = p;
dst-next = n;
dst-score = 0;
 }
@@ -2502,8 +2495,6 @@ parse_done:
ent-suspect = o;
ent-s_lno = bottom;
ent-next = next;
-   if (next)
-   next-prev = ent;
origin_incref(o);
}
origin_decref(o);
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/5] builtin/blame.c: large-scale rewrite

2014-02-03 Thread David Kastrup
The previous implementation uses a sorted linear list of struct
blame_entry in a struct scoreboard for organizing all partial or
completed work.  Every task that is done requires going through the
whole list where most entries are not relevant to the task at hand.

This commit reorganizes the data structures in order to have each
remaining subtask work with its own sorted linear list it can work off
front to back.  Subtasks are organized into struct origin chains
hanging off particular commits.  Commits are organized into a priority
queue, processing them in commit date order in order to keep most of
the work affecting a particular blob collated even in the presence of
an extensive merge history.  In that manner, linear searches can be
basically avoided anywhere.  They still are done for identifying one
of multiple analyzed files in a given commit, but the degenerate case
of a single large file being assembled from a multitude of smaller
files in the past is not likely to occur often enough to warrant
special treatment.
---
 builtin/blame.c | 559 
 1 file changed, 358 insertions(+), 201 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index ead6148..e881b6e 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -18,7 +18,9 @@
 #include cache-tree.h
 #include string-list.h
 #include mailmap.h
+#include mergesort.h
 #include parse-options.h
+#include prio-queue.h
 #include utf8.h
 #include userdiff.h
 #include line-range.h
@@ -83,11 +85,43 @@ static unsigned blame_copy_score;
  */
 struct origin {
int refcnt;
+   /* Record preceding blame record for this blob */
struct origin *previous;
+   /* origins are put in a list linked via `next' hanging off the
+* corresponding commit's util field in order to make finding
+* them fast.  The presence in this chain does not count
+* towards the origin's reference count.  It is tempting to
+* let it count as long as the commit is pending examination,
+* but even under circumstances where the commit will be
+* present multiple times in the priority queue of unexamined
+* commits, processing the first instance will not leave any
+* work requiring the origin data for the second instance.  An
+* interspersed commit changing that would have to be
+* preexisting with a different ancestry and with the same
+* commit date in order to wedge itself between two instances
+* of the same commit in the priority queue _and_ produce
+* blame entries relevant for it.  While we don't want to let
+* us get tripped up by this case, it certainly does not seem
+* worth optimizing for.
+*/
+   struct origin *next;
struct commit *commit;
+   /* `suspects' contains blame entries that may be attributed to
+* this origin's commit or to parent commits.  When a commit
+* is being processed, all suspects will be moved, either by
+* assigning them to an origin in a different commit, or by
+* shipping them to the scoreboard's ent list because they
+* cannot be attributed to a different commit.
+*/
+   struct blame_entry *suspects;
mmfile_t file;
unsigned char blob_sha1[20];
unsigned mode;
+   /* shipped gets set when shipping any suspects to the final
+* blame list instead of other commits
+*/
+   char shipped;
+   char guilty;
char path[FLEX_ARRAY];
 };
 
@@ -176,10 +210,22 @@ static inline struct origin *origin_incref(struct origin 
*o)
 static void origin_decref(struct origin *o)
 {
if (o  --o-refcnt = 0) {
+   struct origin *p, *l = NULL;
if (o-previous)
origin_decref(o-previous);
free(o-file.ptr);
-   free(o);
+   /* Should be present exactly once in commit chain */
+   for (p = o-commit-util; p; l = p, p = p-next) {
+   if (p == o) {
+   if (l)
+   l-next = p-next;
+   else
+   o-commit-util = p-next;
+   free(o);
+   return;
+   }
+   }
+   die(internal error in blame::origin_decref);
}
 }
 
@@ -193,8 +239,12 @@ static void drop_origin_blob(struct origin *o)
 
 /*
  * Each group of lines is described by a blame_entry; it can be split
- * as we pass blame to the parents.  They form a linked list in the
- * scoreboard structure, sorted by the target line number.
+ * as we pass blame to the parents.  They are arranged in linked lists
+ * kept as `suspects' of some unprocessed origin, or entered (when the
+ * blame origin has been finalized) into the scoreboard structure.
+ * While the scoreboard 

[PATCH 2/5] Eliminate same_suspect function in builtin/blame.c

2014-02-03 Thread David Kastrup
Since the origin pointers are interned and reference-counted, comparing
the pointers rather than the content is enough.  The only uninterned
origins are cached values kept in commit-util, but same_suspect is not
called on them.

Signed-off-by: David Kastrup d...@gnu.org
---
 builtin/blame.c | 25 -
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index 2195595..ead6148 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -255,15 +255,6 @@ struct scoreboard {
int *lineno;
 };
 
-static inline int same_suspect(struct origin *a, struct origin *b)
-{
-   if (a == b)
-   return 1;
-   if (a-commit != b-commit)
-   return 0;
-   return !strcmp(a-path, b-path);
-}
-
 static void sanity_check_refcnt(struct scoreboard *);
 
 /*
@@ -276,7 +267,7 @@ static void coalesce(struct scoreboard *sb)
struct blame_entry *ent, *next;
 
for (ent = sb-ent; ent  (next = ent-next); ent = next) {
-   if (same_suspect(ent-suspect, next-suspect) 
+   if (ent-suspect == next-suspect 
ent-guilty == next-guilty 
ent-s_lno + ent-num_lines == next-s_lno) {
ent-num_lines += next-num_lines;
@@ -735,7 +726,7 @@ static int find_last_in_target(struct scoreboard *sb, 
struct origin *target)
int last_in_target = -1;
 
for (e = sb-ent; e; e = e-next) {
-   if (e-guilty || !same_suspect(e-suspect, target))
+   if (e-guilty || e-suspect != target)
continue;
if (last_in_target  e-s_lno + e-num_lines)
last_in_target = e-s_lno + e-num_lines;
@@ -755,7 +746,7 @@ static void blame_chunk(struct scoreboard *sb,
struct blame_entry *e;
 
for (e = sb-ent; e; e = e-next) {
-   if (e-guilty || !same_suspect(e-suspect, target))
+   if (e-guilty || e-suspect != target)
continue;
if (same = e-s_lno)
continue;
@@ -985,7 +976,7 @@ static int find_move_in_parent(struct scoreboard *sb,
while (made_progress) {
made_progress = 0;
for (e = sb-ent; e; e = e-next) {
-   if (e-guilty || !same_suspect(e-suspect, target) ||
+   if (e-guilty || e-suspect != target ||
ent_score(sb, e)  blame_move_score)
continue;
find_copy_in_blob(sb, e, parent, split, file_p);
@@ -1020,14 +1011,14 @@ static struct blame_list *setup_blame_list(struct 
scoreboard *sb,
 
for (e = sb-ent, num_ents = 0; e; e = e-next)
if (!e-scanned  !e-guilty 
-   same_suspect(e-suspect, target) 
+   e-suspect == target 
min_score  ent_score(sb, e))
num_ents++;
if (num_ents) {
blame_list = xcalloc(num_ents, sizeof(struct blame_list));
for (e = sb-ent, i = 0; e; e = e-next)
if (!e-scanned  !e-guilty 
-   same_suspect(e-suspect, target) 
+   e-suspect == target 
min_score  ent_score(sb, e))
blame_list[i++].ent = e;
}
@@ -1171,7 +1162,7 @@ static void pass_whole_blame(struct scoreboard *sb,
origin-file.ptr = NULL;
}
for (e = sb-ent; e; e = e-next) {
-   if (!same_suspect(e-suspect, origin))
+   if (e-suspect != origin)
continue;
origin_incref(porigin);
origin_decref(e-suspect);
@@ -1560,7 +1551,7 @@ static void assign_blame(struct scoreboard *sb, int opt)
 
/* Take responsibility for the remaining entries */
for (ent = sb-ent; ent; ent = ent-next)
-   if (same_suspect(ent-suspect, suspect))
+   if (ent-suspect == suspect)
found_guilty_entry(ent);
origin_decref(suspect);
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/5] Performance improvement: don't drop origin blobs that are going to get tested next.

2014-02-03 Thread David Kastrup
---
 builtin/blame.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index e881b6e..0188115 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1435,7 +1435,8 @@ static void pass_blame(struct scoreboard *sb, struct 
origin *origin, int opt)
  finish:
for (i = 0; i  num_sg; i++) {
if (sg_origin[i]) {
-   drop_origin_blob(sg_origin[i]);
+   if (!sg_origin[i]-suspects)
+   drop_origin_blob(sg_origin[i]);
origin_decref(sg_origin[i]);
}
}
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] Avoid queuing commits multiple times for the same origin

2014-02-03 Thread David Kastrup
---
 builtin/blame.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index 0188115..80345db 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -928,9 +928,12 @@ static int pass_blame_to_parent(struct scoreboard *sb,
/* The rest are the same as the parent */
blame_chunk(d.dstq, d.srcq, INT_MAX, d.offset, INT_MAX, target, 
parent);
*d.dstq = NULL;
-   parent-suspects = blame_merge(parent-suspects, newdest);
if (parent-suspects)
+   parent-suspects = blame_merge(parent-suspects, newdest);
+   else if (newdest) {
+   parent-suspects = newdest;
prio_queue_put(sb-commits, parent-commit);
+   }
 
return 0;
 }
@@ -1303,8 +1306,12 @@ static void pass_whole_blame(struct scoreboard *sb,
origin_decref(e-suspect);
e-suspect = porigin;
}
-   porigin-suspects = blame_merge(porigin-suspects, suspects);
-   prio_queue_put(sb-commits, porigin-commit);
+   if (porigin-suspects)
+   porigin-suspects = blame_merge(porigin-suspects, suspects);
+   else if (suspects) {
+   porigin-suspects = suspects;
+   prio_queue_put(sb-commits, porigin-commit);
+   }
 }
 
 /*
-- 
1.8.3.2

--
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 1/8] fixup! combine_diff: simplify intersect_paths() further

2014-02-03 Thread Junio C Hamano
Kirill Smelkov k...@mns.spb.ru writes:

 That cleanup patch is good, but I've found a bug in it. In the item removal
 code

 +  /* p-path not in q-queue[]; drop it */
 +  struct combine_diff_path *next = p-next;
 +
 +  if ((*tail = next) != NULL)
 +  tail = next-next;
 +  free(p);
continue;

 *tail = next

 is right, but

 tail = next-next

 is wrong,

Heh, surely.  We just have skipped, and the fact that tail points at
the pointer variable that points at the first of the remaining items
does not change with this skipping of next by assigning it to *tail.  
An extra assignment to tail will skip one more, which is unnecessary.
--
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


[WIP/PATCH 0/9] v2 submodule recursive checkout]

2014-02-03 Thread Jens Lehmann
Am 07.01.2014 18:55, schrieb Junio C Hamano:
 Jens Lehmann jens.lehm...@web.de writes:
 
 Am 06.01.2014 23:36, schrieb Junio C Hamano:
 * jl/submodule-recursive-checkout (2013-12-26) 5 commits
  - Teach checkout to recursively checkout submodules
  - submodule: teach unpack_trees() to update submodules
  - submodule: teach unpack_trees() to repopulate submodules
  - submodule: teach unpack_trees() to remove submodule contents
  - submodule: prepare for recursive checkout of submodules

  What is the doneness of this one???

 It's still work in progress. Currently I'm working on a test
 framework so we can reuse recursive submodule checkout tests
 instead of rewriting them for every command that learns the
 --recurse-submodule option. Will reroll this series as soon
 as I have something presentable.
 
 Thanks.

Ok, time for another round. This is still WIP/RFC and not
ready to be merged yet, but I believe this round makes it a
bit more clear where this is heading.

Changes to the first version are:

- Reordered the commits according to Jonathan's proposal
  (this currently makes the checkout tests fail until the
  last commit completes the functionality; this will be
  fixed when the test framework is added)

- Fixed calling parse_fetch_recurse_submodules_arg() where
  parse_update_recurse_submodules_arg() must be used.

- Moved the documentation of the --[no-]recurse-submodule
  option into an include file so different commands can
  reuse it.

- Added the --[no-]recurse-submodule option to bisect, merge
  and reset too.

Tests, documentation and commit messages are not complete yet,
I'll work on them in the next rounds. The wiki page in my Github
repository will describe the current status of this series:

  
https://github.com/jlehmann/git-submod-enhancements/wiki/Recursive-submodule-checkout


Jens Lehmann (9):
  submodule: prepare for recursive checkout of submodules
  Teach reset the --[no-]recurse-submodules option
  Teach checkout the --[no-]recurse-submodules option
  Teach merge the --[no-]recurse-submodules option
  Teach bisect--helper the --[no-]recurse-submodules option
  Teach bisect the --[no-]recurse-submodules option
  submodule: teach unpack_trees() to remove submodule contents
  submodule: teach unpack_trees() to repopulate submodules
  submodule: teach unpack_trees() to update submodules

 Documentation/git-bisect.txt|   5 +
 Documentation/git-checkout.txt  |   2 +
 Documentation/git-merge.txt |   2 +
 Documentation/git-reset.txt |   4 +
 Documentation/recurse-submodules-update.txt |   8 +
 bisect.c|  33 ++--
 bisect.h|   3 +-
 builtin/bisect--helper.c|   9 +-
 builtin/checkout.c  |  14 ++
 builtin/merge.c |  14 ++
 builtin/reset.c |  14 ++
 entry.c |  19 ++-
 git-bisect.sh   |  29 +++-
 submodule.c | 238 +++-
 submodule.h |  12 ++
 t/t2013-checkout-submodule.sh   | 215 -
 unpack-trees.c  |  95 +--
 unpack-trees.h  |   1 +
 wrapper.c   |   3 +
 19 files changed, 676 insertions(+), 44 deletions(-)
 create mode 100644 Documentation/recurse-submodules-update.txt

-- 
1.9.rc0.28.ge3363ff

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


[WIP/PATCH 1/9] submodule: prepare for recursive checkout of submodules

2014-02-03 Thread Jens Lehmann
This commit adds the functions and files needed for configuration,
documentation, setting the default behavior and determining if a
submodule path should be updated automatically.

It won't really enable recursive submodule update. This will be done
by later commits.

Signed-off-by: Jens Lehmann jens.lehm...@web.de
---
 Documentation/recurse-submodules-update.txt |  8 +
 submodule.c | 50 +
 submodule.h |  6 
 3 files changed, 64 insertions(+)
 create mode 100644 Documentation/recurse-submodules-update.txt

diff --git a/Documentation/recurse-submodules-update.txt 
b/Documentation/recurse-submodules-update.txt
new file mode 100644
index 000..e57d452
--- /dev/null
+++ b/Documentation/recurse-submodules-update.txt
@@ -0,0 +1,8 @@
+--[no-]recurse-submodules::
+   Using --recurse-submodules will update the work tree of all
+   initialized submodules according to the commit recorded in the
+   superproject if their update configuration is set to checkout'. If
+   local modifications in a submodule would be overwritten the checkout
+   will fail unless forced. Without this option or with
+   --no-recurse-submodules is, the work trees of submodules will not be
+   updated, only the hash recorded in the superproject will be updated.
diff --git a/submodule.c b/submodule.c
index 613857e..b3eb28d 100644
--- a/submodule.c
+++ b/submodule.c
@@ -16,6 +16,8 @@ static struct string_list config_name_for_path;
 static struct string_list config_fetch_recurse_submodules_for_name;
 static struct string_list config_ignore_for_name;
 static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND;
+static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
+static int option_update_recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
 static struct string_list changed_submodule_paths;
 static int initialized_fetch_ref_tips;
 static struct sha1_array ref_tips_before_fetch;
@@ -382,6 +384,48 @@ int parse_fetch_recurse_submodules_arg(const char *opt, 
const char *arg)
}
 }

+int parse_update_recurse_submodules_arg(const char *opt, const char *arg)
+{
+   switch (git_config_maybe_bool(opt, arg)) {
+   case 1:
+   return RECURSE_SUBMODULES_ON;
+   case 0:
+   return RECURSE_SUBMODULES_OFF;
+   default:
+   if (!strcmp(arg, checkout))
+   return RECURSE_SUBMODULES_ON;
+   die(bad %s argument: %s, opt, arg);
+   }
+}
+
+int option_parse_update_submodules(const struct option *opt,
+  const char *arg, int unset)
+{
+   if (unset) {
+   *(int *)opt-value = RECURSE_SUBMODULES_OFF;
+   } else {
+   if (arg)
+   *(int *)opt-value = 
parse_update_recurse_submodules_arg(opt-long_name, arg);
+   else
+   *(int *)opt-value = RECURSE_SUBMODULES_ON;
+   }
+   return 0;
+}
+
+int submodule_needs_update(const char *path)
+{
+   struct string_list_item *path_option;
+   path_option = unsorted_string_list_lookup(config_name_for_path, path);
+   if (!path_option)
+   return 0;
+
+   /* update can't be none, merge or rebase */
+
+   if (option_update_recurse_submodules != RECURSE_SUBMODULES_DEFAULT)
+   return 1;
+   return config_update_recurse_submodules != RECURSE_SUBMODULES_OFF;
+}
+
 void show_submodule_summary(FILE *f, const char *path,
const char *line_prefix,
unsigned char one[20], unsigned char two[20],
@@ -589,6 +633,12 @@ int push_unpushed_submodules(unsigned char new_sha1[20], 
const char *remotes_nam
return ret;
 }

+void set_config_update_recurse_submodules(int default_value, int option_value)
+{
+   config_update_recurse_submodules = default_value;
+   option_update_recurse_submodules = option_value;
+}
+
 static int is_submodule_commit_present(const char *path, unsigned char 
sha1[20])
 {
int is_present = 0;
diff --git a/submodule.h b/submodule.h
index 7beec48..79b336b 100644
--- a/submodule.h
+++ b/submodule.h
@@ -3,6 +3,7 @@

 struct diff_options;
 struct argv_array;
+struct option;

 enum {
RECURSE_SUBMODULES_ON_DEMAND = -1,
@@ -22,12 +23,17 @@ void gitmodules_config(void);
 int parse_submodule_config_option(const char *var, const char *value);
 void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *);
 int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg);
+int parse_update_recurse_submodules_arg(const char *opt, const char *arg);
+int option_parse_update_submodules(const struct option *opt,
+   const char *arg, int unset);
+int submodule_needs_update(const char *path);
 void show_submodule_summary(FILE *f, const char *path,
const char *line_prefix,
unsigned char one[20], unsigned 

[WIP/PATCH 2/9] Teach reset the --[no-]recurse-submodules option

2014-02-03 Thread Jens Lehmann
This new option will allow the user to not only reset the work tree of
the superproject but to also update the work tree of all initialized
submodules (so they match the SHA-1 recorded in the superproject) when
used together with --hard or --merge. But this commit only adds the
option without any functionality, that will be added to unpack_trees()
in subsequent commits.

Signed-off-by: Jens Lehmann jens.lehm...@web.de
---
 Documentation/git-reset.txt |  4 
 builtin/reset.c | 14 ++
 2 files changed, 18 insertions(+)

diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index f445cb3..8f833f4 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -94,6 +94,10 @@ OPTIONS
 --quiet::
Be quiet, only report errors.

+include::recurse-submodules-update.txt[]
++
+This option only makes sense together with `--hard` and `--merge` and is
+ignored when used without these options.

 EXAMPLES
 
diff --git a/builtin/reset.c b/builtin/reset.c
index 6004803..adf372e 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -20,6 +20,7 @@
 #include parse-options.h
 #include unpack-trees.h
 #include cache-tree.h
+#include submodule.h

 static const char * const git_reset_usage[] = {
N_(git reset [--mixed | --soft | --hard | --merge | --keep] [-q] 
[commit]),
@@ -255,6 +256,8 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
 {
int reset_type = NONE, update_ref_status = 0, quiet = 0;
int patch_mode = 0, unborn;
+   const char *recurse_submodules_default = off;
+   int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
const char *rev;
unsigned char sha1[20];
struct pathspec pathspec;
@@ -270,13 +273,24 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
OPT_SET_INT(0, keep, reset_type,
N_(reset HEAD but keep local changes), KEEP),
OPT_BOOL('p', patch, patch_mode, N_(select hunks 
interactively)),
+   { OPTION_CALLBACK, 0, recurse-submodules, recurse_submodules,
+   checkout, control recursive updating of submodules,
+   PARSE_OPT_OPTARG, option_parse_update_submodules },
+   { OPTION_STRING, 0, recurse-submodules-default,
+   recurse_submodules_default, NULL,
+   default mode for recursion, PARSE_OPT_HIDDEN },
OPT_END()
};

+   gitmodules_config();
git_config(git_default_config, NULL);

argc = parse_options(argc, argv, prefix, options, git_reset_usage,
PARSE_OPT_KEEP_DASHDASH);
+   set_config_update_recurse_submodules(
+   
parse_update_recurse_submodules_arg(--recurse-submodules-default,
+   recurse_submodules_default),
+   recurse_submodules);
parse_args(pathspec, argv, prefix, patch_mode, rev);

unborn = !strcmp(rev, HEAD)  get_sha1(HEAD, sha1);
-- 
1.9.rc0.28.ge3363ff


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


[WIP/PATCH 3/9] Teach checkout the --[no-]recurse-submodules option

2014-02-03 Thread Jens Lehmann
This new option will allow the user to not only update the work tree of
the superproject according to the checked out commit but to also update
the work tree of all initialized submodules (so they match the SHA-1
recorded in the superproject). But this commit only adds the option
without any functionality, that will be added to unpack_trees() in
subsequent commits.

Signed-off-by: Jens Lehmann jens.lehm...@web.de
---
 Documentation/git-checkout.txt |   2 +
 builtin/checkout.c |  14 +++
 t/t2013-checkout-submodule.sh  | 215 -
 3 files changed, 228 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 91294f8..6c7d31f 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -225,6 +225,8 @@ This means that you can use `git checkout -p` to 
selectively discard
 edits from your current working tree. See the ``Interactive Mode''
 section of linkgit:git-add[1] to learn how to operate the `--patch` mode.

+include::recurse-submodules-update.txt[]
+
 branch::
Branch to checkout; if it refers to a branch (i.e., a name that,
when prepended with refs/heads/, is a valid ref), then that
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5df3837..e4ef0ba 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -21,6 +21,9 @@
 #include submodule.h
 #include argv-array.h

+static const char *recurse_submodules_default = off;
+static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
+
 static const char * const checkout_usage[] = {
N_(git checkout [options] branch),
N_(git checkout [options] [branch] -- file...),
@@ -,6 +1114,12 @@ int cmd_checkout(int argc, const char **argv, const char 
*prefix)
 N_(do not limit pathspecs to sparse entries only)),
OPT_HIDDEN_BOOL(0, guess, dwim_new_local_branch,
N_(second guess 'git checkout 
no-such-branch')),
+   { OPTION_CALLBACK, 0, recurse-submodules, recurse_submodules,
+   checkout, control recursive updating of 
submodules,
+   PARSE_OPT_OPTARG, option_parse_update_submodules },
+   { OPTION_STRING, 0, recurse-submodules-default,
+  recurse_submodules_default, NULL,
+  default mode for recursion, PARSE_OPT_HIDDEN },
OPT_END(),
};

@@ -1132,6 +1141,11 @@ int cmd_checkout(int argc, const char **argv, const char 
*prefix)
git_xmerge_config(merge.conflictstyle, conflict_style, NULL);
}

+   set_config_update_recurse_submodules(
+   
parse_update_recurse_submodules_arg(--recurse-submodules-default,
+   recurse_submodules_default),
+   recurse_submodules);
+
if ((!!opts.new_branch + !!opts.new_branch_force + 
!!opts.new_orphan_branch)  1)
die(_(-b, -B and --orphan are mutually exclusive));

diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh
index 06b18f8..bc3e1ca 100755
--- a/t/t2013-checkout-submodule.sh
+++ b/t/t2013-checkout-submodule.sh
@@ -4,17 +4,57 @@ test_description='checkout can handle submodules'

 . ./test-lib.sh

+submodule_creation_must_succeed() {
+   # checkout base ($1)
+   git checkout -f --recurse-submodules $1 
+   git diff-files --quiet 
+   git diff-index --quiet --cached $1 
+
+   # checkout target ($2)
+   if test -d submodule; then
+   echo changesubmodule/first.t 
+   test_must_fail git checkout --recurse-submodules $2 
+   git checkout -f --recurse-submodules $2
+   else
+   git checkout --recurse-submodules $2
+   fi 
+   test -e submodule/.git 
+   test -f submodule/first.t 
+   test -f submodule/second.t 
+   git diff-files --quiet 
+   git diff-index --quiet --cached $2
+}
+
+submodule_removal_must_succeed() {
+   # checkout base ($1)
+   git checkout -f --recurse-submodules $1 
+   git submodule update -f 
+   test -e submodule/.git 
+   git diff-files --quiet 
+   git diff-index --quiet --cached $1 
+
+   # checkout target ($2)
+   echo changesubmodule/first.t 
+   test_must_fail git checkout --recurse-submodules $2 
+   git checkout -f --recurse-submodules $2 
+   git diff-files --quiet 
+   git diff-index --quiet --cached $2 
+   ! test -d submodule
+}
+
 test_expect_success 'setup' '
mkdir submodule 
(cd submodule 
 git init 
 test_commit first) 
-   git add submodule 
+   echo first  file 
+   git add file submodule 
test_tick 
git commit -m superproject 
(cd submodule 
 test_commit second) 
-   git add submodule 
+   echo second  file 
+   git add file submodule 
   

[WIP/PATCH 5/9] Teach bisect--helper the --[no-]recurse-submodules option

2014-02-03 Thread Jens Lehmann
This is necessary before we can teach 'git bisect' this option, as that
calls the bisect--helper to do the actual work which then in turn calls
'git checkout'. The helper just passes the option given on the command
line on to checkout. The new recurse_submodules_enum_to_option() is added
to avoid having the helper learn the command line representation of the
different option values himself.

Signed-off-by: Jens Lehmann jens.lehm...@web.de
---
 bisect.c | 33 ++---
 bisect.h |  3 ++-
 builtin/bisect--helper.c |  9 -
 submodule.c  | 21 +
 submodule.h  |  1 +
 5 files changed, 54 insertions(+), 13 deletions(-)

diff --git a/bisect.c b/bisect.c
index 37200b4..b84e607 100644
--- a/bisect.c
+++ b/bisect.c
@@ -11,13 +11,13 @@
 #include bisect.h
 #include sha1-array.h
 #include argv-array.h
+#include submodule.h

 static struct sha1_array good_revs;
 static struct sha1_array skipped_revs;

 static unsigned char *current_bad_sha1;

-static const char *argv_checkout[] = {checkout, -q, NULL, --, NULL};
 static const char *argv_show_branch[] = {show-branch, NULL, NULL};
 static const char *argv_update_ref[] = {update-ref, --no-deref, 
BISECT_HEAD, NULL, NULL};

@@ -683,22 +683,30 @@ static void mark_expected_rev(char *bisect_rev_hex)
die(closing file %s: %s, filename, strerror(errno));
 }

-static int bisect_checkout(char *bisect_rev_hex, int no_checkout)
+static int bisect_checkout(char *bisect_rev_hex, int no_checkout,
+  const char *recurse_submodules)
 {
int res;

mark_expected_rev(bisect_rev_hex);

-   argv_checkout[2] = bisect_rev_hex;
if (no_checkout) {
argv_update_ref[3] = bisect_rev_hex;
if (run_command_v_opt(argv_update_ref, RUN_GIT_CMD))
die(update-ref --no-deref HEAD failed on %s,
bisect_rev_hex);
} else {
-   res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
+   struct argv_array argv = ARGV_ARRAY_INIT;
+   argv_array_push(argv, checkout);
+   argv_array_push(argv, -q);
+   if (recurse_submodules)
+   argv_array_push(argv, recurse_submodules);
+   argv_array_push(argv, bisect_rev_hex);
+   argv_array_push(argv, --);
+   res = run_command_v_opt(argv.argv, RUN_GIT_CMD);
if (res)
exit(res);
+   argv_array_clear(argv);
}

argv_show_branch[1] = bisect_rev_hex;
@@ -771,7 +779,7 @@ static void handle_skipped_merge_base(const unsigned char 
*mb)
  * - If one is skipped, we can't know but we should warn.
  * - If we don't know, we should check it out and ask the user to test.
  */
-static void check_merge_bases(int no_checkout)
+static void check_merge_bases(int no_checkout, const char *recurse_submodules)
 {
struct commit_list *result;
int rev_nr;
@@ -789,7 +797,8 @@ static void check_merge_bases(int no_checkout)
handle_skipped_merge_base(mb);
} else {
printf(Bisecting: a merge base must be tested\n);
-   exit(bisect_checkout(sha1_to_hex(mb), no_checkout));
+   exit(bisect_checkout(sha1_to_hex(mb), no_checkout,
+recurse_submodules));
}
}

@@ -832,7 +841,8 @@ static int check_ancestors(const char *prefix)
  * If a merge base must be tested by the user, its source code will be
  * checked out to be tested by the user and we will exit.
  */
-static void check_good_are_ancestors_of_bad(const char *prefix, int 
no_checkout)
+static void check_good_are_ancestors_of_bad(const char *prefix, int 
no_checkout,
+   const char *recurse_submodules)
 {
char *filename = git_pathdup(BISECT_ANCESTORS_OK);
struct stat st;
@@ -851,7 +861,7 @@ static void check_good_are_ancestors_of_bad(const char 
*prefix, int no_checkout)

/* Check if all good revs are ancestor of the bad rev. */
if (check_ancestors(prefix))
-   check_merge_bases(no_checkout);
+   check_merge_bases(no_checkout, recurse_submodules);

/* Create file BISECT_ANCESTORS_OK. */
fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
@@ -897,7 +907,8 @@ static void show_diff_tree(const char *prefix, struct 
commit *commit)
  * If no_checkout is non-zero, the bisection process does not
  * checkout the trial commit but instead simply updates BISECT_HEAD.
  */
-int bisect_next_all(const char *prefix, int no_checkout)
+int bisect_next_all(const char *prefix, int no_checkout,
+   const char *recurse_submodules)
 {
struct rev_info revs;
struct commit_list *tried;
@@ -908,7 +919,7 @@ int 

[WIP/PATCH 6/9] Teach bisect the --[no-]recurse-submodules option

2014-02-03 Thread Jens Lehmann
When using this option 'git bisect' will automatically update the work
tree of all initialized submodules (so they match the SHA-1 recorded in
the superproject) in each bisection step. This makes calling 'git
submodule update' eacht time obsolete, which was tedious and error prone.
If the option is given it is stored in the BISECT_RECURSE_SUBMODULES file
in the git directory so that later bisection steps can reuse it. But this
commit only adds the option without any functionality, that will be added
to unpack_trees() in subsequent commits.

Signed-off-by: Jens Lehmann jens.lehm...@web.de
---
 Documentation/git-bisect.txt |  5 +
 git-bisect.sh| 29 -
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index f986c5c..c0aaba8 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -276,6 +276,11 @@ does not require a checked out tree.
 +
 If the repository is bare, `--no-checkout` is assumed.

+include::recurse-submodules-update.txt[]
++
+This option is passed to linkgit:git-checkout[1] when checking out the next
+to be tested commit and is ignored when used together with `--no-checkout`.
+
 EXAMPLES
 

diff --git a/git-bisect.sh b/git-bisect.sh
index 73b4c14..ba64a21 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -3,7 +3,7 @@
 USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'
 LONG_USAGE='git bisect help
print this long help message.
-git bisect start [--no-checkout] [bad [good...]] [--] [pathspec...]
+git bisect start [--no-checkout] [--[no-]recurse-submodules[=mode]] [bad 
[good...]] [--] [pathspec...]
reset bisect state and start bisection.
 git bisect bad [rev]
mark rev a known-bad revision.
@@ -91,6 +91,12 @@ bisect_start() {
--no-checkout)
mode=--no-checkout
shift ;;
+   --no-recurse-submodules)
+   recurse_submodules=$1
+   shift ;;
+   --recurse-submodules*)
+   recurse_submodules=$1
+   shift ;;
--*)
die $(eval_gettext unrecognised option: '\$arg') ;;
*)
@@ -124,9 +130,13 @@ bisect_start() {
then
# Reset to the rev from where we started.
start_head=$(cat $GIT_DIR/BISECT_START)
+   if test -s $GIT_DIR/BISECT_RECURSE_SUBMODULES
+   then
+   recurse_submodules=$(cat 
$GIT_DIR/BISECT_RECURSE_SUBMODULES)
+   fi
if test z$mode != z--no-checkout
then
-   git checkout $start_head -- ||
+   git checkout 
${recurse_submodules:+$recurse_submodules} $start_head -- ||
die $(eval_gettext Checking out '\$start_head' 
failed. Try 'git bisect reset validbranch'.)
fi
else
@@ -168,7 +178,10 @@ bisect_start() {
test z$mode != z--no-checkout ||
git update-ref --no-deref BISECT_HEAD $start_head
} 
-   git rev-parse --sq-quote $@ $GIT_DIR/BISECT_NAMES 
+   git rev-parse --sq-quote $@ $GIT_DIR/BISECT_NAMES  {
+   test -z $recurse_submodules ||
+   echo $recurse_submodules $GIT_DIR/BISECT_RECURSE_SUBMODULES
+   } 
eval $eval true 
echo git bisect start$orig_args $GIT_DIR/BISECT_LOG || exit
#
@@ -306,8 +319,13 @@ bisect_next() {
bisect_autostart
bisect_next_check good

+   if test -f $GIT_DIR/BISECT_RECURSE_SUBMODULES
+   then
+   recurse_submodules=$(cat $GIT_DIR/BISECT_RECURSE_SUBMODULES)
+   fi
+
# Perform all bisection computation, display and checkout
-   git bisect--helper --next-all $(test -f $GIT_DIR/BISECT_HEAD  echo 
--no-checkout)
+   git bisect--helper --next-all $(test -f $GIT_DIR/BISECT_HEAD  echo 
--no-checkout) ${recurse_submodules:+$recurse_submodules}
res=$?

# Check if we should exit because bisection is finished
@@ -374,7 +392,7 @@ bisect_reset() {
usage ;;
esac

-   if ! test -f $GIT_DIR/BISECT_HEAD  ! git checkout $branch --
+   if ! test -f $GIT_DIR/BISECT_HEAD  ! git checkout 
${recurse_submodules:+$recurse_submodules} $branch --
then
die $(eval_gettext Could not check out original HEAD 
'\$branch'.
 Try 'git bisect reset commit'.)
@@ -397,6 +415,7 @@ bisect_clean_state() {
# Cleanup head-name if it got left by an old version of git-bisect
rm -f $GIT_DIR/head-name 
git update-ref -d --no-deref BISECT_HEAD 
+   rm -f $GIT_DIR/BISECT_RECURSE_SUBMODULES 
# clean up BISECT_START last
rm -f $GIT_DIR/BISECT_START
 }
-- 
1.9.rc0.28.ge3363ff


--
To unsubscribe from this list: send the line unsubscribe git in
the 

Re: [PATCH v5 1/5] t0060: Add test for manipulating symlinks via absolute paths

2014-02-03 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 Can we have that git foo $path to the testsuite as well?  That is
 the breakage we do not want to repeat in the future by regressing.

Something like this, perhaps?

 t/t3004-ls-files-basic.sh | 17 +
 1 file changed, 17 insertions(+)

diff --git a/t/t3004-ls-files-basic.sh b/t/t3004-ls-files-basic.sh
index 8d9bc3c..d93089d 100755
--- a/t/t3004-ls-files-basic.sh
+++ b/t/t3004-ls-files-basic.sh
@@ -36,4 +36,21 @@ test_expect_success 'ls-files -h in corrupt repository' '
test_i18ngrep [Uu]sage: git ls-files  broken/usage
 '
 
+test_expect_success SYMLINKS 'ls-files with symlinks' '
+   mkdir subs 
+   ln -s nosuch link 
+   ln -s ../nosuch subs/link 
+   git add link subs/link 
+   git ls-files -s link subs/link expect 
+   git ls-files -s $(pwd)/link $(pwd)/subs/link actual 
+   test_cmp expect actual 
+
+   (
+   cd subs 
+   git ls-files -s link ../expect 
+   git ls-files -s $(pwd)/link ../actual
+   ) 
+   test_cmp expect actual
+'
+
 test_done
--
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


[WIP/PATCH 8/9] submodule: teach unpack_trees() to repopulate submodules

2014-02-03 Thread Jens Lehmann
Implement the functionality needed to enable work tree manipulating
commands so that an added submodule does not only affect the index and
creates an empty directory but it also populates the work tree of any
initialized submodule according to the SHA-1 recorded in the superproject.

That will only work for submodules that store their git directory in the
.git/modules directory of the superproject. Additionally the submodule has
to be found in the .gitmodules file before the work tree update starts as
the git directory is stored under the submodule name, not its path. This
will be fixed when the .gitmodules blob of the tree we are updating to
will be used for the path - name mapping in a later commit.

Signed-off-by: Jens Lehmann jens.lehm...@web.de
---
 entry.c|  4 
 submodule.c| 44 +---
 submodule.h|  1 +
 unpack-trees.c | 19 +++
 4 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/entry.c b/entry.c
index 7b7aa81..d1bf6ec 100644
--- a/entry.c
+++ b/entry.c
@@ -2,6 +2,7 @@
 #include blob.h
 #include dir.h
 #include streaming.h
+#include submodule.h

 static void create_directories(const char *path, int path_len,
   const struct checkout *state)
@@ -203,6 +204,9 @@ static int write_entry(struct cache_entry *ce,
return error(cannot create temporary submodule %s, 
path);
if (mkdir(path, 0777)  0)
return error(cannot create submodule directory %s, 
path);
+   if (submodule_needs_update(path) 
+   populate_submodule(path, ce-sha1, state-force))
+   return error(cannot checkout submodule %s, path);
break;
default:
return error(unknown file mode for %s in index, path);
diff --git a/submodule.c b/submodule.c
index f292e9e..3907034 100644
--- a/submodule.c
+++ b/submodule.c
@@ -447,6 +447,42 @@ int submodule_needs_update(const char *path)
return config_update_recurse_submodules != RECURSE_SUBMODULES_OFF;
 }

+int populate_submodule(const char *path, unsigned char sha1[20], int force)
+{
+   struct string_list_item *path_option;
+   const char *name, *real_git_dir;
+   struct strbuf buf = STRBUF_INIT;
+   struct child_process cp;
+   const char *argv[] = {read-tree, force ? --reset : -m, -u, 
NULL, NULL};
+
+   path_option = unsorted_string_list_lookup(config_name_for_path, path);
+   if (!path_option)
+   return 0;
+
+   name = path_option-util;
+
+   strbuf_addf(buf, %s/modules/%s, resolve_gitdir(get_git_dir()), name);
+   real_git_dir = resolve_gitdir(buf.buf);
+   if (!real_git_dir)
+   goto out;
+   connect_work_tree_and_git_dir(path, real_git_dir);
+
+   /* Run read-tree --reset sha1 */
+   memset(cp, 0, sizeof(cp));
+   cp.argv = argv;
+   cp.env = local_repo_env;
+   cp.git_cmd = 1;
+   cp.no_stdin = 1;
+   cp.dir = path;
+   argv[3] = sha1_to_hex(sha1);
+   if (run_command(cp))
+   warning(_(Checking out submodule %s failed), path);
+
+out:
+   strbuf_release(buf);
+   return 0;
+}
+
 int depopulate_submodule(const char *path)
 {
struct strbuf dot_git = STRBUF_INIT;
@@ -1242,6 +1278,7 @@ void connect_work_tree_and_git_dir(const char *work_tree, 
const char *git_dir)
 {
struct strbuf file_name = STRBUF_INIT;
struct strbuf rel_path = STRBUF_INIT;
+   const char *real_git_dir = xstrdup(real_path(git_dir));
const char *real_work_tree = xstrdup(real_path(work_tree));
FILE *fp;

@@ -1250,15 +1287,15 @@ void connect_work_tree_and_git_dir(const char 
*work_tree, const char *git_dir)
fp = fopen(file_name.buf, w);
if (!fp)
die(_(Could not create git link %s), file_name.buf);
-   fprintf(fp, gitdir: %s\n, relative_path(git_dir, real_work_tree,
+   fprintf(fp, gitdir: %s\n, relative_path(real_git_dir, real_work_tree,
  rel_path));
fclose(fp);

/* Update core.worktree setting */
strbuf_reset(file_name);
-   strbuf_addf(file_name, %s/config, git_dir);
+   strbuf_addf(file_name, %s/config, real_git_dir);
if (git_config_set_in_file(file_name.buf, core.worktree,
-  relative_path(real_work_tree, git_dir,
+  relative_path(real_work_tree, real_git_dir,
 rel_path)))
die(_(Could not set core.worktree in %s),
file_name.buf);
@@ -1266,4 +1303,5 @@ void connect_work_tree_and_git_dir(const char *work_tree, 
const char *git_dir)
strbuf_release(file_name);
strbuf_release(rel_path);
free((void *)real_work_tree);
+   free((void *)real_git_dir);
 }
diff --git a/submodule.h b/submodule.h
index 

[WIP/PATCH 7/9] submodule: teach unpack_trees() to remove submodule contents

2014-02-03 Thread Jens Lehmann
Implement the functionality needed to enable work tree manipulating
commands to that a deleted submodule should not only affect the index
(leaving all the files of the submodule in the work tree) but also to
remove the work tree of the superproject (including any untracked
files).

That will only work properly when the submodule uses a gitfile instead of
a .git directory and no untracked files are present. Otherwise the removal
will fail with a warning (which is just what happened until now).

Extend rmdir_or_warn() to remove the directories of those submodules which
are scheduled for removal. Also teach verify_clean_submodule() to check
that a submodule configured to be removed is not modified before scheduling
it for removal.

Signed-off-by: Jens Lehmann jens.lehm...@web.de
---
 submodule.c| 37 +
 submodule.h|  1 +
 unpack-trees.c |  7 ---
 wrapper.c  |  3 +++
 4 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/submodule.c b/submodule.c
index 448b645..f292e9e 100644
--- a/submodule.c
+++ b/submodule.c
@@ -447,6 +447,43 @@ int submodule_needs_update(const char *path)
return config_update_recurse_submodules != RECURSE_SUBMODULES_OFF;
 }

+int depopulate_submodule(const char *path)
+{
+   struct strbuf dot_git = STRBUF_INIT;
+   struct child_process cp;
+   const char *argv[] = {rm, -rf, path, NULL};
+
+   /* Is it populated? */
+   strbuf_addf(dot_git, %s/.git, path);
+   if (!resolve_gitdir(dot_git.buf)) {
+   strbuf_release(dot_git);
+   return 0;
+   }
+   strbuf_release(dot_git);
+
+   /* Does it have a .git directory? */
+   if (!submodule_uses_gitfile(path)) {
+   warning(_(cannot remove submodule '%s' because it (or one of 
+ its nested submodules) uses a .git directory),
+ path);
+   return -1;
+   }
+
+   /* Remove the whole submodule directory */
+   memset(cp, 0, sizeof(cp));
+   cp.argv = argv;
+   cp.env = local_repo_env;
+   cp.git_cmd = 0;
+   cp.no_stdin = 1;
+   if (run_command(cp)) {
+   warning(Could not remove submodule %s, path);
+   strbuf_release(dot_git);
+   return -1;
+   }
+
+   return 0;
+}
+
 void show_submodule_summary(FILE *f, const char *path,
const char *line_prefix,
unsigned char one[20], unsigned char two[20],
diff --git a/submodule.h b/submodule.h
index 5958010..2139e08 100644
--- a/submodule.h
+++ b/submodule.h
@@ -28,6 +28,7 @@ int parse_update_recurse_submodules_arg(const char *opt, 
const char *arg);
 int option_parse_update_submodules(const struct option *opt,
const char *arg, int unset);
 int submodule_needs_update(const char *path);
+int depopulate_submodule(const char *path);
 void show_submodule_summary(FILE *f, const char *path,
const char *line_prefix,
unsigned char one[20], unsigned char two[20],
diff --git a/unpack-trees.c b/unpack-trees.c
index 164354d..82c99eb 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -8,6 +8,7 @@
 #include progress.h
 #include refs.h
 #include attr.h
+#include submodule.h

 /*
  * Error messages expected by scripts out of plumbing commands such as
@@ -1266,14 +1267,14 @@ static void invalidate_ce_path(const struct cache_entry 
*ce,
 /*
  * Check that checking out ce-sha1 in subdir ce-name is not
  * going to overwrite any working files.
- *
- * Currently, git does not checkout subprojects during a superproject
- * checkout, so it is not going to overwrite anything.
  */
 static int verify_clean_submodule(const struct cache_entry *ce,
  enum unpack_trees_error_types error_type,
  struct unpack_trees_options *o)
 {
+   if (submodule_needs_update(ce-name) 
+   is_submodule_modified(ce-name, 0))
+   return 1;
return 0;
 }

diff --git a/wrapper.c b/wrapper.c
index 0cc5636..425a3fd 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -2,6 +2,7 @@
  * Various trivial helper wrappers around standard functions
  */
 #include cache.h
+#include submodule.h

 static void do_nothing(size_t size)
 {
@@ -409,6 +410,8 @@ int unlink_or_warn(const char *file)

 int rmdir_or_warn(const char *file)
 {
+   if (submodule_needs_update(file)  depopulate_submodule(file))
+   return -1;
return warn_if_unremovable(rmdir, file, rmdir(file));
 }

-- 
1.9.rc0.28.ge3363ff


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


[WIP/PATCH 9/9] submodule: teach unpack_trees() to update submodules

2014-02-03 Thread Jens Lehmann
Implement the functionality needed to enable work tree manipulating
commands so that an changed submodule does not only affect the index but
it also updates the work tree of any initialized submodule according to
the SHA-1 recorded in the superproject.

Signed-off-by: Jens Lehmann jens.lehm...@web.de
---
 entry.c| 15 --
 submodule.c| 86 ++
 submodule.h|  3 ++
 unpack-trees.c | 69 --
 unpack-trees.h |  1 +
 5 files changed, 157 insertions(+), 17 deletions(-)

diff --git a/entry.c b/entry.c
index d1bf6ec..61a2767 100644
--- a/entry.c
+++ b/entry.c
@@ -265,7 +265,7 @@ int checkout_entry(struct cache_entry *ce,

if (!check_path(path, len, st, state-base_dir_len)) {
unsigned changed = ce_match_stat(ce, st, 
CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
-   if (!changed)
+   if (!changed  (!S_ISDIR(st.st_mode) || 
!S_ISGITLINK(ce-ce_mode)))
return 0;
if (!state-force) {
if (!state-quiet)
@@ -280,9 +280,18 @@ int checkout_entry(struct cache_entry *ce,
 * just do the right thing)
 */
if (S_ISDIR(st.st_mode)) {
-   /* If it is a gitlink, leave it alone! */
-   if (S_ISGITLINK(ce-ce_mode))
+   if (S_ISGITLINK(ce-ce_mode)) {
+   if (submodule_needs_update(ce-name)) {
+   if (is_submodule_populated(ce-name)) {
+   if (update_submodule(ce-name, 
ce-sha1, state-force))
+   return error(cannot 
checkout submodule %s, path);
+   } else {
+   if (populate_submodule(path, 
ce-sha1, state-force))
+   return error(cannot 
populate submodule %s, path);
+   }
+   }
return 0;
+   }
if (!state-force)
return error(%s is a directory, path);
remove_subtree(path);
diff --git a/submodule.c b/submodule.c
index 3907034..83e7595 100644
--- a/submodule.c
+++ b/submodule.c
@@ -520,6 +520,42 @@ int depopulate_submodule(const char *path)
return 0;
 }

+int update_submodule(const char *path, const unsigned char sha1[20], int force)
+{
+   struct strbuf buf = STRBUF_INIT;
+   struct child_process cp;
+   const char *hex_sha1 = sha1_to_hex(sha1);
+   const char *argv[] = {
+   checkout,
+   force ? -fq : -q,
+   hex_sha1,
+   NULL,
+   };
+   const char *git_dir;
+
+   strbuf_addf(buf, %s/.git, path);
+   git_dir = read_gitfile(buf.buf);
+   if (!git_dir)
+   git_dir = buf.buf;
+   if (!is_directory(git_dir)) {
+   strbuf_release(buf);
+   /* The submodule is not populated, so we can't check it out */
+   return 0;
+   }
+   strbuf_release(buf);
+
+   memset(cp, 0, sizeof(cp));
+   cp.argv = argv;
+   cp.env = local_repo_env;
+   cp.git_cmd = 1;
+   cp.no_stdin = 1;
+   cp.dir = path;   /* GIT_WORK_TREE doesn't work for git checkout */
+   if (run_command(cp))
+   return error(Could not checkout submodule %s, path);
+
+   return 0;
+}
+
 void show_submodule_summary(FILE *f, const char *path,
const char *line_prefix,
unsigned char one[20], unsigned char two[20],
@@ -961,6 +997,17 @@ out:
return result;
 }

+int is_submodule_populated(const char *path)
+{
+   int retval = 0;
+   struct strbuf gitdir = STRBUF_INIT;
+   strbuf_addf(gitdir, %s/.git, path);
+   if (resolve_gitdir(gitdir.buf))
+   retval = 1;
+   strbuf_release(gitdir);
+   return retval;
+}
+
 unsigned is_submodule_modified(const char *path, int ignore_untracked)
 {
ssize_t len;
@@ -1110,6 +1157,45 @@ int ok_to_remove_submodule(const char *path)
return ok_to_remove;
 }

+unsigned is_submodule_checkout_safe(const char *path, const unsigned char 
sha1[20])
+{
+   struct strbuf buf = STRBUF_INIT;
+   struct child_process cp;
+   const char *hex_sha1 = sha1_to_hex(sha1);
+   const char *argv[] = {
+   read-tree,
+   -n,
+   -m,
+   HEAD,
+   hex_sha1,
+   NULL,
+   };
+   const char *git_dir;
+
+   strbuf_addf(buf, %s/.git, path);
+   git_dir = read_gitfile(buf.buf);
+   if (!git_dir)
+   git_dir = buf.buf;
+   if (!is_directory(git_dir)) {
+   

Bug: git repack keeps temps on ENOSPC

2014-02-03 Thread Andreas Krey
Hi,

I noticed that, when a git repack fails due to insufficient
disk space, the newly created partial pack file isn't unlinked
(which doesn't help at all in that situation).

(Will venture a look myself when time permits.)

Andreas

-- 
Totally trivial. Famous last words.
From: Linus Torvalds torvalds@*.org
Date: Fri, 22 Jan 2010 07:29:21 -0800
--
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] userdiff: update Ada patterns

2014-02-03 Thread Junio C Hamano
Adrian Johnson ajohn...@redneon.com writes:

 - Allow extra space in is new and is separate
 - Fix bug in word regex for numbers

 Signed-off-by: Adrian Johnson ajohn...@redneon.com
 ---
  t/t4034/ada/expect | 2 +-
  userdiff.c | 4 ++--
  2 files changed, 3 insertions(+), 3 deletions(-)

 diff --git a/t/t4034/ada/expect b/t/t4034/ada/expect
 index be2376e..a682d28 100644
 --- a/t/t4034/ada/expect
 +++ b/t/t4034/ada/expect
 @@ -4,7 +4,7 @@
  BOLD+++ b/postRESET
  CYAN@@ -1,13 +1,13 @@RESET
  Ada.Text_IO.Put_Line(Hello WorldRED!RESETGREEN?RESET);
 -1 1eRED-RESET10 16#FE12#E2 3.141_592 'REDxRESETGREENyRESET'
 +1 RED1e-10RESETGREEN1e10RESET 16#FE12#E2 3.141_592 
 'REDxRESETGREENyRESET'
  REDaRESETGREENxRESET+REDb aRESETGREENy xRESET-REDbRESET
  REDaRESETGREENyRESET
  GREENxRESET*REDb aRESETGREENy xRESET/REDbRESET
 diff --git a/userdiff.c b/userdiff.c
 index ea43a03..10b61ec 100644
 --- a/userdiff.c
 +++ b/userdiff.c
 @@ -15,13 +15,13 @@ static int drivers_alloc;
 word_regex |[^[:space:]]|[\xc0-\xff][\x80-\xbf]+ }
  static struct userdiff_driver builtin_drivers[] = {
  IPATTERN(ada,
 -  !^(.*[ \t])?(is new|renames|is separate)([ \t].*)?$\n
 +  !^(.*[ \t])?(is[ \t]+new|renames|is[ \t]+separate)([ \t].*)?$\n
!^[ \t]*with[ \t].*$\n
^[ \t]*((procedure|function)[ \t]+.*)$\n
^[ \t]*((package|protected|task)[ \t]+.*)$,
/* -- */
[a-zA-Z][a-zA-Z0-9_]*
 -  |[0-9][-+0-9#_.eE]
 +  |[-+]?[0-9][0-9#_.aAbBcCdDeEfF]*([eE][+-]?[0-9_]+)?

This would match a lot wider than what I read you said you wanted to
match in your previous message.  Does -04##4_3_2Ee-9 count as a
number, for example, or can we just ignore such syntactically
incorrect sequence?

|=|\\.\\.|\\*\\*|:=|/=|=|=|||),
  IPATTERN(fortran,
!^([C*]|[ \t]*!)\n
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[WIP/PATCH 4/9] Teach merge the --[no-]recurse-submodules option

2014-02-03 Thread Jens Lehmann
This new option will allow the user to not only update the work tree of
the superproject according to the merge result but to also update the
work tree of all initialized submodules (so they match the SHA-1 recorded
in the superproject). But this commit only adds the option without any
functionality, that will be added to unpack_trees() in subsequent commits.

Signed-off-by: Jens Lehmann jens.lehm...@web.de
---
 Documentation/git-merge.txt |  2 ++
 builtin/merge.c | 14 ++
 2 files changed, 16 insertions(+)

diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 4395459..9ed1655 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -96,6 +96,8 @@ commit or stash your changes before running 'git merge'.
 'git merge --abort' is equivalent to 'git reset --merge' when
 `MERGE_HEAD` is present.

+include::recurse-submodules-update.txt[]
+
 commit...::
Commits, usually other branch heads, to merge into our branch.
Specifying more than one commit will create a merge with
diff --git a/builtin/merge.c b/builtin/merge.c
index 4941a6c..a0eb665 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -28,6 +28,7 @@
 #include remote.h
 #include fmt-merge-msg.h
 #include gpg-interface.h
+#include submodule.h

 #define DEFAULT_TWOHEAD (10)
 #define DEFAULT_OCTOPUS (11)
@@ -65,6 +66,8 @@ static int abort_current_merge;
 static int show_progress = -1;
 static int default_to_upstream;
 static const char *sign_commit;
+static const char *recurse_submodules_default = off;
+static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;

 static struct strategy all_strategy[] = {
{ recursive,  DEFAULT_TWOHEAD | NO_TRIVIAL },
@@ -223,6 +226,12 @@ static struct option builtin_merge_options[] = {
{ OPTION_STRING, 'S', gpg-sign, sign_commit, N_(key id),
  N_(GPG sign commit), PARSE_OPT_OPTARG, NULL, (intptr_t)  },
OPT_BOOL(0, overwrite-ignore, overwrite_ignore, N_(update ignored 
files (default))),
+   { OPTION_CALLBACK, 0, recurse-submodules, recurse_submodules,
+   checkout, control recursive updating of submodules,
+   PARSE_OPT_OPTARG, option_parse_update_submodules },
+   { OPTION_STRING, 0, recurse-submodules-default,
+   recurse_submodules_default, NULL,
+   default mode for recursion, PARSE_OPT_HIDDEN },
OPT_END()
 };

@@ -1113,6 +1122,7 @@ int cmd_merge(int argc, const char **argv, const char 
*prefix)
else
head_commit = lookup_commit_or_die(head_sha1, HEAD);

+   gitmodules_config();
git_config(git_merge_config, NULL);

if (branch_mergeoptions)
@@ -1121,6 +1131,10 @@ int cmd_merge(int argc, const char **argv, const char 
*prefix)
builtin_merge_usage, 0);
if (shortlog_len  0)
shortlog_len = (merge_log_config  0) ? merge_log_config : 0;
+   set_config_update_recurse_submodules(
+   
parse_update_recurse_submodules_arg(--recurse-submodules-default,
+   recurse_submodules_default),
+   recurse_submodules);

if (verbosity  0  show_progress == -1)
show_progress = 0;
-- 
1.9.rc0.28.ge3363ff


--
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] userdiff: update Ada patterns

2014-02-03 Thread Junio C Hamano
George Spelvin li...@horizon.com writes:

 Another point is that Ada doesn't actually include leading + or -
 signs in the syntax for number, but rather makes them unary operators.
 This means that spaces are allowed, and whether you want to include them
 in the number pattern is a judgement call.

I tend to agree.  What do the patterns for other languages do?
--
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: [WIP/PATCH 6/9] Teach bisect the --[no-]recurse-submodules option

2014-02-03 Thread W. Trevor King
On Mon, Feb 03, 2014 at 08:51:57PM +0100, Jens Lehmann wrote:
 submodule update' eacht time obsolete, which was tedious and error prone.
^ each

I'm just reading the commit messages this pass ;).

Cheers,
Trevor

-- 
This email may be signed or encrypted with GnuPG (http://www.gnupg.org).
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy


signature.asc
Description: OpenPGP digital signature


Re: [PATCH v5 1/5] t0060: Add test for manipulating symlinks via absolute paths

2014-02-03 Thread Martin Erik Werner
On Mon, Feb 03, 2014 at 10:50:17AM -0800, Junio C Hamano wrote:
 Martin Erik Werner martinerikwer...@gmail.com writes:
 
  When symlinks in the working tree are manipulated using the absolute
  path, git dereferences them, and tries to manipulate the link target
  instead.
 
 The above may a very good description of the root cause, but
 can we have description of a symptom that is visible by end-users
 that is caused by the bug being fixed with the series here, by
 ending the above like so:
 
   ... link target instead.  This causes git foo bar to
   misbehave in this and that way.
 
 Testing the low-level underlying machinery like this patch does is
 not wrong per-se, but I suspect that this series was triggered by
 somebody noticing breakage in a end-user command git foo $path
 with $path being a full pathname to an in-tree symbolic link.  It
 wouldn't be like somebody who was bored and ran test-path-utils
 for fun noticed the root cause without realizing how the fix would
 affect the behaviour that would be visible to end-users, right?
 
 Can we have that git foo $path to the testsuite as well?  That is
 the breakage we do not want to repeat in the future by regressing.
 
 I am guessing foo is add, but I wasn't closely following the
 progression of the series.
 
 Thanks.

Indeed, it was first discovered via git-mv, (by Richard, using
git-annex) and me reproducing and reporting it was the start of the
thread: http://thread.gmane.org/gmane.comp.version-control.git/240467

In going further (PATCHv0):
 I've done a bit more digging into this: The issue applies to pretty
 much all commands which can be given paths to files which are present
 in the work tree, so add, cat-file, rev-list, etc.

At this stage I kind of dropped the reference to any specific top-level
command since it seemed to apply to all of them in some way, and I
figured it made more sense with a generic explanation that would apply
to all commands. But it might definitely be worth to mention it in order
for the commit messages to be less technical, and add at least one test
which would actually trigger it in a user-manner. So for the
explanation, something like that?:

This causes for example 'git add /dir/repo/symlink' to attempt
to add the target of the symlink rather than the symlink itself,
which is usually not what the user intends to do.

Hmm, come to think of it, I even made some of those tests back before I
found it could be narrowly tested via prefix_path... I guess I'll pick
out the git-add one since it's the simplest, should that be added to
t0060-path-utils.sh as well, or would it fit better in t3700-add.sh?:

From 910d8c9f51c3b3f2c03dbf15ce3cf7ea94de8d27 Mon Sep 17 00:00:00 2001
From: Martin Erik Werner martinerikwer...@gmail.com
Date: Thu, 16 Jan 2014 00:24:43 +0100
Subject: [PATCH] Add test for manipulating symlinks via absolute paths

When symlinks in the working tree are manipulated using the absolute
path, git derferences them, and tries to manipulate the link target
instead.

Add three known-breakage tests using add, mv, and rev-list which
checks this behaviour.

The failure of the git-add test is a regression introduced by 18e051a:
  setup: translate symlinks in filename when using absolute paths
(which did not take symlinks in the work tree into consideration).
---
 t/t0054-symlinks-via-abs-path.sh | 38 ++
 1 file changed, 38 insertions(+)
 create mode 100755 t/t0054-symlinks-via-abs-path.sh

diff --git a/t/t0054-symlinks-via-abs-path.sh b/t/t0054-symlinks-via-abs-path.sh
new file mode 100755
index 000..0b3c91e
--- /dev/null
+++ b/t/t0054-symlinks-via-abs-path.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+test_description='symlinks via sbsolute paths
+
+This test checks the behavior when symlinks in the working tree are manipulated
+via absolute path arguments.
+'
+. ./test-lib.sh
+
+test_expect_failure SYMLINKS 'git add symlink with absolute path' '
+
+   ln -s target symlink 
+   git add $(pwd)/symlink
+
+'
+
+rm -f symlink
+
+test_expect_failure SYMLINKS 'git mv symlink with absolute path' '
+
+   ln -s target symlink 
+   git add symlink 
+   git mv $(pwd)/symlink moved
+
+'
+
+rm -f symlink moved
+
+test_expect_failure 'git rev-list symlink with absolute path' '
+
+   ln -s target symlink 
+   git add symlink 
+   git commit -m show 
+   test $(git rev-list HEAD -- symlink) = $(git rev-list HEAD -- 
$(pwd)/symlink)
+
+'
+
+test_done
-- 
1.8.5.2
--
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: [WIP/PATCH 9/9] submodule: teach unpack_trees() to update submodules

2014-02-03 Thread W. Trevor King
On Mon, Feb 03, 2014 at 08:54:17PM +0100, Jens Lehmann wrote:
 Implement the functionality needed to enable work tree manipulating
 commands so that an changed submodule does not only affect the index but
 it also updates the work tree of any initialized submodule according to
 the SHA-1 recorded in the superproject.

How about:

  …so that *a* changed submodule ** updates the index and work tree of
  any initialized submodule according to the SHA-1 recorded in the
  superproject.  Before this commit it updated neither; users had to
  run 'submodule update' to propagate gitlink updates into the
  submodule.

I'm pretty sure that's accurate anyway ;).

Cheers,
Trevor

-- 
This email may be signed or encrypted with GnuPG (http://www.gnupg.org).
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy


signature.asc
Description: OpenPGP digital signature


Re: [PATCH] fast-import.c: always honor the filename case

2014-02-03 Thread Torsten Bögershausen
[]
 So to summarize, when fast-import uses strncmp_icase (what fast-import does 
 now) import on a repository where ignorecase=true is wrong.  My patch, 
 fast-import.c: always honor the filename case fixes this.  Can you verify?

 Thanks in advance,
 Reuben

Yes, I can verify. My feeling is that
a) the fast-export should generate the rename the other way around.
   Would that be feasable ?
   Or generate a real rename ?
  (I'm not using fast-export or import myself)

b)  As a workaround, does it help if you manually set core.ignorecase false ?

c)  Does it help to use git-hg-remote ? (could be another workaround)

And no,  50906e04e8f48215b0 does not include any test cases.
(try git show 50906e04e8)

This is only a short answer, I can prepare a longer answer about ignorecase the 
next days.
/Torsten


--
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: [WIP/PATCH 6/9] Teach bisect the --[no-]recurse-submodules option

2014-02-03 Thread Jens Lehmann
Am 03.02.2014 21:04, schrieb W. Trevor King:
 On Mon, Feb 03, 2014 at 08:51:57PM +0100, Jens Lehmann wrote:
 submodule update' eacht time obsolete, which was tedious and error prone.
 ^ each
 
 I'm just reading the commit messages this pass ;).

Fair enough ;-)
--
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: [WIP/PATCH 7/9] submodule: teach unpack_trees() to remove submodule contents

2014-02-03 Thread W. Trevor King
On Mon, Feb 03, 2014 at 08:52:49PM +0100, Jens Lehmann wrote:
 Implement the functionality needed to enable work tree manipulating
 commands to that a deleted submodule should not only affect the index
 (leaving all the files of the submodule in the work tree) but also to
 remove the work tree of the superproject (including any untracked
 files).
 
 That will only work properly when the submodule uses a gitfile instead of
 a .git directory and no untracked files are present. Otherwise the removal
 will fail with a warning (which is just what happened until now).

I'm having trouble parsing this one.  How about:

  Add a depopulate_submodule helper which removes the submodule
  working directory without touching the index.  This will only work
  properly when the submodule uses a gitfile…

Cheers,
Trevor

-- 
This email may be signed or encrypted with GnuPG (http://www.gnupg.org).
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy


signature.asc
Description: OpenPGP digital signature


Re: [PATCH v3 9/9] pull: add the --gpg-sign option.

2014-02-03 Thread Junio C Hamano
brian m. carlson sand...@crustytoothpaste.net writes:

 git merge already allows us to sign commits, and git rebase has recently
 learned how to do so as well.  Teach git pull to parse the -S/--gpg-sign
 option and pass this along to merge or rebase, as appropriate.

 Signed-off-by: brian m. carlson sand...@crustytoothpaste.net
 ---
  git-pull.sh | 13 -
  1 file changed, 12 insertions(+), 1 deletion(-)

 diff --git a/git-pull.sh b/git-pull.sh
 index 0a5aa2c..3b2ea9e 100755
 --- a/git-pull.sh
 +++ b/git-pull.sh
 @@ -138,6 +138,15 @@ do
   --no-verify-signatures)
   verify_signatures=--no-verify-signatures
   ;;
 + --gpg-sign|-S)
 + gpg_sign_args=-S
 + ;;
 + --gpg-sign=*)
 + gpg_sign_args=$(git rev-parse --sq-quote -S${1#--gpg-sign=})
 + ;;
 + -S*)
 + gpg_sign_args=-S${1#-S}
 + ;;

Interesting.  Remove -S from the beginning and then prefix that with -S?

Also, --gpg-sign='b m c s@c.n' and -S'b m c s@c.n' from the
command line of this program would result in $gpg_sign_args that are
differently quoted.  Both of them cannot be correct at the same time.


   --d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run)
   dry_run=--dry-run
   ;;
 @@ -305,11 +314,13 @@ merge_name=$(git fmt-merge-msg $log_arg 
 $GIT_DIR/FETCH_HEAD) || exit
  case $rebase in
  true)
   eval=git-rebase $diffstat $strategy_args $merge_args $rebase_args 
 $verbosity
 + eval=$eval $gpg_sign_args
   eval=$eval --onto $merge_head ${oldremoteref:-$merge_head}
   ;;
  *)
   eval=git-merge $diffstat $no_commit $verify_signatures $edit $squash 
 $no_ff $ff_only
 - eval=$eval  $log_arg $strategy_args $merge_args $verbosity $progress
 + eval=$eval $log_arg $strategy_args $merge_args $verbosity $progress
 + eval=$eval $gpg_sign_args
   eval=$eval \\$merge_name\ HEAD $merge_head
   ;;
  esac
--
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 1/9] cherry-pick, revert: add the --gpg-sign option

2014-02-03 Thread Junio C Hamano
brian m. carlson sand...@crustytoothpaste.net writes:

 diff --git a/sequencer.c b/sequencer.c
 index 90cac7b..bde5f04 100644
 --- a/sequencer.c
 +++ b/sequencer.c
 @@ -392,11 +392,18 @@ static int run_git_commit(const char *defmsg, struct 
 replay_opts *opts,
  {
   struct argv_array array;
   int rc;
 + char *gpg_sign;
  
   argv_array_init(array);
   argv_array_push(array, commit);
   argv_array_push(array, -n);
  
 + if (opts-gpg_sign) {
 + gpg_sign = xmalloc(3 + strlen(opts-gpg_sign));
 + sprintf(gpg_sign, -S%s, opts-gpg_sign);
 + argv_array_push(array, gpg_sign);
 + free(gpg_sign);

Perhaps

argv_array_pushf(array, -S%s, opts-gpg_sign);

without any temporary?  That would save 5 lines in total.

 + }
   if (opts-signoff)
   argv_array_push(array, -s);
   if (!opts-edit) {


diff --git a/sequencer.c b/sequencer.c
index bde5f04..b200dce 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -392,18 +392,13 @@ static int run_git_commit(const char *defmsg, struct 
replay_opts *opts,
 {
struct argv_array array;
int rc;
-   char *gpg_sign;
 
argv_array_init(array);
argv_array_push(array, commit);
argv_array_push(array, -n);
 
-   if (opts-gpg_sign) {
-   gpg_sign = xmalloc(3 + strlen(opts-gpg_sign));
-   sprintf(gpg_sign, -S%s, opts-gpg_sign);
-   argv_array_push(array, gpg_sign);
-   free(gpg_sign);
-   }
+   if (opts-gpg_sign)
+   argv_array_pushf(array, -S%s, opts-gpg_sign);
if (opts-signoff)
argv_array_push(array, -s);
if (!opts-edit) {
--
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] gitk: use single blamestuff for all show_line_source{} calls

2014-02-03 Thread Max Kirillov
There seems to be no point to search for several origins at once.
I doubt it is even fully working (because there is one blameinst),
but blamestuff for some reason is an array. Also, it is not cleaned
after blame is completed

Signed-off-by: Max Kirillov m...@max630.net
---
 gitk | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/gitk b/gitk
index 90764e8..dfac4fd 100755
--- a/gitk
+++ b/gitk
@@ -3815,17 +3815,18 @@ proc show_line_source {} {
 nowbusy blaming [mc Searching]
 fconfigure $f -blocking 0
 set i [reg_instance $f]
-set blamestuff($i) {}
+set blamestuff {}
 set blameinst $i
 filerun $f [list read_line_source $f $i]
 }
 
 proc stopblaming {} {
-global blameinst
+global blameinst blamestuff
 
 if {[info exists blameinst]} {
stop_instance $blameinst
unset blameinst
+   unset blamestuff
notbusy blaming
 }
 }
@@ -3834,7 +3835,7 @@ proc read_line_source {fd inst} {
 global blamestuff curview commfd blameinst nullid nullid2
 
 while {[gets $fd line] = 0} {
-   lappend blamestuff($inst) $line
+   lappend blamestuff $line
 }
 if {![eof $fd]} {
return 1
@@ -3845,17 +3846,18 @@ proc read_line_source {fd inst} {
 fconfigure $fd -blocking 1
 if {[catch {close $fd} err]} {
error_popup [mc Error running git blame: %s $err]
+   unset blamestuff
return 0
 }
 
 set fname {}
-set line [split [lindex $blamestuff($inst) 0]  ]
+set line [split [lindex $blamestuff 0]  ]
 set id [lindex $line 0]
 set lnum [lindex $line 1]
 if {[string length $id] == 40  [string is xdigit $id] 
[string is digit -strict $lnum]} {
# look for filename line
-   foreach l $blamestuff($inst) {
+   foreach l $blamestuff {
if {[string match filename * $l]} {
set fname [string range $l 9 end]
break
@@ -3878,6 +3880,7 @@ proc read_line_source {fd inst} {
 } else {
puts oops couldn't parse git blame output
 }
+unset blamestuff
 return 0
 }
 
-- 
1.8.5.2.421.g4cdf8d0

--
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 4/5] setup: Add 'abspath_part_inside_repo' function

2014-02-03 Thread Junio C Hamano
Martin Erik Werner martinerikwer...@gmail.com writes:

 The path being exactly equal to the work tree is handled separately,
 since then there is no directory separator between the work tree and
 in-repo part.

What is an in-repo part?  Whatever it is, I am not sure if I
follow that logic.  After the while (*path) loop checks each level,
you check the whole path---wouldn't that code handle that special
case already?

Because it is probably the normal case not to have any symbolic link
in the leading part (hence not having to dereference them), I think
checking is work_tree[] a prefix of path[] early is justified from
performance point of view, though.

  /*
 + * No checking if the path is in fact an absolute path is done, and it must
 + * already be normalized.

This is not quite parsable to me.

 + * Find the part of an absolute path that lies inside the work tree by
 + * dereferencing symlinks outside the work tree, for example:
 + * /dir1/repo/dir2/file   (work tree is /dir1/repo)  - dir2/file
 + * /dir/file  (work tree is /)   - dir/file
 + * /dir/symlink1/symlink2 (symlink1 points to work tree) - symlink2
 + * /dir/repolink/file (repolink points to /dir/repo) - file
 + * /dir/repo  (exactly equal to work tree)   - (empty string)
 + */
 +static inline int abspath_part_inside_repo(char *path)

It looks a bit too big to be marked inline; better leave it to the
compiler to notice that there is only a single callsite and decide
to (or not to) inline it.

 +{
 + size_t len;
 + size_t wtlen;
 + char *path0;
 + int off;
 +
 + const char* work_tree = get_git_work_tree();
 + if (!work_tree)
 + return -1;
 + wtlen = strlen(work_tree);
 + len = strlen(path);

I expect that this is called from a callsite that _knows_ how long
path[] is.  Shouldn't len be a parameter to this function instead?

 + off = 0;
 +
 + /* check if work tree is already the prefix */
 + if (strncmp(path, work_tree, wtlen) == 0) {

I wonder if we want to be explicit and compare wtlen and len before
even attempting strncmp().  If work_tree is longer than path, it
cannot be a prefix of path, right?

In other words, also with a style-fix to prefer !XXcmp() over
XXcmp() == 0:

if (wtlen = len  !strncmp(path, work_tree, wtlen)) {

perhaps?  That would make it clear why referring to path[wtlen] on
the next line is permissible (it is obvious that it won't access
past the end of path[]):

 + if (path[wtlen] == '/') {
 + memmove(path, path + wtlen + 1, len - wtlen);
 + return 0;
 + } else if (path[wtlen - 1] == '/' || path[wtlen] == '\0') {
 + /* work tree is the root, or the whole path */
 + memmove(path, path + wtlen, len - wtlen + 1);

If work_tree[] == /, path[] == /a, then len == 2, wtlen == 1,
path[wtlen - 1] == '/' and this shifts path[] to the left by one,
leaving path[] = a, which is what we want.  OK.

If work_tree[] == path[] == /a, then len == wtlen == 2,
path[wtlen] == '\0', and this becomes equivalent to path[0] = '\0'.
Hmph  How do our callers treat an empty path?  In other words,
should these three be equivalent?

cd /a  git ls-files /a
cd /a  git ls-files 
cd /a  git ls-files .

 + return 0;
 + }
 + /* work tree might match beginning of a symlink to work tree */
 + off = wtlen;
 + }
 + path0 = path;
 + path += offset_1st_component(path) + off;
 +
 + /* check each level */
 + while (*path) {
 + path++;
 + if (*path == '/') {
 + *path = '\0';
 + if (strcmp(real_path(path0), work_tree) == 0) {
 + memmove(path0, path + 1, len - (path - path0));
 + return 0;
 + }
 + *path = '/';
 + }
 + }
 +
 + /* check whole path */
 + if (strcmp(real_path(path0), work_tree) == 0) {
 + *path0 = '\0';
 + return 0;
 + }
 +
 + return -1;
 +}
 +
 +/*
   * Normalize path, prepending the prefix for relative paths. If
   * remaining_prefix is not NULL, return the actual prefix still
   * remains in the path. For example, prefix = sub1/sub2/ and path is
--
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 8/9] rebase: add the --gpg-sign option

2014-02-03 Thread Junio C Hamano
brian m. carlson sand...@crustytoothpaste.net writes:

 diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
 index 43c19e0..73d32dd 100644
 --- a/git-rebase--interactive.sh
 +++ b/git-rebase--interactive.sh
 @@ -181,7 +181,7 @@ exit_with_patch () {
   git rev-parse --verify HEAD  $amend
   warn You can amend the commit now, with
   warn
 - warn   git commit --amend
 + warn   git commit --amend $gpg_sign_opt
   warn
   warn Once you are satisfied with your changes, run
   warn
 @@ -248,7 +248,8 @@ pick_one () {
  
   test -d $rewritten 
   pick_one_preserving_merges $@  return
 - output eval git cherry-pick $strategy_args $empty_args $ff $@
 + output eval git cherry-pick ${gpg_sign_opt:+$gpg_sign_opt} \
 + $strategy_args $empty_args $ff $@

This uses $gpg_sign_opt on eval, which means that the variable's
contents must be properly shell quoted, e.g.

gpg_sign_opt='-S'\''brian m. carson sand...@c.net'\'

throughout this script, so that everything between the first
double-quote  and closing ket  is passed as a single parameter
without being broken up.

 @@ -359,7 +360,8 @@ pick_one_preserving_merges () {
   echo $sha1 $(git rev-parse HEAD^0)  
 $rewritten_list
   ;;
   *)
 - output eval git cherry-pick $strategy_args $@ ||
 + output eval git cherry-pick 
 ${gpg_sign_opt:+$gpg_sign_opt} \

And this part has the same expectation.  However...

 @@ -470,7 +472,8 @@ do_pick () {
  --no-post-rewrite -n -q -C $1 
   pick_one -n $1 
   git commit --allow-empty --allow-empty-message \
 ---amend --no-post-rewrite -n -q -C $1 ||
 +--amend --no-post-rewrite -n -q -C $1 \
 +${gpg_sign_opt:+$gpg_sign_opt} ||

This does not want that extra level of quoting.  It would want to
have something like this instead:

gpg_sign_opt='-Sbrian m. carson sand...@c.net'

I am not sure how you are managing these two conflicting needs of
the use sites.

 @@ -497,7 +500,7 @@ do_next () {
  
   mark_action_done
   do_pick $sha1 $rest
 - git commit --amend --no-post-rewrite || {
 + git commit --amend --no-post-rewrite 
 ${gpg_sign_opt:+$gpg_sign_opt} || {

Ditto.

 diff --git a/git-rebase--merge.sh b/git-rebase--merge.sh
 index e7d96de..5381857 100644
 --- a/git-rebase--merge.sh
 +++ b/git-rebase--merge.sh
 @@ -27,7 +27,7 @@ continue_merge () {
   cmt=`cat $state_dir/current`
   if ! git diff-index --quiet --ignore-submodules HEAD --
   then
 - if ! git commit --no-verify -C $cmt
 + if ! git commit ${gpg_sign_opt:+$gpg_sign_opt} --no-verify -C 
 $cmt

Ditto.

   then
   echo Commit failed, please do not call \git commit\
   echo directly, but instead do one of the following: 
 diff --git a/git-rebase.sh b/git-rebase.sh
 index 842d7d4..055af1b 100755
 --- a/git-rebase.sh
 +++ b/git-rebase.sh
 @@ -37,6 +37,7 @@ ignore-date!   passed to 'git am'
  whitespace=!   passed to 'git apply'
  ignore-whitespace! passed to 'git apply'
  C=!passed to 'git apply'
 +S,gpg-sign?GPG-sign commits
   Actions:
  continue!  continue
  abort! abort and check out the original branch
 @@ -85,6 +86,7 @@ preserve_merges=
  autosquash=
  keep_empty=
  test $(git config --bool rebase.autosquash) = true  autosquash=t
 +gpg_sign_opt=
  
  read_basic_state () {
   test -f $state_dir/head-name 
 @@ -107,6 +109,8 @@ read_basic_state () {
   strategy_opts=$(cat $state_dir/strategy_opts)
   test -f $state_dir/allow_rerere_autoupdate 
   allow_rerere_autoupdate=$(cat 
 $state_dir/allow_rerere_autoupdate)
 + test -f $state_dir/gpg_sign_opt 
 + gpg_sign_opt=$(cat $state_dir/gpg_sign_opt)
  }
  
  write_basic_state () {
 @@ -120,6 +124,7 @@ write_basic_state () {
   $state_dir/strategy_opts
   test -n $allow_rerere_autoupdate  echo $allow_rerere_autoupdate  
 \
   $state_dir/allow_rerere_autoupdate
 + test -n $gpg_sign_opt  echo $gpg_sign_opt  
 $state_dir/gpg_sign_opt
  }
  
  output () {
 @@ -324,6 +329,15 @@ do
   --rerere-autoupdate|--no-rerere-autoupdate)
   allow_rerere_autoupdate=$1
   ;;
 + --gpg-sign)
 + gpg_sign_opt=-S
 + ;;
 + --gpg-sign=*)
 + # Try to quote only the argument, as this will appear in 
 human-readable
 + # output as well as being passed to commands.
 + gpg_sign_opt=-S$(git rev-parse --sq-quote ${1#--gpg-sign=} |
 + sed 's/^ //')

Isn't an invocation of sed excessive?

gpg_sign_opt=$(git rev-parse --sq-quote 

Re: [RFC/PATCH] howto/maintain-git.txt: new version numbering scheme

2014-02-03 Thread Philip Oakley

From: Junio C Hamano gits...@pobox.com
Sent: Friday, January 31, 2014 11:14 PM

We wanted to call the upcoming release Git 1.9, with its
maintenance track being Git 1.9.1, Git 1.9.2, etc., but various
third-party tools are reported to assume that there are at least
three dewey-decimal components in our version number.

Adjust the plan so that vX.Y.0 are feature releases while vX.Y.Z
(Z  0) are maintenance releases.

Signed-off-by: Junio C Hamano gits...@pobox.com
---

* Haven't committed to this outline, but I am raising a
  weather-balloon to see reaction from the list.  Comments?



From a familiarity viewpoint the (my) expectation would be that a

colloquial V1.9 would be 1.9.0 under the hood (that is, the version
string would say that).

If we are progressing from V1.9 to V2.0 quickly (one cycle?), which I
understand is the plan, then mixing the minor development items (patch
series which progress to master) with the maintenance fixes over the
next few months, thus only having 1.9.x releases, sounds reasonable.

If there is going to be separate maintenance fixes from the patch series
developments then keeping to the previous 1.9.x.y for maintenance would
be better.

Will the new rapid counting continue after V2.0, such that we get to
V2.9 - V3.0 rather more quickly than V1.0 - V2.0 ?

The key discriminator would be to say when V2.0 will be out for deciding
the V1.9 sequence.

My £0.02p

Philip



Documentation/howto/maintain-git.txt | 18 +++---
1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/Documentation/howto/maintain-git.txt
b/Documentation/howto/maintain-git.txt
index 33ae69c..ca43787 100644
--- a/Documentation/howto/maintain-git.txt
+++ b/Documentation/howto/maintain-git.txt
@@ -39,26 +39,26 @@ The policy on Integration is informally mentioned
in A Note
from the maintainer message, which is periodically posted to
this mailing list after each feature release is made.

- - Feature releases are numbered as vX.Y.Z and are meant to
+ - Feature releases are numbered as vX.Y.0 and are meant to
   contain bugfixes and enhancements in any area, including
   functionality, performance and usability, without regression.

 - One release cycle for a feature release is expected to last for
   eight to ten weeks.

- - Maintenance releases are numbered as vX.Y.Z.W and are meant
-   to contain only bugfixes for the corresponding vX.Y.Z feature
-   release and earlier maintenance releases vX.Y.Z.V (V  W).
+ - Maintenance releases are numbered as vX.Y.Z and are meant
+   to contain only bugfixes for the corresponding vX.Y.0 feature
+   release and earlier maintenance releases vX.Y.W (W  Z).

 - 'master' branch is used to prepare for the next feature
   release. In other words, at some point, the tip of 'master'
-   branch is tagged with vX.Y.Z.
+   branch is tagged with vX.Y.0.

 - 'maint' branch is used to prepare for the next maintenance
-   release.  After the feature release vX.Y.Z is made, the tip
+   release.  After the feature release vX.Y.0 is made, the tip
   of 'maint' branch is set to that release, and bugfixes will
   accumulate on the branch, and at some point, the tip of the
-   branch is tagged with vX.Y.Z.1, vX.Y.Z.2, and so on.
+   branch is tagged with vX.Y.1, vX.Y.2, and so on.

 - 'next' branch is used to publish changes (both enhancements
   and fixes) that (1) have worthwhile goal, (2) are in a fairly
@@ -86,6 +86,10 @@ this mailing list after each feature release is
made.
   users are encouraged to test it so that regressions and bugs
   are found before new topics are merged to 'master'.

+Note that before v1.9.0 release, the version numbers used to be
+structured slightly differently.  vX.Y.Z were feature releases while
+vX.Y.Z.W were maintenance releases for vX.Y.Z.
+

A Typical Git Day
-
--
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



--
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: [WIP/PATCH 1/9] submodule: prepare for recursive checkout of submodules

2014-02-03 Thread Junio C Hamano
Jens Lehmann jens.lehm...@web.de writes:

 This commit adds the functions and files needed for configuration,

Please just say Add the functions and files needed for 

 +++ b/Documentation/recurse-submodules-update.txt
 @@ -0,0 +1,8 @@
 +--[no-]recurse-submodules::
 + Using --recurse-submodules will update the work tree of all
 + initialized submodules according to the commit recorded in the
 + superproject if their update configuration is set to checkout'. If

That single quote does not seem to be closing any matching quote.

The phrase according to feels a bit too fuzzy.  Merging the commit
to what is checked out is one possible implementation of according to.
Applying the diff between the commit and what is checked out to work
tree is another.  Resetting the work tree files to exactly match the
commit would be yet another.

I think update the work trees to the commit (i.e. lose the
according) would be the closest to what you are trying to say
here.

 + local modifications in a submodule would be overwritten the checkout
 + will fail unless forced. Without this option or with
 + --no-recurse-submodules is, the work trees of submodules will not be
 + updated, only the hash recorded in the superproject will be updated.

It is unclear what happens if their update configuration is set to
something other than 'checkout'.

 diff --git a/submodule.c b/submodule.c
 index 613857e..b3eb28d 100644
 --- a/submodule.c
 +++ b/submodule.c
 @@ -382,6 +384,48 @@ int parse_fetch_recurse_submodules_arg(const char *opt, 
 const char *arg)
 ...
 +int option_parse_update_submodules(const struct option *opt,
 +const char *arg, int unset)
 +{
 + if (unset) {
 + *(int *)opt-value = RECURSE_SUBMODULES_OFF;
 + } else {
 + if (arg)
 + *(int *)opt-value = 
 parse_update_recurse_submodules_arg(opt-long_name, arg);
 + else
 + *(int *)opt-value = RECURSE_SUBMODULES_ON;
 + }

You can easily unnest to lose {}

if (unset)
value = off;
else if (arg)
value = parse...;
else
value = on;

Also I suspect that git_config_maybe_bool() natively knows how to
handle arg==NULL, so

if (unset)
value = off;
else
value = parse...;

is sufficient?
--
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: [WIP/PATCH 2/9] Teach reset the --[no-]recurse-submodules option

2014-02-03 Thread Junio C Hamano
Jens Lehmann jens.lehm...@web.de writes:

 This new option will allow the user to not only reset the work tree of
 the superproject but to also update the work tree of all initialized
 submodules (so they match the SHA-1 recorded in the superproject) when
 used together with --hard or --merge. But this commit only adds the

I agree that --soft and --mixed should not do anything.  I am not
sure why --keep should not do anything to submodule working trees
when asked to recurse, though.

 option without any functionality, that will be added to unpack_trees()
 in subsequent commits.

 Signed-off-by: Jens Lehmann jens.lehm...@web.de
 ---
  Documentation/git-reset.txt |  4 
  builtin/reset.c | 14 ++
  2 files changed, 18 insertions(+)

 diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
 index f445cb3..8f833f4 100644
 --- a/Documentation/git-reset.txt
 +++ b/Documentation/git-reset.txt
 @@ -94,6 +94,10 @@ OPTIONS
  --quiet::
   Be quiet, only report errors.

 +include::recurse-submodules-update.txt[]
 ++
 +This option only makes sense together with `--hard` and `--merge` and is
 +ignored when used without these options.

  EXAMPLES
  
 diff --git a/builtin/reset.c b/builtin/reset.c
 index 6004803..adf372e 100644
 --- a/builtin/reset.c
 +++ b/builtin/reset.c
 @@ -20,6 +20,7 @@
  #include parse-options.h
  #include unpack-trees.h
  #include cache-tree.h
 +#include submodule.h

  static const char * const git_reset_usage[] = {
   N_(git reset [--mixed | --soft | --hard | --merge | --keep] [-q] 
 [commit]),
 @@ -255,6 +256,8 @@ int cmd_reset(int argc, const char **argv, const char 
 *prefix)
  {
   int reset_type = NONE, update_ref_status = 0, quiet = 0;
   int patch_mode = 0, unborn;
 + const char *recurse_submodules_default = off;
 + int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
   const char *rev;
   unsigned char sha1[20];
   struct pathspec pathspec;
 @@ -270,13 +273,24 @@ int cmd_reset(int argc, const char **argv, const char 
 *prefix)
   OPT_SET_INT(0, keep, reset_type,
   N_(reset HEAD but keep local changes), KEEP),
   OPT_BOOL('p', patch, patch_mode, N_(select hunks 
 interactively)),
 + { OPTION_CALLBACK, 0, recurse-submodules, recurse_submodules,
 + checkout, control recursive updating of submodules,
 + PARSE_OPT_OPTARG, option_parse_update_submodules },
 + { OPTION_STRING, 0, recurse-submodules-default,
 + recurse_submodules_default, NULL,
 + default mode for recursion, PARSE_OPT_HIDDEN },
   OPT_END()
   };

 + gitmodules_config();
   git_config(git_default_config, NULL);

   argc = parse_options(argc, argv, prefix, options, git_reset_usage,
   PARSE_OPT_KEEP_DASHDASH);
 + set_config_update_recurse_submodules(
 + 
 parse_update_recurse_submodules_arg(--recurse-submodules-default,
 + recurse_submodules_default),
 + recurse_submodules);
   parse_args(pathspec, argv, prefix, patch_mode, rev);

   unborn = !strcmp(rev, HEAD)  get_sha1(HEAD, sha1);
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] gitk: show latest change to region

2014-02-03 Thread Max Kirillov
Hi!

I quite like the Show origin of this line feature of the
gitk. It is more convenient than blame, because it
directly answers the question which is usually addressed to
blame.

But, sometimes there is no key line which one could blame.
Instead there is a function, block, or some other region of
code. So I need a similar feature, but for several lines
rather than for a single one.

The series of patches implements the feature. It consists of
3 patches:

* gitk: refactor: separate generic hunk parsing out of find_hunk_blamespecs{}
* gitk: refactor: separate io from logic in the searching origin of line
* gitk: pick selection for region blame

It also requires the gitk: use single blamestuff for all
show_line_source{} calls patch, which it replies to.

-- 
Max
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] gitk: refactor: separate io from logic in the searching origin of line

2014-02-03 Thread Max Kirillov
The pattern of maintaining blame command and collecting output
can be reused for searching of latest change to region.
It still can use the blame's global variables, because the two
search commands should not run concurrently as well as two instances
of blame.

Signed-off-by: Max Kirillov m...@max630.net
---
 gitk | 23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/gitk b/gitk
index 7699a66..eef88a1 100755
--- a/gitk
+++ b/gitk
@@ -3771,7 +3771,7 @@ proc external_blame {parent_idx {line {}}} {
 }
 
 proc show_line_source {} {
-global cmitmode currentid parents curview blamestuff blameinst
+global cmitmode currentid parents curview
 global diff_menu_line diff_menu_filebase flist_menu_file
 global nullid nullid2 gitdir cdup
 
@@ -3827,6 +3827,12 @@ proc show_line_source {} {
lappend blameargs $id
 }
 lappend blameargs -- [file join $cdup $flist_menu_file]
+startblaming $blameargs read_line_source
+}
+
+proc startblaming {blameargs blamecommand} {
+global blamestuff blameinst
+
 if {[catch {
set f [open $blameargs r]
 } err]} {
@@ -3838,7 +3844,7 @@ proc show_line_source {} {
 set i [reg_instance $f]
 set blamestuff {}
 set blameinst $i
-filerun $f [list read_line_source $f $i]
+filerun $f [list blameiocallback $f $i $blamecommand]
 }
 
 proc stopblaming {} {
@@ -3852,8 +3858,8 @@ proc stopblaming {} {
 }
 }
 
-proc read_line_source {fd inst} {
-global blamestuff curview commfd blameinst nullid nullid2
+proc blameiocallback {fd inst blamecommand} {
+global blamestuff blameinst commfd
 
 while {[gets $fd line] = 0} {
lappend blamestuff $line
@@ -3871,6 +3877,14 @@ proc read_line_source {fd inst} {
return 0
 }
 
+$blamecommand
+unset blamestuff
+return 0
+}
+
+proc read_line_source {} {
+global blamestuff curview nullid nullid2
+
 set fname {}
 set line [split [lindex $blamestuff 0]  ]
 set id [lindex $line 0]
@@ -3901,7 +3915,6 @@ proc read_line_source {fd inst} {
 } else {
puts oops couldn't parse git blame output
 }
-unset blamestuff
 return 0
 }
 
-- 
1.8.5.2.421.g4cdf8d0

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] gitk: refactor: separate generic hunk parsing out of find_hunk_blamespecs{}

2014-02-03 Thread Max Kirillov
For requesting a region blame, it is necessary to parse a hunk and
find the region in the parent file corresponding to the selected region.
There is already hunk parsin functionality in the find_hunk_blamespec{},
but returns only information for a single line.

The new function, resolve_hunk_lines{}, scans the hunk once and returns
for all hunk lines between $start_diffline and $end_diffline, in which parent
each of them exists and which is its number there.

Signed-off-by: Max Kirillov m...@max630.net
---
 gitk | 93 ++--
 1 file changed, 57 insertions(+), 36 deletions(-)

diff --git a/gitk b/gitk
index dfac4fd..7699a66 100755
--- a/gitk
+++ b/gitk
@@ -3590,11 +3590,11 @@ proc external_diff {} {
 }
 }
 
-proc find_hunk_blamespec {base line} {
+proc resolve_hunk_lines {base start_diffline end_diffline} {
 global ctext
 
 # Find and parse the hunk header
-set s_lix [$ctext search -backwards -regexp ^@@ $line.0 lineend $base.0]
+set s_lix [$ctext search -backwards -regexp ^@@ $start_diffline.0 
lineend $base.0]
 if {$s_lix eq {}} return
 
 set s_line [$ctext get $s_lix $s_lix + 1 lines]
@@ -3614,49 +3614,70 @@ proc find_hunk_blamespec {base line} {
 }
 
 # Now scan the lines to determine offset within the hunk
-set max_parent [expr {[llength $base_lines]-2}]
-set dline 0
+set max_parent [expr {[llength $base_lines]-1}]
 set s_lno [lindex [split $s_lix .] 0]
 
-# Determine if the line is removed
-set chunk [$ctext get $line.0 $line.1 + $max_parent chars]
-if {[string match {[-+ ]*} $chunk]} {
-   set removed_idx [string first - $chunk]
-   # Choose a parent index
-   if {$removed_idx = 0} {
-   set parent $removed_idx
+set commitlines_by_diffline {}
+array unset commit_lines
+for {set p 0} {$p = $max_parent} {incr p} {
+   set commit_lines($p) [expr [lindex $base_lines $p] - 1]
+}
+for {set diffline [expr $s_lno + 1]} {$diffline = $end_diffline} {incr 
diffline} {
+   set chunk [$ctext get $diffline.0 $diffline.0 + $max_parent chars]
+   if {$chunk eq {} || [string match \[\n@\]* $chunk]} {
+   # region is larger than hunk
+   return {}
+   }
+   set is_removed [expr [string first - $chunk] = 0]
+   if {!$is_removed} {
+   incr commit_lines(0)
+   set commitlines [list [list 0 $commit_lines(0)]]
} else {
-   set unchanged_idx [string first   $chunk]
-   if {$unchanged_idx = 0} {
-   set parent $unchanged_idx
-   } else {
-   # blame the current commit
-   set parent -1
-   }
-   }
-   # then count other lines that belong to it
-   for {set i $line} {[incr i -1]  $s_lno} {} {
-   set chunk [$ctext get $i.0 $i.1 + $max_parent chars]
-   # Determine if the line is removed
-   set removed_idx [string first - $chunk]
-   if {$parent = 0} {
-   set code [string index $chunk $parent]
-   if {$code eq - || ($removed_idx  0  $code ne +)} {
-   incr dline
+   set commitlines {}
+   }
+   for {set p 1} {$p = $max_parent} {incr p} {
+   switch -- [string index $chunk $p-1] {
+   + {
}
-   } else {
-   if {$removed_idx  0} {
-   incr dline
+   - {
+   incr commit_lines($p)
+   lappend commitlines [list $p $commit_lines($p)]
+   }
+ {
+   if {!$is_removed} {
+   incr commit_lines($p)
+   lappend commitlines [list $p $commit_lines($p)]
+   }
+   }
+   default {
+   error_popup resolve_hunk_lines: unexpected diff 
line($diffline): $chunk
+   break
}
}
}
-   incr parent
-} else {
-   set parent 0
+   if {$diffline = $start_diffline} {
+   lappend commitlines_by_diffline [list $diffline $commitlines]
+   }
 }
+return $commitlines_by_diffline
+}
 
-incr dline [lindex $base_lines $parent]
-return [list $parent $dline]
+proc find_hunk_blamespec {base line} {
+foreach cl_spec [resolve_hunk_lines $base $line $line] {
+   if {[lindex $cl_spec 0] == $line} {
+   set commitlines [lindex $cl_spec 1]
+   if {[llength $commitlines]  0} {
+   if {[llength $commitlines]  1  [lindex $commitlines 0 0] eq 
0} {
+   return [lindex $commitlines 1]
+   } else {
+   return [lindex $commitlines 0]
+   }
+   } else {
+   error_popup find_hunk_blamespec: invalid commitlines: 
$commitlines
+   }
+   }
+}
+return {}
 }
 
 proc external_blame_diff {} {
-- 
1.8.5.2.421.g4cdf8d0

--
To 

[PATCH 3/3] gitk: pick selection for region blame

2014-02-03 Thread Max Kirillov
Add the new command to the diffmenu, Show the latest change of selected
region.  The menu command picks selection, and if it exists and covers
a single hunk, locates the latest change which has been made to the
selected lines in the file.

The menu command is disabled if the region blame is impossible, for
example if nothing is selected or the selection does not lie fully in a
single diff hunk.

The search is implemented by use of git log -L... command. Unlike git
blame, it can locate merges which brings together changes to the region
from different branches. This is what is desired, actually.

Unfortunally, using git log -L for finding a single line origin is
suboptimal, because (a) it does not support the --contents commandline
argument, or any other way to blame uncommitted changes, and (b) it is
noticeably slower. Hopely in some future git log -L will be mature
enough to be used for picking the single line origin, for now the best
option is to implement region logic separately, reusing their basic io.

For diffs, the first parent is always searched. This decision is quite
voluntary, just to avoid complications to UI.

Signed-off-by: Max Kirillov m...@max630.net
---
 gitk | 138 +++
 1 file changed, 138 insertions(+)

diff --git a/gitk b/gitk
index eef88a1..676c990 100755
--- a/gitk
+++ b/gitk
@@ -2650,6 +2650,7 @@ proc makewindow {} {
 makemenu $diff_menu {
{mc Show origin of this line command show_line_source}
{mc Run git gui blame on this line command {external_blame_diff}}
+   {mc Show the latest change of selected region command 
show_selection_source}
 }
 $diff_menu configure -tearoff 0
 }
@@ -3464,6 +3465,7 @@ proc pop_diff_menu {w X Y x y} {
 global ctext diff_menu flist_menu_file
 global diff_menu_txtpos diff_menu_line
 global diff_menu_filebase
+global selection_source_data
 
 set diff_menu_txtpos [split [$w index @$x,$y] .]
 set diff_menu_line [lindex $diff_menu_txtpos 0]
@@ -3476,6 +3478,12 @@ proc pop_diff_menu {w X Y x y} {
 if {$f eq {}} return
 set flist_menu_file [lindex $f 0]
 set diff_menu_filebase [lindex $f 1]
+prepare_show_selection_source
+if {$selection_source_data ne {}} {
+   $diff_menu entryconf 2 -state normal
+} else {
+   $diff_menu entryconf 2 -state disabled
+}
 tk_popup $diff_menu $X $Y
 }
 
@@ -3918,6 +3926,136 @@ proc read_line_source {} {
 return 0
 }
 
+proc show_selection_source {} {
+global selection_source_data
+global blameinst blamestuff
+
+if {$selection_source_data eq {}} {
+   return
+}
+
+foreach var {id fname lnum lnumber} val $selection_source_data { set $var 
$val }
+set args [list | git log --pretty=format:%H -L$lnum,+$lnumber:$fname -M 
-n1 $id]
+
+startblaming $args selsource_read
+}
+
+proc selsource_read {} {
+global blamestuff
+global curview
+
+set id {}
+set lnum {}
+set state start
+foreach l $blamestuff {
+   switch -- $state {
+   start { if {[regexp {^([0-9a-f]{40})$} $l _ id_match]} {
+   set id $id_match
+   set state diff_header_diff
+   } else {
+   break
+   }
+   }
+   diff_header_diff { if {[regexp {^diff --git} $l]} { set state 
diff_header_oldfile } else { break } }
+   diff_header_oldfile { if {[regexp {^---} $l]} {set state 
diff_header_newfile} else { break } }
+   diff_header_newfile {
+   if {[regexp {^\+\+\+ b/(.*)$} $l _ fname_match]} {
+   set fname $fname_match
+   set state diff_hunk_header
+   } else {
+   break
+   }
+   }
+   diff_hunk_header {
+   if {[regexp {^@@@*.* \+([0-9]+),[0-9]+ @@@*$} $l _ 
lnum_matched]} {
+   set lnum $lnum_matched
+   break
+   }
+   }
+   }
+}
+
+if {$id eq {}} {
+   error_popup [mc Parsing output of git log failed]
+   return 0
+}
+
+if {![commitinview $id $curview]} {
+   error_popup [mc The latest change is in commit %s, \
+which is not in this view [shortids $id]]
+   return 0
+}
+
+selectline [rowofcommit $id] 1 [list $fname $lnum]
+}
+
+proc prepare_show_selection_source {} {
+global ctext
+global selection_source_data
+
+set selection [$ctext tag ranges sel]
+if {[llength $selection] != 2} {
+   set selection_source_data {}
+   return
+}
+set start_line [lindex [split [lindex $selection 0] .] 0]
+set end_index [split [lindex $selection 1] .]
+if {[lindex $end_index 1] eq 0} {
+   set end_line [expr [lindex $end_index 0] - 1]
+} else {
+   set end_line [lindex $end_index 0]
+}
+set selection_source_data [prepare_show_region_source $start_line 

[PATCH 3/3 v2] gitk: show latest change to region

2014-02-03 Thread Max Kirillov
Add a new command to the diffmenu, Show the latest change of selected
region.  The menu command picks selection, and if it exists and covers
a single hunk, locates the latest change which has been made to the
selected lines in the file.

The menu command is disabled if the region blame is impossible, for
example if nothing is selected or the selection does not lie fully in a
single diff hunk.

The search is implemented by use of git log -L... command. Unlike git
blame, it can locate merges which brings together changes to the region
from different branches. This is what is desired, actually.

Unfortunally, using git log -L for finding a single line origin is
suboptimal, because (a) it does not support the --contents commandline
argument, or any other way to blame uncommitted changes, and (b) it is
noticeably slower. Hopely in some future git log -L will be mature
enough to be used for picking the single line origin, for now the best
option is to implement region logic separately, reusing the blame's basic io.

For diffs, the first parent is always searched. This decision is quite
voluntary, just to avoid complications to UI.

Signed-off-by: Max Kirillov m...@max630.net
---
Fixed comment, same code
 gitk | 138 +++
 1 file changed, 138 insertions(+)

diff --git a/gitk b/gitk
index eef88a1..676c990 100755
--- a/gitk
+++ b/gitk
@@ -2650,6 +2650,7 @@ proc makewindow {} {
 makemenu $diff_menu {
{mc Show origin of this line command show_line_source}
{mc Run git gui blame on this line command {external_blame_diff}}
+   {mc Show the latest change of selected region command 
show_selection_source}
 }
 $diff_menu configure -tearoff 0
 }
@@ -3464,6 +3465,7 @@ proc pop_diff_menu {w X Y x y} {
 global ctext diff_menu flist_menu_file
 global diff_menu_txtpos diff_menu_line
 global diff_menu_filebase
+global selection_source_data
 
 set diff_menu_txtpos [split [$w index @$x,$y] .]
 set diff_menu_line [lindex $diff_menu_txtpos 0]
@@ -3476,6 +3478,12 @@ proc pop_diff_menu {w X Y x y} {
 if {$f eq {}} return
 set flist_menu_file [lindex $f 0]
 set diff_menu_filebase [lindex $f 1]
+prepare_show_selection_source
+if {$selection_source_data ne {}} {
+   $diff_menu entryconf 2 -state normal
+} else {
+   $diff_menu entryconf 2 -state disabled
+}
 tk_popup $diff_menu $X $Y
 }
 
@@ -3918,6 +3926,136 @@ proc read_line_source {} {
 return 0
 }
 
+proc show_selection_source {} {
+global selection_source_data
+global blameinst blamestuff
+
+if {$selection_source_data eq {}} {
+   return
+}
+
+foreach var {id fname lnum lnumber} val $selection_source_data { set $var 
$val }
+set args [list | git log --pretty=format:%H -L$lnum,+$lnumber:$fname -M 
-n1 $id]
+
+startblaming $args selsource_read
+}
+
+proc selsource_read {} {
+global blamestuff
+global curview
+
+set id {}
+set lnum {}
+set state start
+foreach l $blamestuff {
+   switch -- $state {
+   start { if {[regexp {^([0-9a-f]{40})$} $l _ id_match]} {
+   set id $id_match
+   set state diff_header_diff
+   } else {
+   break
+   }
+   }
+   diff_header_diff { if {[regexp {^diff --git} $l]} { set state 
diff_header_oldfile } else { break } }
+   diff_header_oldfile { if {[regexp {^---} $l]} {set state 
diff_header_newfile} else { break } }
+   diff_header_newfile {
+   if {[regexp {^\+\+\+ b/(.*)$} $l _ fname_match]} {
+   set fname $fname_match
+   set state diff_hunk_header
+   } else {
+   break
+   }
+   }
+   diff_hunk_header {
+   if {[regexp {^@@@*.* \+([0-9]+),[0-9]+ @@@*$} $l _ 
lnum_matched]} {
+   set lnum $lnum_matched
+   break
+   }
+   }
+   }
+}
+
+if {$id eq {}} {
+   error_popup [mc Parsing output of git log failed]
+   return 0
+}
+
+if {![commitinview $id $curview]} {
+   error_popup [mc The latest change is in commit %s, \
+which is not in this view [shortids $id]]
+   return 0
+}
+
+selectline [rowofcommit $id] 1 [list $fname $lnum]
+}
+
+proc prepare_show_selection_source {} {
+global ctext
+global selection_source_data
+
+set selection [$ctext tag ranges sel]
+if {[llength $selection] != 2} {
+   set selection_source_data {}
+   return
+}
+set start_line [lindex [split [lindex $selection 0] .] 0]
+set end_index [split [lindex $selection 1] .]
+if {[lindex $end_index 1] eq 0} {
+   set end_line [expr [lindex $end_index 0] - 1]
+} else {
+   set end_line [lindex $end_index 0]
+}
+set selection_source_data 

Re: [WIP/PATCH 3/9] Teach checkout the --[no-]recurse-submodules option

2014-02-03 Thread Junio C Hamano
Jens Lehmann jens.lehm...@web.de writes:

 + set_config_update_recurse_submodules(
 + 
 parse_update_recurse_submodules_arg(--recurse-submodules-default,
 + recurse_submodules_default),
 + recurse_submodules);

I think I saw these exact lines in another patch.  Perhaps the whole
thing can become a helper function that lets the caller avoid typing
the whole long strings that needs a strange/unfortunate line break? 

 diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh
 index 06b18f8..bc3e1ca 100755
 --- a/t/t2013-checkout-submodule.sh
 +++ b/t/t2013-checkout-submodule.sh
 @@ -4,17 +4,57 @@ test_description='checkout can handle submodules'

  . ./test-lib.sh

 +submodule_creation_must_succeed() {

Style: SP before (), i.e.

submodule_creation_must_succeed () {

 + # checkout base ($1)
 + git checkout -f --recurse-submodules $1 
 + git diff-files --quiet 
 + git diff-index --quiet --cached $1 

Please make it a habit to quote a parameter that is intended not to
be split at $IFS (e.g. write these as $1 not as $1).  Otherwise
the reader has to wonder if this can be called with a foo bar and
the expects it to be split into two.

 + # checkout target ($2)
 + if test -d submodule; then

Style: no semicolons in standard control structure, i.e.

if test -d submodule
then

 + echo changesubmodule/first.t 

Style: SP before but not after redirection operator, i.e.

echo foo bar

 +submodule_removal_must_succeed() {

Likewise.

 + # checkout base ($1)
 + git checkout -f --recurse-submodules $1 

Likewise.

 + echo first  file 

Likewise.

 +test_expect_success 'checkout --recurse-submodules replaces submodule with 
 files' '
 + git checkout -f base 
 + git checkout -b replace_submodule_with_dir 
 + git update-index --force-remove submodule 
 + rm -rf submodule/.git .gitmodules 
 + git add .gitmodules submodule/* 
 + git commit -m submodule replaced 
 + git checkout -f base 
 + git submodule update -f 
 + git checkout --recurse-submodules replace_submodule_with_dir 
 + test -d submodule 
 + ! test -e submodule/.git 
 + test -f submodule/first.t 
 + test -f submodule/second.t
 +'

H.  Is it sufficient for these files to just exist, or do we
want to make sure they have expected contents?

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: [WIP/PATCH 4/9] Teach merge the --[no-]recurse-submodules option

2014-02-03 Thread Junio C Hamano
Jens Lehmann jens.lehm...@web.de writes:

 This new option will allow the user to not only update the work tree of
 the superproject according to the merge result but to also update the
 work tree of all initialized submodules (so they match the SHA-1 recorded
 in the superproject). But this commit only adds the option without any
 functionality, that will be added to unpack_trees() in subsequent commits.

When the two branches of the superproject being merged wants to put
a submodule project to commit A and B, that conflict needs to be
resolved, but if they agree that the submodule project should be at
C (which is different from what the current superproject HEAD has
for the submodule in its gitlink), then we want a checkout of that
commit to happen in that submodule.  Makes sense.

After resolving such a conflict between A and B, who is responsible
to adjust the working tree state of the submodule involved, by the
way?  git merge --continue does not exist and its moral equivalent
to conclude such an interrupted merge is git commit.  Should it
learn to do recurse-submodule, or should the user run a separate
checkout --recurse-submodule?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/8] tests: add checking that combine-diff emits only correct paths

2014-02-03 Thread Junio C Hamano
Kirill Smelkov k...@mns.spb.ru writes:

 where correct paths stands for paths that are different to all
 parents.

 Up until now, we were testing combined diff only on one file, or on
 several files which were all different (t4038-diff-combined.sh).

 As recent thinko in simplify intersect_paths() further showed, and
 also, since we are going to rework code for finding paths different to
 all parents, lets write at least basic tests.

Thanks.  Some nitpicks.


 Signed-off-by: Kirill Smelkov k...@mns.spb.ru
 ---
  t/t4057-diff-combined-paths.sh | 106 
 +
  1 file changed, 106 insertions(+)
  create mode 100755 t/t4057-diff-combined-paths.sh

 diff --git a/t/t4057-diff-combined-paths.sh b/t/t4057-diff-combined-paths.sh
 new file mode 100755
 index 000..e6e457d
 --- /dev/null
 +++ b/t/t4057-diff-combined-paths.sh
 @@ -0,0 +1,106 @@
 +#!/bin/sh
 +
 +test_description='combined diff show only paths that are different to all 
 parents'
 +
 +. ./test-lib.sh
 +
 +# verify that diffc.expect matches output of
 +# `git diff -c --name-only HEAD HEAD^ HEAD^2`
 +diffc_verify() {

Style: SP before (), i.e.

diffc_verify () {

 + git diff -c --name-only HEAD HEAD^ HEAD^2 diffc.actual 
 + test_cmp diffc.expect diffc.actual
 +}
 +
 +test_expect_success 'trivial merge - combine-diff empty' '
 + for i in `test_seq 1 9`

Style: prefer $() over ``

 + do
 + echo $i $i.txt 
 + git add $i.txt

Quiz.  What happens when this git add fails with an earlier value
of $i?

 + done 
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/8] tree-diff: no need to manually verify that there is no mode change for a path

2014-02-03 Thread Junio C Hamano
Kirill Smelkov k...@mns.spb.ru writes:

 Because if there is, such two tree entries would never be compared as
 equal - the code in base_name_compare() explicitly compares modes, if
 there is a change for dir bit, even for equal paths, entries would
 compare as different.

OK.
--
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 4/5] setup: Add 'abspath_part_inside_repo' function

2014-02-03 Thread Martin Erik Werner
On Mon, Feb 03, 2014 at 11:52:33AM -0800, Junio C Hamano wrote:
 Junio C Hamano gits...@pobox.com writes:
 
  Can we have that git foo $path to the testsuite as well?  That is
  the breakage we do not want to repeat in the future by regressing.
 
 Something like this, perhaps?
 
  t/t3004-ls-files-basic.sh | 17 +
  1 file changed, 17 insertions(+)
 
 diff --git a/t/t3004-ls-files-basic.sh b/t/t3004-ls-files-basic.sh
 index 8d9bc3c..d93089d 100755
 --- a/t/t3004-ls-files-basic.sh
 +++ b/t/t3004-ls-files-basic.sh
 @@ -36,4 +36,21 @@ test_expect_success 'ls-files -h in corrupt repository' '
   test_i18ngrep [Uu]sage: git ls-files  broken/usage
  '
  
 +test_expect_success SYMLINKS 'ls-files with symlinks' '
 + mkdir subs 
 + ln -s nosuch link 
 + ln -s ../nosuch subs/link 
 + git add link subs/link 
 + git ls-files -s link subs/link expect 
 + git ls-files -s $(pwd)/link $(pwd)/subs/link actual 
 + test_cmp expect actual 
 +
 + (
 + cd subs 
 + git ls-files -s link ../expect 
 + git ls-files -s $(pwd)/link ../actual
 + ) 
 + test_cmp expect actual
 +'
 +
  test_done

Your test looks preferrable to the simple git-add one that I proposed,
since it covers some more ground than the simple:

test_expect_success SYMLINKS 'add with abs path to link...' '
ln -s target link 
git add link
'

Will you add that test or should I place it in the series with you as
author?

On Mon, Feb 03, 2014 at 01:00:48PM -0800, Junio C Hamano wrote:
 Martin Erik Werner martinerikwer...@gmail.com writes:
 
  The path being exactly equal to the work tree is handled separately,
  since then there is no directory separator between the work tree and
  in-repo part.
 
 What is an in-repo part?  Whatever it is, I am not sure if I
 follow that logic.  After the while (*path) loop checks each level,
 you check the whole path---wouldn't that code handle that special
 case already?

Given /dir1/repo/dir2/file I've used 'in-repo' to refer to
dir2/file, sometimes interchangably with part inside the work tree
which might be better terminology, and should replace it?

I was trying to convey that if path is simply /dir/repo, then the while
loop method of replacing a '/' and checking from the beginning won't
work for the last level, since it has no terminating '/' to replace, so
hence it's a special case, mentioning the part inside the work tree
is arguably confusing in that case, since there isn't really one, maybe
it should be left out completely, since the check each level
explanation covers it already?

 
 Because it is probably the normal case not to have any symbolic link
 in the leading part (hence not having to dereference them), I think
 checking is work_tree[] a prefix of path[] early is justified from
 performance point of view, though.
 
   /*
  + * No checking if the path is in fact an absolute path is done, and it must
  + * already be normalized.
 
 This is not quite parsable to me.
Hmm, what about
The input parameter must contain an absolute path, and it must
already be normalized.
?

  + * Find the part of an absolute path that lies inside the work tree by
  + * dereferencing symlinks outside the work tree, for example:
  + * /dir1/repo/dir2/file   (work tree is /dir1/repo)  - dir2/file
  + * /dir/file  (work tree is /)   - dir/file
  + * /dir/symlink1/symlink2 (symlink1 points to work tree) - symlink2
  + * /dir/repolink/file (repolink points to /dir/repo) - file
  + * /dir/repo  (exactly equal to work tree)   - (empty string)
  + */
  +static inline int abspath_part_inside_repo(char *path)
 
 It looks a bit too big to be marked inline; better leave it to the
 compiler to notice that there is only a single callsite and decide
 to (or not to) inline it.

Ok, will do.

  +{
  +   size_t len;
  +   size_t wtlen;
  +   char *path0;
  +   int off;
  +
  +   const char* work_tree = get_git_work_tree();
  +   if (!work_tree)
  +   return -1;
  +   wtlen = strlen(work_tree);
  +   len = strlen(path);
 
 I expect that this is called from a callsite that _knows_ how long
 path[] is.  Shouldn't len be a parameter to this function instead?

Currently, it actually doesn't, since 'normalize_path_copy_len' is
called on it prior, which can mess with the string length. Do you think
the 'strlen' call should still be moved up a step into
'prefix_path_gently'?

  +   off = 0;
  +
  +   /* check if work tree is already the prefix */
  +   if (strncmp(path, work_tree, wtlen) == 0) {
 
 I wonder if we want to be explicit and compare wtlen and len before
 even attempting strncmp().  If work_tree is longer than path, it
 cannot be a prefix of path, right?
 
 In other words, also with a style-fix to prefer !XXcmp() over
 XXcmp() == 0:
 
   if (wtlen = len  !strncmp(path, work_tree, wtlen)) {
 
 perhaps?  That would make it clear why referring to path[wtlen] on
 the next line is 

Re: [PATCH 1/3] gitk: refactor: separate generic hunk parsing out of find_hunk_blamespecs{}

2014-02-03 Thread Eric Sunshine
On Mon, Feb 3, 2014 at 5:41 PM, Max Kirillov m...@max630.net wrote:
 For requesting a region blame, it is necessary to parse a hunk and
 find the region in the parent file corresponding to the selected region.
 There is already hunk parsin functionality in the find_hunk_blamespec{},

s/parsin/parsing/
s/in the/in/

 but returns only information for a single line.

s/but/but it/

 The new function, resolve_hunk_lines{}, scans the hunk once and returns
 for all hunk lines between $start_diffline and $end_diffline, in which parent
 each of them exists and which is its number there.

 Signed-off-by: Max Kirillov m...@max630.net
 ---
  gitk | 93 
 ++--
  1 file changed, 57 insertions(+), 36 deletions(-)

 diff --git a/gitk b/gitk
 index dfac4fd..7699a66 100755
 --- a/gitk
 +++ b/gitk
 @@ -3590,11 +3590,11 @@ proc external_diff {} {
  }
  }

 -proc find_hunk_blamespec {base line} {
 +proc resolve_hunk_lines {base start_diffline end_diffline} {
  global ctext

  # Find and parse the hunk header
 -set s_lix [$ctext search -backwards -regexp ^@@ $line.0 lineend 
 $base.0]
 +set s_lix [$ctext search -backwards -regexp ^@@ $start_diffline.0 
 lineend $base.0]
  if {$s_lix eq {}} return

  set s_line [$ctext get $s_lix $s_lix + 1 lines]
 @@ -3614,49 +3614,70 @@ proc find_hunk_blamespec {base line} {
  }

  # Now scan the lines to determine offset within the hunk
 -set max_parent [expr {[llength $base_lines]-2}]
 -set dline 0
 +set max_parent [expr {[llength $base_lines]-1}]
  set s_lno [lindex [split $s_lix .] 0]

 -# Determine if the line is removed
 -set chunk [$ctext get $line.0 $line.1 + $max_parent chars]
 -if {[string match {[-+ ]*} $chunk]} {
 -   set removed_idx [string first - $chunk]
 -   # Choose a parent index
 -   if {$removed_idx = 0} {
 -   set parent $removed_idx
 +set commitlines_by_diffline {}
 +array unset commit_lines
 +for {set p 0} {$p = $max_parent} {incr p} {
 +   set commit_lines($p) [expr [lindex $base_lines $p] - 1]
 +}
 +for {set diffline [expr $s_lno + 1]} {$diffline = $end_diffline} {incr 
 diffline} {
 +   set chunk [$ctext get $diffline.0 $diffline.0 + $max_parent chars]
 +   if {$chunk eq {} || [string match \[\n@\]* $chunk]} {
 +   # region is larger than hunk
 +   return {}
 +   }
 +   set is_removed [expr [string first - $chunk] = 0]
 +   if {!$is_removed} {
 +   incr commit_lines(0)
 +   set commitlines [list [list 0 $commit_lines(0)]]
 } else {
 -   set unchanged_idx [string first   $chunk]
 -   if {$unchanged_idx = 0} {
 -   set parent $unchanged_idx
 -   } else {
 -   # blame the current commit
 -   set parent -1
 -   }
 -   }
 -   # then count other lines that belong to it
 -   for {set i $line} {[incr i -1]  $s_lno} {} {
 -   set chunk [$ctext get $i.0 $i.1 + $max_parent chars]
 -   # Determine if the line is removed
 -   set removed_idx [string first - $chunk]
 -   if {$parent = 0} {
 -   set code [string index $chunk $parent]
 -   if {$code eq - || ($removed_idx  0  $code ne +)} {
 -   incr dline
 +   set commitlines {}
 +   }
 +   for {set p 1} {$p = $max_parent} {incr p} {
 +   switch -- [string index $chunk $p-1] {
 +   + {
 }
 -   } else {
 -   if {$removed_idx  0} {
 -   incr dline
 +   - {
 +   incr commit_lines($p)
 +   lappend commitlines [list $p $commit_lines($p)]
 +   }
 + {
 +   if {!$is_removed} {
 +   incr commit_lines($p)
 +   lappend commitlines [list $p $commit_lines($p)]
 +   }
 +   }
 +   default {
 +   error_popup resolve_hunk_lines: unexpected diff 
 line($diffline): $chunk
 +   break
 }
 }
 }
 -   incr parent
 -} else {
 -   set parent 0
 +   if {$diffline = $start_diffline} {
 +   lappend commitlines_by_diffline [list $diffline $commitlines]
 +   }
  }
 +return $commitlines_by_diffline
 +}

 -incr dline [lindex $base_lines $parent]
 -return [list $parent $dline]
 +proc find_hunk_blamespec {base line} {
 +foreach cl_spec [resolve_hunk_lines $base $line $line] {
 +   if {[lindex $cl_spec 0] == $line} {
 +   set commitlines [lindex $cl_spec 1]
 +   if {[llength $commitlines]  0} {
 +   if {[llength $commitlines]  1  [lindex $commitlines 0 0] 
 eq 0} {
 +   return [lindex $commitlines 1]
 +   } else {
 +   return [lindex $commitlines 0]
 + 

Re: [PATCH 5/8] combine-diff: move show_log_first logic/action out of paths scanning

2014-02-03 Thread Junio C Hamano
Kirill Smelkov k...@mns.spb.ru writes:

 Judging from sample outputs and tests nothing changes in diff -c output,

Yuck.

I do not think the processing done inside the loop for the first
path (i.e. i==0) before we call show_log(rev) affects what that
called show_log(rev) does, so it probably is a good readability
change.

Thanks.

 and this change will help later patches, when we'll be refactoring paths
 scanning into its own function with several variants - the
 show_log_first logic / code will stay common to all of them.

 NOTE: only now we have to take care to explicitly not show anything if
 parents array is empty, as in fact there are some clients in Git code,
 which calls diff_tree_combined() in such a way.

 Signed-off-by: Kirill Smelkov k...@mns.spb.ru
 ---
  combine-diff.c | 24 ++--
  1 file changed, 14 insertions(+), 10 deletions(-)

 diff --git a/combine-diff.c b/combine-diff.c
 index a03147c..272931f 100644
 --- a/combine-diff.c
 +++ b/combine-diff.c
 @@ -1313,6 +1313,20 @@ void diff_tree_combined(const unsigned char *sha1,
   struct combine_diff_path *p, *paths = NULL;
   int i, num_paths, needsep, show_log_first, num_parent = parents-nr;
  
 + /* nothing to do, if no parents */
 + if (!num_parent)
 + return;
 +
 + show_log_first = !!rev-loginfo  !rev-no_commit_id;
 + needsep = 0;
 + if (show_log_first) {
 + show_log(rev);
 +
 + if (rev-verbose_header  opt-output_format)
 + printf(%s%c, diff_line_prefix(opt),
 +opt-line_termination);
 + }
 +
   diffopts = *opt;
   copy_pathspec(diffopts.pathspec, opt-pathspec);
   diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
 @@ -1321,8 +1335,6 @@ void diff_tree_combined(const unsigned char *sha1,
   /* tell diff_tree to emit paths in sorted (=tree) order */
   diffopts.orderfile = NULL;
  
 - show_log_first = !!rev-loginfo  !rev-no_commit_id;
 - needsep = 0;
   /* find set of paths that everybody touches */
   for (i = 0; i  num_parent; i++) {
   /* show stat against the first parent even
 @@ -1338,14 +1350,6 @@ void diff_tree_combined(const unsigned char *sha1,
   diffcore_std(diffopts);
   paths = intersect_paths(paths, i, num_parent);
  
 - if (show_log_first  i == 0) {
 - show_log(rev);
 -
 - if (rev-verbose_header  opt-output_format)
 - printf(%s%c, diff_line_prefix(opt),
 -opt-line_termination);
 - }
 -
   /* if showing diff, show it in requested order */
   if (diffopts.output_format != DIFF_FORMAT_NO_OUTPUT 
   opt-orderfile) {
--
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 7/8] combine-diff: Fast changed-to-all-parents paths scanning

2014-02-03 Thread Junio C Hamano
Kirill Smelkov k...@mns.spb.ru writes:

 As was recently shown (c839f1bd combine-diff: optimize
 combine_diff_path sets intersection), combine-diff runs very slowly. In
 that commit we optimized paths sets intersection, but that accounted
 only for ~ 25% of the slowness, and as my tracing showed, for linux.git
 v3.10..v3.11, for merges a lot of time is spent computing
 diff(commit,commit^2) just to only then intersect that huge diff to
 almost small set of files from diff(commit,commit^1).

 That's because at present, to compute combine-diff, for first finding
 paths, that every parent touches, we use the following combine-diff
 property/definition:

 D(A,P1...Pn) = D(A,P1) ^ ... ^ D(A,Pn)  (w.r.t. paths)

 where

 D(A,P1...Pn) is combined diff between commit A, and parents Pi

 and

 D(A,Pi) is usual two-tree diff Pi..A

and A ^ B means what???

I do like the approach of walking the tree entries and stop as
shallowly as possible without recursing.
--
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 7/8] combine-diff: Fast changed-to-all-parents paths scanning

2014-02-03 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 Kirill Smelkov k...@mns.spb.ru writes:

 As was recently shown (c839f1bd combine-diff: optimize
 combine_diff_path sets intersection), combine-diff runs very slowly. In
 that commit we optimized paths sets intersection, but that accounted
 only for ~ 25% of the slowness, and as my tracing showed, for linux.git
 v3.10..v3.11, for merges a lot of time is spent computing
 diff(commit,commit^2) just to only then intersect that huge diff to
 almost small set of files from diff(commit,commit^1).

 That's because at present, to compute combine-diff, for first finding
 paths, that every parent touches, we use the following combine-diff
 property/definition:

 D(A,P1...Pn) = D(A,P1) ^ ... ^ D(A,Pn)  (w.r.t. paths)

 where

 D(A,P1...Pn) is combined diff between commit A, and parents Pi

 and

 D(A,Pi) is usual two-tree diff Pi..A

 and A ^ B means what???

Silly me; obviously it is the set intersection operator.

We probably could instead use the current set of paths as literal
pathspec to compute subsequent paths, i.e.

D(A,Pi,PS) is two tree diff P1..A limited to paths PS

D(A,P1...Pn) = D(A,P1,[]) ^
   D(A,P2,D(A,P1,[])) ^
   ...
   D(A,Pn,D(A,P1...Pn-1))

if we did not want to reinvent the whole tree walking thing, which
would add risks for new bugs and burden to maintain this and the
usual two-tree diff tree walking in sync.
--
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


Broken link on Git SCM E-Book

2014-02-03 Thread Varun Agrawal
In the footer, both links on the text are giving 404

Text is

This open sourced site is hosted on GitHub.
Patches, suggestions, and comments are welcome
--
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: [RFC/PATCH] howto/maintain-git.txt: new version numbering scheme

2014-02-03 Thread Junio C Hamano
Philip Oakley philipoak...@iee.org writes:

 If we are progressing from V1.9 to V2.0 quickly (one cycle?), which I
 understand is the plan, then mixing the minor development items (patch
 series which progress to master) with the maintenance fixes over the
 next few months, thus only having 1.9.x releases, sounds reasonable.

 If there is going to be separate maintenance fixes from the patch series
 developments then keeping to the previous 1.9.x.y for maintenance would
 be better.

 Will the new rapid counting continue after V2.0, such that we get to
 V2.9 - V3.0 rather more quickly than V1.0 - V2.0 ?

 The key discriminator would be to say when V2.0 will be out for deciding
 the V1.9 sequence.

I do not quite follow.  The time distance between v1.9 and v2.0
should not affect anything.  If it is a long road, there may be
v1.10, v1.11, v1.12, ... before we have v2.0.  If not, v2.0 may
immediately follow v1.9 as a new feature release.  There may be
maintenance releases based on v1.9 that does not add any new
features.

Right now, if you count the maintenance releases, there are
potentially four kinds of version gaps:

 - Between v1.8.5 and v1.8.5.1, there are fixes but no new features;

 - Between v1.8.5 and v1.8.6, there are new features but no
   compatibility worries;

 - Between v1.8.6 and v1.9.0, there are new features, no
   compatibility worries, but somehow the jump is larger than the
   one between v1.8.5 and v1.8.6; and

 - Between v1.9.0 and v2.0.0, there are new features and also
   compatibility concerns.

Switching to 2-digit scheme and calling the upcoming one v1.9 (and
the next major one v2.0) was meant to make the naming more flat, as
the third item in the above list somehow the jump is larger does
not seem to add much value to the end users.  So the logical
numbering becomes more like this:

 - Between v1.9 and v1.9.1, there are fixes but no new features;

 - Between v1.9.x and v1.10, there are new features but no
   compatibility worries;

 - Between v1.9.x and v2.0, there are new features and also
   compatibility concerns.

With a twist, though.  There seem to be many places where at least
three digits are assumed to exist in our version numbers, so in
order to make life easier, the updated document says vX.Y (a feature
release) will identify itself as vX.Y.0

--
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 7/8] combine-diff: Fast changed-to-all-parents paths scanning

2014-02-03 Thread Junio C Hamano
Kirill Smelkov k...@mns.spb.ru writes:

 + parents_sha1 = xmalloc(nparent * sizeof(parents_sha1[0]));
 + for (i = 0; i  nparent; i++)
 + parents_sha1[i] = parents-sha1[i];
 +
 + /* fake list head, so worker can assume it is non-NULL */
 + struct combine_diff_path paths_head;

decl-after-statement; please fix.

 + paths_head.next = NULL;
 +
 + struct strbuf base;

likewise.

--
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: [WIP/PATCH 1/9] submodule: prepare for recursive checkout of submodules

2014-02-03 Thread Jonathan Nieder
Jens Lehmann wrote:

 This commit adds the functions and files needed for configuration,
 documentation, setting the default behavior and determining if a
 submodule path should be updated automatically.

Yay!

[...]
  Documentation/recurse-submodules-update.txt |  8 +
  submodule.c | 50 
 +
  submodule.h |  6 
  3 files changed, 64 insertions(+)
  create mode 100644 Documentation/recurse-submodules-update.txt

I like the shared documentation snippet.

Ok, naive questions and overly pedantic nitpicking follow.  Patch with
a couple of suggested changes at the end.

[...]
 --- /dev/null
 +++ b/Documentation/recurse-submodules-update.txt
 @@ -0,0 +1,8 @@
 +--[no-]recurse-submodules::
 + Using --recurse-submodules will update the work tree of all
 + initialized submodules according to the commit recorded in the
 + superproject if their update configuration is set to checkout'. If
 + local modifications in a submodule would be overwritten the checkout
 + will fail unless forced. Without this option or with
 + --no-recurse-submodules is, the work trees of submodules will not be
 + updated, only the hash recorded in the superproject will be updated.

Tweaks:

 * Spelling out --no-recurse-submodules, --recurse-submodules (imitating
   e.g. --decorate in git-log(1))

 * Shortening, using imperative mood
 
 * Skipping description of safety check, since it matches how checkout
   works in general

That would make

--no-recurse-submodules::
--recurse-submodules::
Perform the checkout in submodules, too.  This only affects
submodules with update strategy `checkout` (which is the
default update strategy; see `submodule.name.update` in
link:gitmodules[5]).
+
The default behavior is to update submodule entries in the superproject
index and to leave the inside of submodules alone.  That behavior can 
also
be requested explicitly with --no-recurse-submodules.

Ideas for further work:

 * The safety check probably deserves a new section where it could be
   described in detail alongside a description of the corresponding check
   for plain checkout.  Then the description of the -f option could
   point to that section.

 * What happens when update = merge, rebase, or !command?  I think
   skipping them for now like suggested above is fine, but:

   - It would be even better to error out when there are changes to carry
 over with update = merge or rebase

   - Better still to perform the rebase when update = rebase

   - I have no idea what update = merge should do for non-fast-forward
 moves

 --- a/submodule.c
 +++ b/submodule.c
 @@ -16,6 +16,8 @@ static struct string_list config_name_for_path;
  static struct string_list config_fetch_recurse_submodules_for_name;
  static struct string_list config_ignore_for_name;
  static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND;
 +static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
 +static int option_update_recurse_submodules = RECURSE_SUBMODULES_DEFAULT;

Confusingly, config_update_recurse_submodules is set using the
--recurse-submodules-default option, not configuration.  There's
precedent for that in fetch.recurseSubmodules handling, but perhaps
a comment would help --- something like

/*
 * When no --recurse-submodules option was passed, should git fetch
 * from submodules where submodule.name.fetchRecurseSubmodules
 * doesn't indicate what to do?
 *
 * Controlled by fetch.recurseSubmodules.  The default is determined by
 * the --recurse-submodules-default option, which propagates
 * --recurse-submodules from the parent git process when recursing.
 */
static int config_fetch_recurse_submodules = 
RECURSE_SUBMODULES_ON_DEMAND;

/*
 * When no --recurse-submodules option was passed, should git update
 * the index and worktree within submodules (and in turn their
 * submodules, etc)?
 *
 * Controlled by the --recurse-submodules-default option, which
 * propagates --recurse-submodules from the parent git process
 * when recursing.
 */
static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;

[...]
 @@ -382,6 +384,48 @@ int parse_fetch_recurse_submodules_arg(const char *opt, 
 const char *arg)
   }
  }
 
 +int parse_update_recurse_submodules_arg(const char *opt, const char *arg)
 +{
 + switch (git_config_maybe_bool(opt, arg)) {
 + case 1:
 + return RECURSE_SUBMODULES_ON;
 + case 0:
 + return RECURSE_SUBMODULES_OFF;
 + default:
 + if (!strcmp(arg, checkout))
 + return RECURSE_SUBMODULES_ON;

Hm, is this arg == checkout case futureproofing for when

Re: [PATCH v5 5/5] setup: Don't dereference in-tree symlinks for absolute paths

2014-02-03 Thread Junio C Hamano
Martin Erik Werner martinerikwer...@gmail.com writes:

 Then it seems like one could get rid of npath completely:

Yes.  And you need to remove its definition as well to avoid unused
variable warning.

Will queue with an obvious fix-up.

Thanks.


 diff --git a/setup.c b/setup.c
 index 230505c..dd120cd 100644
 --- a/setup.c
 +++ b/setup.c
 @@ -88,21 +88,17 @@ char *prefix_path_gently(const char *prefix, int len,
   if (is_absolute_path(orig)) {
   char *npath;
  
 - npath = xmalloc(strlen(path) + 1);
 + sanitized = xmalloc(strlen(path) + 1);
   if (remaining_prefix)
   *remaining_prefix = 0;
 - if (normalize_path_copy_len(npath, path, remaining_prefix)) {
 - free(npath);
 + if (normalize_path_copy_len(sanitized, path, remaining_prefix)) 
 {
 + free(sanitized);
   return NULL;
   }
 - if (abspath_part_inside_repo(npath)) {
 - free(npath);
 + if (abspath_part_inside_repo(sanitized)) {
 + free(sanitized);
   return NULL;
   }
 -
 - sanitized = xmalloc(strlen(npath) + 1);
 - strcpy(sanitized, npath);
 - free(npath);
   } else {
   sanitized = xmalloc(len + strlen(path) + 1);
   if (len)

 at the cost of 'sanitized' always being the length of path, regardless
 if it's shorter, or even a NUL string.

 --
 Martin Erik Werner martinerikwer...@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: [WIP/PATCH 9/9] submodule: teach unpack_trees() to update submodules

2014-02-03 Thread Duy Nguyen
On Tue, Feb 4, 2014 at 2:54 AM, Jens Lehmann jens.lehm...@web.de wrote:
 Implement the functionality needed to enable work tree manipulating
 commands so that an changed submodule does not only affect the index but
 it also updates the work tree of any initialized submodule according to
 the SHA-1 recorded in the superproject.

 Signed-off-by: Jens Lehmann jens.lehm...@web.de
 ---
  entry.c| 15 --
  submodule.c| 86 
 ++
  submodule.h|  3 ++
  unpack-trees.c | 69 --
  unpack-trees.h |  1 +
  5 files changed, 157 insertions(+), 17 deletions(-)

 diff --git a/entry.c b/entry.c
 index d1bf6ec..61a2767 100644
 --- a/entry.c
 +++ b/entry.c
 @@ -265,7 +265,7 @@ int checkout_entry(struct cache_entry *ce,

 if (!check_path(path, len, st, state-base_dir_len)) {
 unsigned changed = ce_match_stat(ce, st, 
 CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
 -   if (!changed)
 +   if (!changed  (!S_ISDIR(st.st_mode) || 
 !S_ISGITLINK(ce-ce_mode)))
 return 0;

Should we report something when ce is a gitlink, but path is not a
directory, instead of siliently exit?

 diff --git a/submodule.c b/submodule.c
 index 3907034..83e7595 100644
 --- a/submodule.c
 +++ b/submodule.c
 @@ -520,6 +520,42 @@ int depopulate_submodule(const char *path)
 return 0;
  }

 +int update_submodule(const char *path, const unsigned char sha1[20], int 
 force)
 +{
 +   struct strbuf buf = STRBUF_INIT;
 +   struct child_process cp;
 +   const char *hex_sha1 = sha1_to_hex(sha1);
 +   const char *argv[] = {
 +   checkout,
 +   force ? -fq : -q,

respect state-quiet in checkout_entry() as well?

 +   hex_sha1,
 +   NULL,
 +   };
 +   const char *git_dir;
 +
 +   strbuf_addf(buf, %s/.git, path);
 +   git_dir = read_gitfile(buf.buf);
 +   if (!git_dir)
 +   git_dir = buf.buf;
 +   if (!is_directory(git_dir)) {
 +   strbuf_release(buf);
 +   /* The submodule is not populated, so we can't check it out */
 +   return 0;
 +   }
 +   strbuf_release(buf);
 +
 +   memset(cp, 0, sizeof(cp));
 +   cp.argv = argv;
 +   cp.env = local_repo_env;
 +   cp.git_cmd = 1;
 +   cp.no_stdin = 1;
 +   cp.dir = path;   /* GIT_WORK_TREE doesn't work for git checkout */

And if we do respect --quiet and it's not specified, paths printed by
this process is relative to dir, not to user cwd. Could be
confusing.

 +   if (run_command(cp))
 +   return error(Could not checkout submodule %s, path);
 +
 +   return 0;
 +}
 +
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] fast-import.c: always honor the filename case

2014-02-03 Thread Junio C Hamano
Torsten Bögershausen tbo...@web.de writes:

 []
 So to summarize, when fast-import uses strncmp_icase (what fast-import does 
 now) import on a repository where ignorecase=true is wrong.  My patch, 
 fast-import.c: always honor the filename case fixes this.  Can you verify?

 Thanks in advance,
 Reuben

 Yes, I can verify. My feeling is that
 a) the fast-export should generate the rename the other way around.
Would that be feasable ?
Or generate a real rename ?
   (I'm not using fast-export or import myself)

I do not think this matters.  Or at least, it should not matter.  As
Peff said in the nearby message, core.ignorecase is completely about
the _filesystem_, and that git should generally be case-sensitive
internally.

And fast-import is about reading internal representation of paths
and data to populate the repository, without having to guess what
pathnames were meant to be used---the guess is only needed if we
need to consult the filesystem that loses case information.

The change made by 50906e04 (Support case folding in git fast-import
when core.ignorecase=true, 2010-10-03) should probably be half
reverted by making the case-squashing an optional feature, that
could be used even on a system with case sensitive filesystems.

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


What's cooking in git.git (Feb 2014, #01; Mon, 3)

2014-02-03 Thread Junio C Hamano
Here are the topics that have been cooking.  Commits prefixed with
'-' are only in 'pu' (proposed updates) while commits prefixed with
'+' are in 'next'.

The tip of 'master' is at 1.9-rc2.

You can find the changes described here in the integration branches
of the repositories listed at

http://git-blame.blogspot.com/p/git-public-repositories.html

--
[New Topics]

* bs/stdio-undef-before-redef (2014-01-31) 1 commit
  (merged to 'next' on 2014-01-31 at 9874918)
 + git-compat-util.h: #undef (v)snprintf before #define them

 When we replace broken macros from stdio.h in git-compat-util.h,
 #undef them to avoid re-definition warnings from the C
 preprocessor.

 Will cook in 'next'.


* ep/varscope (2014-01-31) 7 commits
  (merged to 'next' on 2014-01-31 at d198f5d)
 + builtin/gc.c: reduce scope of variables
 + builtin/fetch.c: reduce scope of variable
 + builtin/commit.c: reduce scope of variables
 + builtin/clean.c: reduce scope of variable
 + builtin/blame.c: reduce scope of variables
 + builtin/apply.c: reduce scope of variables
 + bisect.c: reduce scope of variable

 Shrink lifetime of variables by moving their definitions to an
 inner scope where appropriate.

 Will cook in 'next'.


* mw/symlinks (2014-02-03) 5 commits
 - setup: don't dereference in-tree symlinks for absolute paths
 - setup: add 'abspath_part_inside_repo' function
 - t0060: add tests for prefix_path when path begins with work tree
 - t0060: add test for prefix_path when path == work tree
 - t0060: add test for manipulating symlinks via absolute paths

 All subcommands that take pathspecs mishandled an in-tree symbolic
 link when given it as a full path from the root (which arguably is
 a sick way to use pathspecs).  git ls-files -s $(pwd)/RelNotes in
 our tree is an easy reproduction recipe.

 We may want to add tests to illustrate symptoms that are visible to
 the end user, but the updated code looked reasonable.

 Will merge to 'next'.


* ks/diff-c-with-diff-order-more (2014-02-03) 5 commits
 - combine-diff: move changed-paths scanning logic into its own function
 - combine-diff: move show_log_first logic/action out of paths scanning
 - tree-diff: no need to pass match to skip_uninteresting()
 - tree-diff: no need to manually verify that there is no mode change for a path
 - tests: add checking that combine-diff emits only correct paths
 (this branch uses ks/diff-c-with-diff-order.)

 By avoiding running full two-way diff between the resulting
 revision and each of its N parents, combine-diff can be sped up
 significantly.

 Not quite sure if we want another custom tree walker for it, or it
 should be written by using existing two-way diff with the result of
 earlier intersect_path() as pathspec.

--
[Stalled]

* jk/color-for-more-pagers (2014-01-17) 4 commits
 - pager: disable colors for some known-bad configurations
 - DONOTMERGE: needs matching change to git-sh-setup
 - setup_pager: set MORE=R
 - setup_pager: refactor LESS/LV environment setting

 'more' implementation of BSD wants to be told with MORE=R
 environment before it shows colored output, while 'more' on some
 other platforms will die when seeing MORE=R environment.

 It appears that we are coming to the consensus that trying to be
 too intimately knowledgeable about quirks of various pager
 implementations on different platforms is a losing proposition.

 Waiting for a reroll.


* po/everyday-doc (2014-01-27) 1 commit
 - Make 'git help everyday' work

 This may make the said command to emit something, but the source is
 not meant to be formatted into a manual pages to begin with, and
 also its contents are a bit stale.  It may be a good first step in
 the right direction, but needs more work to at least get the
 mark-up right before public consumption.

 Will hold.


* jk/branch-at-publish-rebased (2014-01-17) 5 commits
 - t1507 (rev-parse-upstream): fix typo in test title
 - implement @{publish} shorthand
 - branch_get: provide per-branch pushremote pointers
 - branch_get: return early on error
 - sha1_name: refactor upstream_mark

 Give an easier access to the tracking branches from other side in
 a triangular workflow by introducing B@{publish} that works in a
 similar way to how B@{upstream} does.

 Will hold.


* rb/merge-prepare-commit-msg-hook (2014-01-10) 4 commits
 - merge: drop unused arg from abort_commit method signature
 - merge: make prepare_to_commit responsible for write_merge_state
 - t7505: ensure cleanup after hook blocks merge
 - t7505: add missing 

 Expose more merge states (e.g. $GIT_DIR/MERGE_MODE) to hooks that
 run during git merge.  The log message stresses too much on one
 hook, prepare-commit-msg, but it would equally apply to other hooks
 like post-merge, I think.

 Waiting for a reroll.


* jl/submodule-recursive-checkout (2013-12-26) 5 commits
 - Teach checkout to recursively checkout submodules
 - submodule: teach unpack_trees() to 

Re: splitting a commit that adds new files

2014-02-03 Thread Duy Nguyen
On Tue, Feb 4, 2014 at 1:11 AM, Junio C Hamano gits...@pobox.com wrote:
 Jeff King p...@peff.net writes:

 [1] I _do_ use reset -p when splitting commits, but I do not think it
 is useful here. I use it for oops, I staged this change, but it
 actually belongs in the next commit. Undo my staging, but leave the
 changes in the working tree for the next one.

 Sure.  I thought that was exactly what Duy was attempting to do when
 he splitted a commit into two (or more).

For splitting into two commits, reset -p or reset @^; add -p would
be more or less the same, although I still prefer to think this is
what I need than this is what I do _not_ need. add -p is more
convenient when the commit is big and you need to split into more than
two because the number of revert chunks may be higher than the number
of added chunks. I recall editing a patch with checkout -p sometimes
does not work, not sure it happens with reset -p too.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] t7101, t7014: rename test files to indicate what that file is for

2014-02-03 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Looks like a good thing to do.. Three files with the same -reset.sh
 suffix could be confusing.

 t/t7101-reset-empty-subdirs.sh (new +x) | 63 +
 t/t7101-reset.sh (gone) | 63 -
 t/t7104-reset-hard.sh (new +x)  | 46 
 t/t7104-reset.sh (gone) | 46 
 4 files changed, 109 insertions(+), 109 deletions(-)
 create mode 100755 t/t7101-reset-empty-subdirs.sh
 delete mode 100755 t/t7101-reset.sh
 create mode 100755 t/t7104-reset-hard.sh
 delete mode 100755 t/t7104-reset.sh

diff --git a/t/t7101-reset-empty-subdirs.sh b/t/t7101-reset-empty-subdirs.sh
new file mode 100755
index 000..96e163f
--- /dev/null
+++ b/t/t7101-reset-empty-subdirs.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Shawn Pearce
+#
+
+test_description='git reset should cull empty subdirs'
+. ./test-lib.sh
+
+test_expect_success \
+'creating initial files' \
+'mkdir path0 
+ cp $TEST_DIRECTORY/../COPYING path0/COPYING 
+ git add path0/COPYING 
+ git commit -m add -a'
+
+test_expect_success \
+'creating second files' \
+'mkdir path1 
+ mkdir path1/path2 
+ cp $TEST_DIRECTORY/../COPYING path1/path2/COPYING 
+ cp $TEST_DIRECTORY/../COPYING path1/COPYING 
+ cp $TEST_DIRECTORY/../COPYING COPYING 
+ cp $TEST_DIRECTORY/../COPYING path0/COPYING-TOO 
+ git add path1/path2/COPYING 
+ git add path1/COPYING 
+ git add COPYING 
+ git add path0/COPYING-TOO 
+ git commit -m change -a'
+
+test_expect_success \
+'resetting tree HEAD^' \
+'git reset --hard HEAD^'
+
+test_expect_success \
+'checking initial files exist after rewind' \
+'test -d path0 
+ test -f path0/COPYING'
+
+test_expect_success \
+'checking lack of path1/path2/COPYING' \
+'! test -f path1/path2/COPYING'
+
+test_expect_success \
+'checking lack of path1/COPYING' \
+'! test -f path1/COPYING'
+
+test_expect_success \
+'checking lack of COPYING' \
+'! test -f COPYING'
+
+test_expect_success \
+'checking checking lack of path1/COPYING-TOO' \
+'! test -f path0/COPYING-TOO'
+
+test_expect_success \
+'checking lack of path1/path2' \
+'! test -d path1/path2'
+
+test_expect_success \
+'checking lack of path1' \
+'! test -d path1'
+
+test_done
diff --git a/t/t7101-reset.sh b/t/t7101-reset.sh
deleted file mode 100755
index 96e163f..000
--- a/t/t7101-reset.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2006 Shawn Pearce
-#
-
-test_description='git reset should cull empty subdirs'
-. ./test-lib.sh
-
-test_expect_success \
-'creating initial files' \
-'mkdir path0 
- cp $TEST_DIRECTORY/../COPYING path0/COPYING 
- git add path0/COPYING 
- git commit -m add -a'
-
-test_expect_success \
-'creating second files' \
-'mkdir path1 
- mkdir path1/path2 
- cp $TEST_DIRECTORY/../COPYING path1/path2/COPYING 
- cp $TEST_DIRECTORY/../COPYING path1/COPYING 
- cp $TEST_DIRECTORY/../COPYING COPYING 
- cp $TEST_DIRECTORY/../COPYING path0/COPYING-TOO 
- git add path1/path2/COPYING 
- git add path1/COPYING 
- git add COPYING 
- git add path0/COPYING-TOO 
- git commit -m change -a'
-
-test_expect_success \
-'resetting tree HEAD^' \
-'git reset --hard HEAD^'
-
-test_expect_success \
-'checking initial files exist after rewind' \
-'test -d path0 
- test -f path0/COPYING'
-
-test_expect_success \
-'checking lack of path1/path2/COPYING' \
-'! test -f path1/path2/COPYING'
-
-test_expect_success \
-'checking lack of path1/COPYING' \
-'! test -f path1/COPYING'
-
-test_expect_success \
-'checking lack of COPYING' \
-'! test -f COPYING'
-
-test_expect_success \
-'checking checking lack of path1/COPYING-TOO' \
-'! test -f path0/COPYING-TOO'
-
-test_expect_success \
-'checking lack of path1/path2' \
-'! test -d path1/path2'
-
-test_expect_success \
-'checking lack of path1' \
-'! test -d path1'
-
-test_done
diff --git a/t/t7104-reset-hard.sh b/t/t7104-reset-hard.sh
new file mode 100755
index 000..f136ee7
--- /dev/null
+++ b/t/t7104-reset-hard.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+test_description='reset --hard unmerged'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+   mkdir before later 
+   before/1 
+   before/2 
+   hello 
+   later/3 
+   git add before hello later 
+   git commit -m world 
+
+   H=$(git rev-parse :hello) 
+   git rm --cached hello 
+   echo 100644 $H 2   hello | git update-index --index-info 
+
+   rm -f hello 
+   mkdir -p hello 
+   hello/world 
+   test $(git ls-files -o) = hello/world
+
+'
+
+test_expect_success 'reset --hard should restore unmerged ones' '
+
+   git reset --hard 
+   git ls-files --error-unmatch before/1 before/2 hello 

[PATCH 2/2] reset: support --mixed --intent-to-add mode

2014-02-03 Thread Nguyễn Thái Ngọc Duy
When --mixed is used, entries could be removed from index if the
target ref does not have them. When reset is used in preparation for
commit spliting (in a dirty worktree), it could be hard to track what
files to be added back. The new option --intent-to-add simplifies it
by marking all removed files intent-to-add.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git-reset.txt |  5 -
 builtin/reset.c | 19 +--
 cache.h |  1 +
 read-cache.c|  9 +
 t/t7102-reset.sh|  9 +
 5 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index f445cb3..a077ba0 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -10,7 +10,7 @@ SYNOPSIS
 [verse]
 'git reset' [-q] [tree-ish] [--] paths...
 'git reset' (--patch | -p) [tree-ish] [--] [paths...]
-'git reset' [--soft | --mixed | --hard | --merge | --keep] [-q] [commit]
+'git reset' [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [commit]
 
 DESCRIPTION
 ---
@@ -60,6 +60,9 @@ section of linkgit:git-add[1] to learn how to operate the 
`--patch` mode.
Resets the index but not the working tree (i.e., the changed files
are preserved but not marked for commit) and reports what has not
been updated. This is the default action.
++
+If `-N` is specified, removed paths are marked as intent-to-add (see
+linkgit:git-add[1]).
 
 --hard::
Resets the index and working tree. Any changes to tracked files in the
diff --git a/builtin/reset.c b/builtin/reset.c
index 6004803..f34eab4 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -116,6 +116,7 @@ static void update_index_from_diff(struct diff_queue_struct 
*q,
struct diff_options *opt, void *data)
 {
int i;
+   int *intent_to_add = data;
 
for (i = 0; i  q-nr; i++) {
struct diff_filespec *one = q-queue[i]-one;
@@ -128,13 +129,20 @@ static void update_index_from_diff(struct 
diff_queue_struct *q,
one-path);
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD |
ADD_CACHE_OK_TO_REPLACE);
+   } else if (*intent_to_add) {
+   int pos = cache_name_pos(one-path, strlen(one-path));
+   if (pos  0)
+   die(_(%s does not exist in index),
+   one-path);
+   set_intent_to_add(the_index, active_cache[pos]);
} else
remove_file_from_cache(one-path);
}
 }
 
 static int read_from_tree(const struct pathspec *pathspec,
- unsigned char *tree_sha1)
+ unsigned char *tree_sha1,
+ int intent_to_add)
 {
struct diff_options opt;
 
@@ -142,6 +150,7 @@ static int read_from_tree(const struct pathspec *pathspec,
copy_pathspec(opt.pathspec, pathspec);
opt.output_format = DIFF_FORMAT_CALLBACK;
opt.format_callback = update_index_from_diff;
+   opt.format_callback_data = intent_to_add;
 
if (do_diff_cache(tree_sha1, opt))
return 1;
@@ -258,6 +267,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
const char *rev;
unsigned char sha1[20];
struct pathspec pathspec;
+   int intent_to_add = 0;
const struct option options[] = {
OPT__QUIET(quiet, N_(be quiet, only report errors)),
OPT_SET_INT(0, mixed, reset_type,
@@ -270,6 +280,8 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
OPT_SET_INT(0, keep, reset_type,
N_(reset HEAD but keep local changes), KEEP),
OPT_BOOL('p', patch, patch_mode, N_(select hunks 
interactively)),
+   OPT_BOOL('N', intent-to-add, intent_to_add,
+   N_(record only the fact that removed paths 
will be added later)),
OPT_END()
};
 
@@ -327,6 +339,9 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
die(_(%s reset is not allowed in a bare repository),
_(reset_type_names[reset_type]));
 
+   if (intent_to_add  reset_type != MIXED)
+   die(_(-N can only be used with --mixed));
+
/* Soft reset does not touch the index file nor the working tree
 * at all, but requires them in a good order.  Other resets reset
 * the index file to the tree object we are switching to. */
@@ -338,7 +353,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
int newfd = hold_locked_index(lock, 1);
if (reset_type == MIXED) {
int flags = quiet ? REFRESH_QUIET : 
REFRESH_IN_PORCELAIN;
-   

bug? git push triggers auto pack when gc.auto = 0

2014-02-03 Thread chris
Hi,

I have garbage collection disabled globally with gc.auto = 0.  Today while
pushing a branch remotely, I saw a message Auto packing the repository for
optimum performance. which I've never noticed before.  Searching for that
phrase shows me that common knowledge is that 'gc.auto = 0' should disable
such from occurring.  Looking at .git/objects/pack/ in the repository show a
new pack file created at the time.  However, all loose objects still exist
in the repository, which is what I want, so it is good that no apparent data
loss occurred.

Here is the relevant command and its output:

$ git push origin next 
Counting objects: 56, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 895 bytes | 0 bytes/s, done.
Total 9 (delta 8), reused 0 (delta 0)
Auto packing the repository for optimum performance.
To ssh://g...@my.server.com/my_project
   3560275..f508080  next - next
$ git config gc.auto
0
$ git config gc.autopacklimit
0
$ git --version
git version 1.8.5.3

So my question is, should gc.auto = 0 disable auto-packing from occurring on
git push and other non-gc commands?

Thanks,

Chris


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: bug? git push triggers auto pack when gc.auto = 0

2014-02-03 Thread Duy Nguyen
On Tue, Feb 4, 2014 at 9:20 AM, chris j...@hotmail.com wrote:
 $ git push origin next
 Counting objects: 56, done.
 Delta compression using up to 4 threads.
 Compressing objects: 100% (9/9), done.
 Writing objects: 100% (9/9), 895 bytes | 0 bytes/s, done.
 Total 9 (delta 8), reused 0 (delta 0)
 Auto packing the repository for optimum performance.

This string only appears in versions before 1.8.0. It's longer after 1.8.0.

 To ssh://g...@my.server.com/my_project
3560275..f508080  next - next
 $ git config gc.auto
 0
 $ git config gc.autopacklimit
 0
 $ git --version
 git version 1.8.5.3

but your client is after 1.8.0 so the string printed above is from the
server side. git config gc.auto here does not matter. Run that
command again on my.server.com.

 So my question is, should gc.auto = 0 disable auto-packing from occurring on
 git push and other non-gc commands?

Yes it should.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] git-tag.txt: commit for --contains is optional

2014-02-03 Thread Nguyễn Thái Ngọc Duy
This goes far back to e84fb2f (branch --contains: default to HEAD -
2008-07-08) where the same parsing code is shared with
builtin/tag.c. git-branch.txt correctly states that commit for
--contains is optional while git-tag.txt does not. Correct it.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git-tag.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index c418c44..404257d 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -103,8 +103,9 @@ OPTIONS
 +
 This option is only applicable when listing tags without annotation lines.
 
---contains commit::
-   Only list tags which contain the specified commit.
+--contains [commit]::
+   Only list tags which contain the specified commit (HEAD if not
+   specified).
 
 --points-at object::
Only list tags of the given object.
-- 
1.8.5.2.240.g8478abd

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: bug? git push triggers auto pack when gc.auto = 0

2014-02-03 Thread chris
Duy Nguyen pclouds at gmail.com writes:
 On Tue, Feb 4, 2014 at 9:20 AM, chris jugg at hotmail.com wrote:
  $ git push origin next
  Counting objects: 56, done.
  Delta compression using up to 4 threads.
  Compressing objects: 100% (9/9), done.
  Writing objects: 100% (9/9), 895 bytes | 0 bytes/s, done.
  Total 9 (delta 8), reused 0 (delta 0)
  Auto packing the repository for optimum performance.
 
 This string only appears in versions before 1.8.0. It's longer after 1.8.0.
 
  To ssh://git at my.server.com/my_project
 3560275..f508080  next - next
  $ git config gc.auto
  0
  $ git config gc.autopacklimit
  0
  $ git --version
  git version 1.8.5.3
 
 but your client is after 1.8.0 so the string printed above is from the
 server side. git config gc.auto here does not matter. Run that
 command again on my.server.com.

Ok, so I can understand if the message is from the server.  I'll chalk up
never noticing it before to someone else always being the lucky one to
trigger it.

However, I question why I should even care about this message?  I'm going to
assume that simply it is a lengthy synchronous operation that someone felt
deserved some verbosity to why the client push action is taking longer than
it should.  Yet that makes me question why I'm being penalized for this
server side operation.  My client time should not be consumed for server
side house keeping.

An obvious fix is to disable gc on the server and implement a cron job for
the house keeping task.  However, as often the case one does not have
control over the server, so it is unfortunate that git has this server side
house keeping as a blocking operation to a client action.

  So my question is, should gc.auto = 0 disable auto-packing from occurring on
  git push and other non-gc commands?
 
 Yes it should.

Thanks for the confirmation.

Regards,

Chris



--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: bug? git push triggers auto pack when gc.auto = 0

2014-02-03 Thread Duy Nguyen
On Tue, Feb 4, 2014 at 12:13 PM, chris j...@hotmail.com wrote:
 However, I question why I should even care about this message?  I'm going to
 assume that simply it is a lengthy synchronous operation that someone felt
 deserved some verbosity to why the client push action is taking longer than
 it should.  Yet that makes me question why I'm being penalized for this
 server side operation.  My client time should not be consumed for server
 side house keeping.

 An obvious fix is to disable gc on the server and implement a cron job for
 the house keeping task.  However, as often the case one does not have
 control over the server, so it is unfortunate that git has this server side
 house keeping as a blocking operation to a client action.

I agree it should not block the client. I think you can Ctrl-C git
push at this point without losing anything (data has already been
pushed at this point) but that's not a good advice to general cases.
Maybe we can do something at the server side to not block the client..

Another thing we could do is put remote:  in front of these strings,
even in ssh case. They seem to confuse you (and me too) that things
happened locally.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] receive-pack: update $GIT_DIR/info before auto garbage collection

2014-02-03 Thread Nguyễn Thái Ngọc Duy
Auto gc could take a long time, and it's optional. git push user
should be allowed to stop the program if they don't want to wait. Move
server update step before auto gc. So we're ready to die any time
since auto gc is kicked off.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/receive-pack.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 85bba35..82e2f76 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1208,6 +1208,8 @@ int cmd_receive_pack(int argc, const char **argv, const 
char *prefix)
report(commands, unpack_status);
run_receive_hook(commands, post-receive, 1);
run_update_post_hook(commands);
+   if (auto_update_server_info)
+   update_server_info(0);
if (auto_gc) {
const char *argv_gc_auto[] = {
gc, --auto, --quiet, NULL,
@@ -1215,8 +1217,6 @@ int cmd_receive_pack(int argc, const char **argv, const 
char *prefix)
int opt = RUN_GIT_CMD | RUN_COMMAND_STDOUT_TO_STDERR;
run_command_v_opt(argv_gc_auto, opt);
}
-   if (auto_update_server_info)
-   update_server_info(0);
clear_shallow_info(si);
}
if (use_sideband)
-- 
1.8.5.2.240.g8478abd

--
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/RFC 2/2] receive-pack: hint that the user can stop git push at auto gc time

2014-02-03 Thread Nguyễn Thái Ngọc Duy
Housekeeping jobs like auto gc generally should not get in the way.
Users who are pushing may not want to wait until auto gc is done on
the server. Give a hint for those users that it's safe now to break
git push and stop waiting.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 This bandage patch may be a good compromise between running auto gc
 and not annoying users much.
 
 If I'm not mistaken, when ^C on git push this way, gc will still be
 running until it needs to print something out (which it should not
 normally because of --quiet). The user won't see gc errors, but the
 user generally can't do much anyway.

 builtin/gc.c   | 9 -
 builtin/receive-pack.c | 2 +-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/builtin/gc.c b/builtin/gc.c
index c19545d..592271a 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -253,6 +253,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
int auto_gc = 0;
int quiet = 0;
int force = 0;
+   int break_ok = 0;
const char *name;
pid_t pid;
 
@@ -263,6 +264,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire },
OPT_BOOL(0, aggressive, aggressive, N_(be more thorough 
(increased runtime))),
OPT_BOOL(0, auto, auto_gc, N_(enable auto-gc mode)),
+   OPT_HIDDEN_BOOL(0, break-ok, break_ok,
+   hint that it is ok to stop the program),
OPT_BOOL(0, force, force, N_(force running gc even if there 
may be another gc running)),
OPT_END()
};
@@ -301,7 +304,11 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 */
if (!need_to_gc())
return 0;
-   if (!quiet)
+   if (break_ok)
+   fprintf(stderr,
+   _(Auto packing the repository for optimum 
performance.\n
+ It is safe to stop the program with 
Ctrl-C.\n));
+   else if (!quiet)
fprintf(stderr,
_(Auto packing the repository for 
optimum performance. You may also\n
run \git gc\ manually. See 
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 82e2f76..68d16e0 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1212,7 +1212,7 @@ int cmd_receive_pack(int argc, const char **argv, const 
char *prefix)
update_server_info(0);
if (auto_gc) {
const char *argv_gc_auto[] = {
-   gc, --auto, --quiet, NULL,
+   gc, --auto, --quiet, --break-ok, NULL,
};
int opt = RUN_GIT_CMD | RUN_COMMAND_STDOUT_TO_STDERR;
run_command_v_opt(argv_gc_auto, opt);
-- 
1.8.5.2.240.g8478abd

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