Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
I would like to ignore branches that match a certain pattern, e.g.:

markus@x4 gcc % git branch -a
  gcc-4.8
* master
  remotes/origin/HEAD - origin/master
  remotes/origin/aldyh/cilk-in-gomp
...
  remotes/origin/hjl/arch
  remotes/origin/hjl/asan
...
  remotes/origin/hjl/x86/m16
  remotes/origin/ifunc
  remotes/origin/jason/4.6-cxx0x
  remotes/origin/jason/alias-decl
  remotes/origin/jason/comdat-debug
  remotes/origin/lw-ipo
  remotes/origin/master
...

Is it possible to ignore all branches that match hjl?

-- 
Markus
--
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 0/9] add --gpg-sign to rebase and pull

2014-01-24 Thread Nicolas Vigier
On Fri, 24 Jan 2014, brian m. carlson wrote:

 This series was posted to the list some time back, but it fell through
 the cracks.  This is a re-send of Nicolas Vigier's work with an
 additional patch that adds --gpg-sign to pull as well.  I added my
 sign-off to his patches because SubmittingPatches (section (c)) seems to
 imply that I should, although I can rebase it out if it's a problem.

Thanks!

An improvement I was thinking to do on this series but had not time to
do yet is to make the '--no-gpg-sign' option disable gpg signing when
the commit.gpgsign config option is set to true.

This would fix the problem mentioned about commit.gpgsign in What's
cooking in git.git that the variable cannot be overriden from the
command line of some of the commands that create commits.

Nicolas

--
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 0/9] About the trailing slashes

2014-01-24 Thread Nguyễn Thái Ngọc Duy
So this is the reroll that makes

  git diff HEAD submodule
  git diff HEAD submodule/

and

  git diff HEAD HEAD^ submodule
  git diff HEAD HEAD^ submodule/

behave the same way. The main patches are 04/09 and 09/09. The rest is
just refactoring and cleaning up.

While looking at this, I found a funny behavior of fill_directory.

  $ git init
  $ mkdir b
  $ b/c
  $ b/d
  $ git status b
  Untracked files:
  b/
  $ git status b/
  Untracked files:
  b/c b/d

Notice how the trailing slash produces different untracked listing.
This is because of common_prefix_len(). In the b case,
common_prefix_len() returns empty prefix, so read_directory reads top
directory, traverses through, reaches b and eventually calls
treat_directory() on it, which results in b/ in the output.

In the b/ case, common_prefix_len() found the prefix b, so
read_directory() starts at b instead of b's parent.
treat_directory() is never called on b itself, which results in
b/c and b/d.

I'm tempted to make it consistent, favoring b/ output. But that
involves extra lstat, or reordering the complex read_directory() code.
This is probably very unusual case to pay attention to anyway.

Nguyễn Thái Ngọc Duy (9):
  Convert some match_pathspec_depth() to ce_path_match()
  Convert some match_pathspec_depth() to dir_path_match()
  Rename match_pathspec_depth() to match_pathspec()
  dir.c: prepare match_pathspec_item for taking more flags
  match_pathspec: match pathspec foo/ against directory foo
  Pass directory indicator to match_pathspec_item()
  clean: replace match_pathspec() with dir_path_match()
  clean: use cache_name_is_other()
  tree-walk.c: ignore trailing slash on submodule in
tree_entry_interesting()

 builtin/add.c |  3 +--
 builtin/checkout.c|  3 +--
 builtin/clean.c   | 24 +++-
 builtin/commit.c  |  2 +-
 builtin/grep.c|  6 ++
 builtin/ls-files.c|  9 ++---
 builtin/ls-tree.c |  2 +-
 builtin/rm.c  |  2 +-
 builtin/update-index.c|  3 ++-
 cache.h   |  2 --
 diff-lib.c|  5 +++--
 dir.c | 40 ++--
 dir.h | 24 +---
 pathspec.c|  2 +-
 preload-index.c   |  3 ++-
 read-cache.c  |  8 +---
 rerere.c  |  4 ++--
 resolve-undo.c|  2 +-
 revision.c|  3 ++-
 t/t4010-diff-pathspec.sh  | 23 +++
 t/t6131-pathspec-icase.sh |  6 +++---
 tree-walk.c   |  2 +-
 wt-status.c   |  6 +++---
 23 files changed, 107 insertions(+), 77 deletions(-)

-- 
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 v2 8/9] clean: use cache_name_is_other()

2014-01-24 Thread Nguyễn Thái Ngọc Duy
cmd_clean() has the exact same code of index_name_is_other(). Reduce
code duplication.

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

diff --git a/builtin/clean.c b/builtin/clean.c
index 5adb52d..cb02a53 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -933,29 +933,12 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
 
for (i = 0; i  dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
-   int len, pos;
int matches = 0;
-   const struct cache_entry *ce;
struct stat st;
const char *rel;
 
-   /*
-* Remove the '/' at the end that directory
-* walking adds for directory entries.
-*/
-   len = ent-len;
-   if (len  ent-name[len-1] == '/')
-   len--;
-   pos = cache_name_pos(ent-name, len);
-   if (0 = pos)
-   continue;   /* exact match */
-   pos = -pos - 1;
-   if (pos  active_nr) {
-   ce = active_cache[pos];
-   if (ce_namelen(ce) == len 
-   !memcmp(ce-name, ent-name, len))
-   continue; /* Yup, this one exists unmerged */
-   }
+   if (!cache_name_is_other(ent-name, ent-len))
+   continue;
 
if (lstat(ent-name, st))
die_errno(Cannot lstat '%s', ent-name);
-- 
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 v2 6/9] Pass directory indicator to match_pathspec_item()

2014-01-24 Thread Nguyễn Thái Ngọc Duy
This patch activates the DO_MATCH_DIRECTORY code in m_p_i(), which
makes git diff HEAD submodule/ and git diff HEAD submodule produce
the same output. Previously only the version without trailing slash
returns the difference (if any).

That's the effect of new ce_path_match(). dir_path_match() is not
executed by the new tests. And it should not introduce regressions.

Previously if path dir/ is passed in with pathspec dir/, they
obviously match. With new dir_path_match(), the path becomes
_directory_ dir vs pathspec dir/, which is not executed by the old
code path in m_p_i(). The new code path is executed and produces the
same result.

The other case is pathspec dir and path dir/ is now turned to
dir (with DO_MATCH_DIRECTORY). Still the same result before or after
the patch.

So why change? Because of the next patch about clean.c.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/clean.c  |  2 +-
 builtin/ls-files.c   |  5 +++--
 dir.c|  4 ++--
 dir.h| 10 +++---
 rerere.c |  2 +-
 t/t4010-diff-pathspec.sh | 17 +
 6 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index f59c753..4c9680a 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -962,7 +962,7 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
 
if (pathspec.nr)
matches = match_pathspec(pathspec, ent-name,
-len, 0, NULL);
+len, 0, NULL, 0);
 
if (S_ISDIR(st.st_mode)) {
if (remove_directories || (matches == MATCHED_EXACTLY)) 
{
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 02db0e1..47c3880 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -140,7 +140,8 @@ static void show_ce_entry(const char *tag, const struct 
cache_entry *ce)
die(git ls-files: internal error - cache entry not superset of 
prefix);
 
if (!match_pathspec(pathspec, ce-name, ce_namelen(ce),
-   len, ps_matched))
+   len, ps_matched,
+   S_ISDIR(ce-ce_mode) || S_ISGITLINK(ce-ce_mode)))
return;
 
if (tag  *tag  show_valid_bit 
@@ -197,7 +198,7 @@ static void show_ru_info(void)
if (len  max_prefix_len)
continue; /* outside of the prefix */
if (!match_pathspec(pathspec, path, len,
-   max_prefix_len, ps_matched))
+   max_prefix_len, ps_matched, 0))
continue; /* uninterested */
for (i = 0; i  3; i++) {
if (!ui-mode[i])
diff --git a/dir.c b/dir.c
index 7b50072..2fd0ebd 100644
--- a/dir.c
+++ b/dir.c
@@ -360,10 +360,10 @@ static int do_match_pathspec(const struct pathspec *ps,
 
 int match_pathspec(const struct pathspec *ps,
   const char *name, int namelen,
-  int prefix, char *seen)
+  int prefix, char *seen, int is_dir)
 {
int positive, negative;
-   unsigned flags = 0;
+   unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0;
positive = do_match_pathspec(ps, name, namelen,
 prefix, seen, flags);
if (!(ps-magic  PATHSPEC_EXCLUDE) || !positive)
diff --git a/dir.h b/dir.h
index c31ed9a..55e5345 100644
--- a/dir.h
+++ b/dir.h
@@ -134,7 +134,7 @@ extern int no_wildcard(const char *string);
 extern char *common_prefix(const struct pathspec *pathspec);
 extern int match_pathspec(const struct pathspec *pathspec,
  const char *name, int namelen,
- int prefix, char *seen);
+ int prefix, char *seen, int is_dir);
 extern int within_depth(const char *name, int namelen, int depth, int 
max_depth);
 
 extern int fill_directory(struct dir_struct *dir, const struct pathspec 
*pathspec);
@@ -209,14 +209,18 @@ static inline int ce_path_match(const struct cache_entry 
*ce,
const struct pathspec *pathspec,
char *seen)
 {
-   return match_pathspec(pathspec, ce-name, ce_namelen(ce), 0, seen);
+   return match_pathspec(pathspec, ce-name, ce_namelen(ce), 0, seen,
+ S_ISDIR(ce-ce_mode) || S_ISGITLINK(ce-ce_mode));
 }
 
 static inline int dir_path_match(const struct dir_entry *ent,
 const struct pathspec *pathspec,
 int prefix, char *seen)
 {
-   return match_pathspec(pathspec, ent-name, ent-len, prefix, seen);
+   int has_trailing_dir = ent-len  ent-name[ent-len - 1] == '/';
+   int len = has_trailing_dir ? ent-len - 1 : ent-len;
+   return match_pathspec(pathspec, ent-name, len, prefix, seen,
+ 

[PATCH v2 9/9] tree-walk.c: ignore trailing slash on submodule in tree_entry_interesting()

2014-01-24 Thread Nguyễn Thái Ngọc Duy
We do ignore trailing slash on a directory, so pathspec abc/ matches
directory abc. A submodule is also a directory. Apply the same logic
to it. This makes git log submodule-path and git log submodule-path/
produce the same output.

Reported-by: Paweł Sikora pawel.sik...@agmk.net
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 t/t4010-diff-pathspec.sh | 6 ++
 tree-walk.c  | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
index 167af53..2424af0 100755
--- a/t/t4010-diff-pathspec.sh
+++ b/t/t4010-diff-pathspec.sh
@@ -127,4 +127,10 @@ test_expect_success 'diff-cache ignores trailing slash on 
submodule path' '
test_cmp expect actual
 '
 
+test_expect_success 'diff-tree ignores trailing slash on submodule path' '
+   git diff --name-only HEAD^ HEAD submod expect 
+   git diff --name-only HEAD^ HEAD submod/ actual 
+   test_cmp expect actual
+'
+
 test_done
diff --git a/tree-walk.c b/tree-walk.c
index 680afda..c29b6a3 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -543,7 +543,7 @@ static int match_entry(const struct pathspec_item *item,
if (matchlen  pathlen) {
if (match[pathlen] != '/')
return 0;
-   if (!S_ISDIR(entry-mode))
+   if (!S_ISDIR(entry-mode)  !S_ISGITLINK(entry-mode))
return 0;
}
 
-- 
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 v2 7/9] clean: replace match_pathspec() with dir_path_match()

2014-01-24 Thread Nguyễn Thái Ngọc Duy
This instance was left out when many match_pathspec() call sites that
take input from dir_entry were converted to dir_path_match() because
it passed a path with the trailing slash stripped out to match_pathspec()
while the others did not. Stripping for all call sites back then would
be a regression because match_pathspec() did not know how to match
pathspec foo/ against _directory_ foo (the stripped version of path
foo/).

match_pathspec() knows how to do it now. And dir_path_match() strips
the trailing slash also. Use the new function, because the stripping
code is removed in the next patch.

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

diff --git a/builtin/clean.c b/builtin/clean.c
index 4c9680a..5adb52d 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -961,8 +961,7 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
die_errno(Cannot lstat '%s', ent-name);
 
if (pathspec.nr)
-   matches = match_pathspec(pathspec, ent-name,
-len, 0, NULL, 0);
+   matches = dir_path_match(ent, pathspec, 0, NULL);
 
if (S_ISDIR(st.st_mode)) {
if (remove_directories || (matches == MATCHED_EXACTLY)) 
{
-- 
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 v2 4/9] dir.c: prepare match_pathspec_item for taking more flags

2014-01-24 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/dir.c b/dir.c
index 8960ea1..35e09bd 100644
--- a/dir.c
+++ b/dir.c
@@ -195,6 +195,8 @@ int within_depth(const char *name, int namelen,
return 1;
 }
 
+#define DO_MATCH_EXCLUDE   1
+
 /*
  * Does 'match' match the given name?
  * A match is found if
@@ -208,7 +210,7 @@ int within_depth(const char *name, int namelen,
  * It returns 0 when there is no match.
  */
 static int match_pathspec_item(const struct pathspec_item *item, int prefix,
-  const char *name, int namelen)
+  const char *name, int namelen, unsigned flags)
 {
/* name/namelen has prefix cut off by caller */
const char *match = item-match + prefix;
@@ -285,9 +287,9 @@ static int match_pathspec_item(const struct pathspec_item 
*item, int prefix,
 static int do_match_pathspec(const struct pathspec *ps,
 const char *name, int namelen,
 int prefix, char *seen,
-int exclude)
+unsigned flags)
 {
-   int i, retval = 0;
+   int i, retval = 0, exclude = flags  DO_MATCH_EXCLUDE;
 
GUARD_PATHSPEC(ps,
   PATHSPEC_FROMTOP |
@@ -327,7 +329,8 @@ static int do_match_pathspec(const struct pathspec *ps,
 */
if (seen  ps-items[i].magic  PATHSPEC_EXCLUDE)
seen[i] = MATCHED_FNMATCH;
-   how = match_pathspec_item(ps-items+i, prefix, name, namelen);
+   how = match_pathspec_item(ps-items+i, prefix, name,
+ namelen, flags);
if (ps-recursive 
(ps-magic  PATHSPEC_MAXDEPTH) 
ps-max_depth != -1 
@@ -355,10 +358,14 @@ int match_pathspec(const struct pathspec *ps,
   int prefix, char *seen)
 {
int positive, negative;
-   positive = do_match_pathspec(ps, name, namelen, prefix, seen, 0);
+   unsigned flags = 0;
+   positive = do_match_pathspec(ps, name, namelen,
+prefix, seen, flags);
if (!(ps-magic  PATHSPEC_EXCLUDE) || !positive)
return positive;
-   negative = do_match_pathspec(ps, name, namelen, prefix, seen, 1);
+   negative = do_match_pathspec(ps, name, namelen,
+prefix, seen,
+flags | DO_MATCH_EXCLUDE);
return negative ? 0 : positive;
 }
 
-- 
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 v2 1/9] Convert some match_pathspec_depth() to ce_path_match()

2014-01-24 Thread Nguyễn Thái Ngọc Duy
This helps reduce the number of match_pathspec_depth() call sites and
show how match_pathspec_depth() is used.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c | 3 +--
 builtin/commit.c   | 2 +-
 builtin/grep.c | 2 +-
 builtin/rm.c   | 2 +-
 builtin/update-index.c | 3 ++-
 cache.h| 2 --
 diff-lib.c | 5 +++--
 dir.h  | 7 +++
 pathspec.c | 2 +-
 preload-index.c| 3 ++-
 read-cache.c   | 8 +---
 resolve-undo.c | 2 +-
 revision.c | 3 ++-
 wt-status.c| 2 +-
 14 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5df3837..ada51fa 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -297,8 +297,7 @@ static int checkout_paths(const struct checkout_opts *opts,
 * match_pathspec() for _all_ entries when
 * opts-source_tree != NULL.
 */
-   if (match_pathspec_depth(opts-pathspec, ce-name, 
ce_namelen(ce),
-  0, ps_matched))
+   if (ce_path_match(ce, opts-pathspec, ps_matched))
ce-ce_flags |= CE_MATCHED;
}
 
diff --git a/builtin/commit.c b/builtin/commit.c
index 3767478..26b2986 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -234,7 +234,7 @@ static int list_paths(struct string_list *list, const char 
*with_tree,
 
if (ce-ce_flags  CE_UPDATE)
continue;
-   if (!match_pathspec_depth(pattern, ce-name, ce_namelen(ce), 0, 
m))
+   if (!ce_path_match(ce, pattern, m))
continue;
item = string_list_insert(list, ce-name);
if (ce_skip_worktree(ce))
diff --git a/builtin/grep.c b/builtin/grep.c
index 63f8603..3d924c2 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -379,7 +379,7 @@ static int grep_cache(struct grep_opt *opt, const struct 
pathspec *pathspec, int
const struct cache_entry *ce = active_cache[nr];
if (!S_ISREG(ce-ce_mode))
continue;
-   if (!match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), 
0, NULL))
+   if (!ce_path_match(ce, pathspec, NULL))
continue;
/*
 * If CE_VALID is on, we assume worktree file and its cache 
entry
diff --git a/builtin/rm.c b/builtin/rm.c
index 3a0e0ea..0564218 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -308,7 +308,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 
for (i = 0; i  active_nr; i++) {
const struct cache_entry *ce = active_cache[i];
-   if (!match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), 
0, seen))
+   if (!ce_path_match(ce, pathspec, seen))
continue;
ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
list.entry[list.nr].name = ce-name;
diff --git a/builtin/update-index.c b/builtin/update-index.c
index e3a10d7..aaa6f78 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -12,6 +12,7 @@
 #include resolve-undo.h
 #include parse-options.h
 #include pathspec.h
+#include dir.h
 
 /*
  * Default to not allowing changes to the list of files. The
@@ -564,7 +565,7 @@ static int do_reupdate(int ac, const char **av,
struct cache_entry *old = NULL;
int save_nr;
 
-   if (ce_stage(ce) || !ce_path_match(ce, pathspec))
+   if (ce_stage(ce) || !ce_path_match(ce, pathspec, NULL))
continue;
if (has_head)
old = read_one_ent(NULL, head_sha1,
diff --git a/cache.h b/cache.h
index 83a2726..3c558f8 100644
--- a/cache.h
+++ b/cache.h
@@ -500,8 +500,6 @@ extern void *read_blob_data_from_index(struct index_state 
*, const char *, unsig
 extern int ie_match_stat(const struct index_state *, const struct cache_entry 
*, struct stat *, unsigned int);
 extern int ie_modified(const struct index_state *, const struct cache_entry *, 
struct stat *, unsigned int);
 
-extern int ce_path_match(const struct cache_entry *ce, const struct pathspec 
*pathspec);
-
 #define HASH_WRITE_OBJECT 1
 #define HASH_FORMAT_CHECK 2
 extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum 
object_type type, const char *path, unsigned flags);
diff --git a/diff-lib.c b/diff-lib.c
index 346cac6..2eddc66 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -11,6 +11,7 @@
 #include unpack-trees.h
 #include refs.h
 #include submodule.h
+#include dir.h
 
 /*
  * diff-files
@@ -108,7 +109,7 @@ int run_diff_files(struct rev_info *revs, unsigned int 
option)
if (diff_can_quit_early(revs-diffopt))
break;
 
-   if (!ce_path_match(ce, revs-prune_data))
+   if (!ce_path_match(ce, 

[PATCH v2 2/9] Convert some match_pathspec_depth() to dir_path_match()

2014-01-24 Thread Nguyễn Thái Ngọc Duy
This helps reduce the number of match_pathspec_depth() call sites and
show how m_p_d() is used. And it usage is:

 - match against an index entry (ce_path_match or match_pathspec_depth
   in ls-files)

 - match against a dir_entry from read_directory (dir_path_match and
   match_pathspec_depth in clean.c, which will be converted later)

 - resolve-undo (rerere.c and ls-files.c)

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c  | 3 +--
 builtin/grep.c | 4 +---
 builtin/ls-files.c | 2 +-
 dir.h  | 7 +++
 wt-status.c| 4 ++--
 5 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 2a2722f..672adc0 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -208,8 +208,7 @@ static char *prune_directory(struct dir_struct *dir, struct 
pathspec *pathspec,
i = dir-nr;
while (--i = 0) {
struct dir_entry *entry = *src++;
-   if (match_pathspec_depth(pathspec, entry-name, entry-len,
-prefix, seen))
+   if (dir_path_match(entry, pathspec, prefix, seen))
*dst++ = entry;
else if (flag  WARN_IMPLICIT_DOT)
/*
diff --git a/builtin/grep.c b/builtin/grep.c
index 3d924c2..69ac2d8 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -524,9 +524,7 @@ static int grep_directory(struct grep_opt *opt, const 
struct pathspec *pathspec,
 
fill_directory(dir, pathspec);
for (i = 0; i  dir.nr; i++) {
-   const char *name = dir.entries[i]-name;
-   int namelen = strlen(name);
-   if (!match_pathspec_depth(pathspec, name, namelen, 0, NULL))
+   if (!dir_path_match(dir.entries[i], pathspec, 0, NULL))
continue;
hit |= grep_file(opt, dir.entries[i]-name);
if (hit  opt-status_only)
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index e1cf6d8..e238608 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -64,7 +64,7 @@ static void show_dir_entry(const char *tag, struct dir_entry 
*ent)
if (len = ent-len)
die(git ls-files: internal error - directory entry not 
superset of prefix);
 
-   if (!match_pathspec_depth(pathspec, ent-name, ent-len, len, 
ps_matched))
+   if (!dir_path_match(ent, pathspec, len, ps_matched))
return;
 
fputs(tag, stdout);
diff --git a/dir.h b/dir.h
index 42793e5..65f54b6 100644
--- a/dir.h
+++ b/dir.h
@@ -212,4 +212,11 @@ static inline int ce_path_match(const struct cache_entry 
*ce,
return match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), 0, 
seen);
 }
 
+static inline int dir_path_match(const struct dir_entry *ent,
+const struct pathspec *pathspec,
+int prefix, char *seen)
+{
+   return match_pathspec_depth(pathspec, ent-name, ent-len, prefix, 
seen);
+}
+
 #endif
diff --git a/wt-status.c b/wt-status.c
index 295c09e..a452407 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -552,7 +552,7 @@ static void wt_status_collect_untracked(struct wt_status *s)
for (i = 0; i  dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
if (cache_name_is_other(ent-name, ent-len) 
-   match_pathspec_depth(s-pathspec, ent-name, ent-len, 0, 
NULL))
+   dir_path_match(ent, s-pathspec, 0, NULL))
string_list_insert(s-untracked, ent-name);
free(ent);
}
@@ -560,7 +560,7 @@ static void wt_status_collect_untracked(struct wt_status *s)
for (i = 0; i  dir.ignored_nr; i++) {
struct dir_entry *ent = dir.ignored[i];
if (cache_name_is_other(ent-name, ent-len) 
-   match_pathspec_depth(s-pathspec, ent-name, ent-len, 0, 
NULL))
+   dir_path_match(ent, s-pathspec, 0, NULL))
string_list_insert(s-ignored, ent-name);
free(ent);
}
-- 
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 v2 3/9] Rename match_pathspec_depth() to match_pathspec()

2014-01-24 Thread Nguyễn Thái Ngọc Duy
A long time ago, for some reason I was not happy with
match_pathspec(). I created a better version, match_pathspec_depth()
that was suppose to replace match_pathspec()
eventually. match_pathspec() has finally been gone since 6 months
ago. Use the shorter name for match_pathspec_depth().

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/clean.c   |  4 ++--
 builtin/ls-files.c|  6 --
 builtin/ls-tree.c |  2 +-
 dir.c | 20 ++--
 dir.h | 10 +-
 rerere.c  |  4 ++--
 t/t6131-pathspec-icase.sh |  6 +++---
 7 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index 2f26297..f59c753 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -961,8 +961,8 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
die_errno(Cannot lstat '%s', ent-name);
 
if (pathspec.nr)
-   matches = match_pathspec_depth(pathspec, ent-name,
-  len, 0, NULL);
+   matches = match_pathspec(pathspec, ent-name,
+len, 0, NULL);
 
if (S_ISDIR(st.st_mode)) {
if (remove_directories || (matches == MATCHED_EXACTLY)) 
{
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index e238608..02db0e1 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -139,7 +139,8 @@ static void show_ce_entry(const char *tag, const struct 
cache_entry *ce)
if (len = ce_namelen(ce))
die(git ls-files: internal error - cache entry not superset of 
prefix);
 
-   if (!match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), len, 
ps_matched))
+   if (!match_pathspec(pathspec, ce-name, ce_namelen(ce),
+   len, ps_matched))
return;
 
if (tag  *tag  show_valid_bit 
@@ -195,7 +196,8 @@ static void show_ru_info(void)
len = strlen(path);
if (len  max_prefix_len)
continue; /* outside of the prefix */
-   if (!match_pathspec_depth(pathspec, path, len, max_prefix_len, 
ps_matched))
+   if (!match_pathspec(pathspec, path, len,
+   max_prefix_len, ps_matched))
continue; /* uninterested */
for (i = 0; i  3; i++) {
if (!ui-mode[i])
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 65ec931..51184df 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -171,7 +171,7 @@ int cmd_ls_tree(int argc, const char **argv, const char 
*prefix)
 * show_recursive() rolls its own matching code and is
 * generally ignorant of 'struct pathspec'. The magic mask
 * cannot be lifted until it is converted to use
-* match_pathspec_depth() or tree_entry_interesting()
+* match_pathspec() or tree_entry_interesting()
 */
parse_pathspec(pathspec, PATHSPEC_GLOB | PATHSPEC_ICASE,
   PATHSPEC_PREFER_CWD,
diff --git a/dir.c b/dir.c
index d10a63f..8960ea1 100644
--- a/dir.c
+++ b/dir.c
@@ -218,7 +218,7 @@ static int match_pathspec_item(const struct pathspec_item 
*item, int prefix,
 * The normal call pattern is:
 * 1. prefix = common_prefix_len(ps);
 * 2. prune something, or fill_directory
-* 3. match_pathspec_depth()
+* 3. match_pathspec()
 *
 * 'prefix' at #1 may be shorter than the command's prefix and
 * it's ok for #2 to match extra files. Those extras will be
@@ -282,10 +282,10 @@ static int match_pathspec_item(const struct pathspec_item 
*item, int prefix,
  * pathspec did not match any names, which could indicate that the
  * user mistyped the nth pathspec.
  */
-static int match_pathspec_depth_1(const struct pathspec *ps,
- const char *name, int namelen,
- int prefix, char *seen,
- int exclude)
+static int do_match_pathspec(const struct pathspec *ps,
+const char *name, int namelen,
+int prefix, char *seen,
+int exclude)
 {
int i, retval = 0;
 
@@ -350,15 +350,15 @@ static int match_pathspec_depth_1(const struct pathspec 
*ps,
return retval;
 }
 
-int match_pathspec_depth(const struct pathspec *ps,
-const char *name, int namelen,
-int prefix, char *seen)
+int match_pathspec(const struct pathspec *ps,
+  const char *name, int namelen,
+  int prefix, char *seen)
 {
int positive, negative;
-   positive = match_pathspec_depth_1(ps, name, namelen, prefix, seen, 0);
+   positive = do_match_pathspec(ps, name, namelen, prefix, seen, 

[PATCH v2 5/9] match_pathspec: match pathspec foo/ against directory foo

2014-01-24 Thread Nguyễn Thái Ngọc Duy
Currently we do support matching pathspec foo/ against directory
foo. That is because match_pathspec() has no way to tell foo is a
directory and matching foo/ against _file_ foo is wrong.

The callers can now tell match_pathspec if foo is a directory, we
could make an exception for this case. Code is not executed though
because no callers pass the flag yet.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/dir.c b/dir.c
index 35e09bd..7b50072 100644
--- a/dir.c
+++ b/dir.c
@@ -196,6 +196,7 @@ int within_depth(const char *name, int namelen,
 }
 
 #define DO_MATCH_EXCLUDE   1
+#define DO_MATCH_DIRECTORY 2
 
 /*
  * Does 'match' match the given name?
@@ -259,7 +260,11 @@ static int match_pathspec_item(const struct pathspec_item 
*item, int prefix,
 
if (match[matchlen-1] == '/' || name[matchlen] == '/')
return MATCHED_RECURSIVELY;
-   }
+   } else if ((flags  DO_MATCH_DIRECTORY) 
+  match[matchlen - 1] == '/' 
+  namelen == matchlen - 1 
+  !ps_strncmp(item, match, name, namelen))
+   return MATCHED_EXACTLY;
 
if (item-nowildcard_len  item-len 
!git_fnmatch(item, match, name,
-- 
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 1/3] t3030-merge-recursive: Test known breakage with empty work tree

2014-01-24 Thread Brad King
Add test cases that use 'merge-recursive' plumbing with a temporary
index and empty work tree.  Populate the index using 'read-tree' and
'update-index --ignore-missing --refresh' to prepare for merge without
actually checking all files out to disk.  Verify that each merge
produces its expected tree while displaying no error diagnostics.

This approach can be used to compute tree merges while checking out only
conflicting files to disk (which is useful for server-side scripts).
Prior to commit 5b448b85 (merge-recursive: When we detect we can skip an
update, actually skip it, 2011-08-11) this worked cleanly in all cases.
Since that commit, merge-recursive displays a diagnostic such as

 error: addinfo_cache failed for path 'e'

when our side has a rename (to 'e').  The diagnostic does not
influence the return code and the merge appears to succeed, but it
causes this test case to fail.

Signed-off-by: Brad King brad.k...@kitware.com
---
 t/t3030-merge-recursive.sh | 47 ++
 1 file changed, 47 insertions(+)

diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
index 2f96100..b6d3ed0 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -257,6 +257,7 @@ test_expect_success 'setup 8' '
git add e 
test_tick 
git commit -m rename a-e 
+   c7=$(git rev-parse --verify HEAD) 
git checkout rename-ln 
git mv a e 
test_ln_s_add e a 
@@ -517,6 +518,52 @@ test_expect_success 'reset and bind merge' '
 
 '
 
+test_expect_failure 'merge-recursive w/ empty work tree - ours has rename' '
+   (
+GIT_WORK_TREE=$PWD/ours-has-rename-work 
+export GIT_WORK_TREE 
+GIT_INDEX_FILE=$PWD/ours-has-rename-index 
+export GIT_INDEX_FILE 
+mkdir $GIT_WORK_TREE 
+git read-tree -i -m $c7 
+git update-index --ignore-missing --refresh 
+git merge-recursive $c0 -- $c7 $c3 
+git ls-files -s actual-files
+   ) 2actual-err 
+   expected-err 
+   cat expected-files -EOF 
+   100644 $o3 0b/c
+   100644 $o0 0c
+   100644 $o0 0d/e
+   100644 $o0 0e
+   EOF
+   test_cmp expected-files actual-files 
+   test_cmp expected-err actual-err
+'
+
+test_expect_success 'merge-recursive w/ empty work tree - theirs has rename' '
+   (
+GIT_WORK_TREE=$PWD/theirs-has-rename-work 
+export GIT_WORK_TREE 
+GIT_INDEX_FILE=$PWD/theirs-has-rename-index 
+export GIT_INDEX_FILE 
+mkdir $GIT_WORK_TREE 
+git read-tree -i -m $c3 
+git update-index --ignore-missing --refresh 
+git merge-recursive $c0 -- $c3 $c7 
+git ls-files -s actual-files
+   ) 2actual-err 
+   expected-err 
+   cat expected-files -EOF 
+   100644 $o3 0b/c
+   100644 $o0 0c
+   100644 $o0 0d/e
+   100644 $o0 0e
+   EOF
+   test_cmp expected-files actual-files 
+   test_cmp expected-err actual-err
+'
+
 test_expect_success 'merge removes empty directories' '
 
git reset --hard master 
-- 
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


[PATCH/RFC 0/3] merge-recursive: Avoid diagnostic on empty work tree

2014-01-24 Thread Brad King
On 01/23/2014 07:24 PM, Elijah Newren wrote:
 Two options are just doing a stat to determine whether the file
 is present (which means we'll be stat'ing the file multiple times
 in these cases, which feels wasteful), or perhaps writing a
 modified make_cache_entry() with the behavior we want
 (seems like ugly code duplication).  Suggestions?

Perhaps we can thread enough information through the make_cache_entry
signature to allow the caller to know when lstat reported ENOENT.
Here is a series that takes such an approach.

* Patch 1 is the original test case from $gmane/240853.

* Patch 2 extends the make_cache_entry signature to return lstat errno.

* Patch 3 uses this information to silence the add_cacheinfo diagnostic

-Brad

Brad King (3):
  t3030-merge-recursive: Test known breakage with empty work tree
  read-cache.c: Thread lstat error through make_cache_entry signature
  merge-recursive: Tolerate missing file when HEAD is up to date

 builtin/apply.c|  2 +-
 builtin/checkout.c |  2 +-
 builtin/reset.c|  2 +-
 cache.h|  2 +-
 merge-recursive.c  | 22 ++
 read-cache.c   | 12 +++-
 resolve-undo.c |  2 +-
 t/t3030-merge-recursive.sh | 47 ++
 8 files changed, 73 insertions(+), 18 deletions(-)

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


[PATCH/RFC 3/3] merge-recursive: Tolerate missing file when HEAD is up to date

2014-01-24 Thread Brad King
Teach add_cacheinfo to optionally tolerate make_cache_entry failure when
the reason is ENOENT from lstat.  Tell it to do so in the call path when
the entry from HEAD is known to be up to date.

This fixes the 'merge-recursive w/ empty work tree - ours has rename'
case in t3030-merge-recursive.

Signed-off-by: Brad King brad.k...@kitware.com
---
 merge-recursive.c  | 21 +
 t/t3030-merge-recursive.sh |  2 +-
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/merge-recursive.c b/merge-recursive.c
index 4394c44..6a2b962 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -198,13 +198,18 @@ static void output_commit_title(struct merge_options *o, 
struct commit *commit)
 }
 
 static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
-   const char *path, int stage, int refresh, int options)
+const char *path, int stage, int refresh,
+int options, int noent_okay)
 {
struct cache_entry *ce;
+   int cache_errno = 0;
ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path,
- stage, refresh, NULL);
-   if (!ce)
+ stage, refresh, cache_errno);
+   if (!ce) {
+   if(cache_errno == ENOENT  noent_okay)
+   return 0;
return error(_(addinfo_cache failed for path '%s'), path);
+   }
return add_cache_entry(ce, options);
 }
 
@@ -552,13 +557,13 @@ static int update_stages(const char *path, const struct 
diff_filespec *o,
if (remove_file_from_cache(path))
return -1;
if (o)
-   if (add_cacheinfo(o-mode, o-sha1, path, 1, 0, options))
+   if (add_cacheinfo(o-mode, o-sha1, path, 1, 0, options, 0))
return -1;
if (a)
-   if (add_cacheinfo(a-mode, a-sha1, path, 2, 0, options))
+   if (add_cacheinfo(a-mode, a-sha1, path, 2, 0, options, 0))
return -1;
if (b)
-   if (add_cacheinfo(b-mode, b-sha1, path, 3, 0, options))
+   if (add_cacheinfo(b-mode, b-sha1, path, 3, 0, options, 0))
return -1;
return 0;
 }
@@ -789,7 +794,7 @@ static void update_file_flags(struct merge_options *o,
}
  update_index:
if (update_cache)
-   add_cacheinfo(mode, sha, path, 0, update_wd, 
ADD_CACHE_OK_TO_ADD);
+   add_cacheinfo(mode, sha, path, 0, update_wd, 
ADD_CACHE_OK_TO_ADD, 0);
 }
 
 static void update_file(struct merge_options *o,
@@ -1624,7 +1629,7 @@ static int merge_content(struct merge_options *o,
path_renamed_outside_HEAD = !path2 || !strcmp(path, path2);
if (!path_renamed_outside_HEAD) {
add_cacheinfo(mfi.mode, mfi.sha, path,
- 0, (!o-call_depth), 0);
+ 0, (!o-call_depth), 0, 1);
return mfi.clean;
}
} else
diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
index b6d3ed0..c8ba895 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -518,7 +518,7 @@ test_expect_success 'reset and bind merge' '
 
 '
 
-test_expect_failure 'merge-recursive w/ empty work tree - ours has rename' '
+test_expect_success 'merge-recursive w/ empty work tree - ours has rename' '
(
 GIT_WORK_TREE=$PWD/ours-has-rename-work 
 export GIT_WORK_TREE 
-- 
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


[PATCH/RFC 2/3] read-cache.c: Thread lstat error through make_cache_entry signature

2014-01-24 Thread Brad King
Add an 'int *err' argument to make_cache_entry to receive any error
that occurred when matching stat information for a file on disk.
Thread it through to the same argument of refresh_cache_ent.
This will allow callers of make_cache_entry to determine whether
failure was due to a missing file on disk.

Signed-off-by: Brad King brad.k...@kitware.com
---
 builtin/apply.c|  2 +-
 builtin/checkout.c |  2 +-
 builtin/reset.c|  2 +-
 cache.h|  2 +-
 merge-recursive.c  |  3 ++-
 read-cache.c   | 12 +++-
 resolve-undo.c |  2 +-
 7 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/builtin/apply.c b/builtin/apply.c
index b0d0986..15e14ce 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -3675,7 +3675,7 @@ static void build_fake_ancestor(struct patch *list, const 
char *filename)
die(sha1 information is lacking or useless 
(%s)., name);
 
-   ce = make_cache_entry(patch-old_mode, sha1, name, 0, 0);
+   ce = make_cache_entry(patch-old_mode, sha1, name, 0, 0, NULL);
if (!ce)
die(_(make_cache_entry failed for path '%s'), name);
if (add_index_entry(result, ce, ADD_CACHE_OK_TO_ADD))
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5df3837..c7338bb 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -208,7 +208,7 @@ static int checkout_merged(int pos, struct checkout *state)
if (write_sha1_file(result_buf.ptr, result_buf.size,
blob_type, sha1))
die(_(Unable to add merge result for '%s'), path);
-   ce = make_cache_entry(mode, sha1, path, 2, 0);
+   ce = make_cache_entry(mode, sha1, path, 2, 0, NULL);
if (!ce)
die(_(make_cache_entry failed for path '%s'), path);
status = checkout_entry(ce, state, NULL);
diff --git a/builtin/reset.c b/builtin/reset.c
index 6004803..8e0375d 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -122,7 +122,7 @@ static void update_index_from_diff(struct diff_queue_struct 
*q,
if (one-mode  !is_null_sha1(one-sha1)) {
struct cache_entry *ce;
ce = make_cache_entry(one-mode, one-sha1, one-path,
-   0, 0);
+ 0, 0, NULL);
if (!ce)
die(_(make_cache_entry failed for path '%s'),
one-path);
diff --git a/cache.h b/cache.h
index c9efe88..8e4f17d 100644
--- a/cache.h
+++ b/cache.h
@@ -487,7 +487,7 @@ extern int remove_file_from_index(struct index_state *, 
const char *path);
 #define ADD_CACHE_IMPLICIT_DOT 32  /* internal to git add -u/-A */
 extern int add_to_index(struct index_state *, const char *path, struct stat *, 
int flags);
 extern int add_file_to_index(struct index_state *, const char *path, int 
flags);
-extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned 
char *sha1, const char *path, int stage, int refresh);
+extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned 
char *sha1, const char *path, int stage, int refresh, int *err);
 extern int ce_same_name(const struct cache_entry *a, const struct cache_entry 
*b);
 extern int index_name_is_other(const struct index_state *, const char *, int);
 extern void *read_blob_data_from_index(struct index_state *, const char *, 
unsigned long *);
diff --git a/merge-recursive.c b/merge-recursive.c
index a18bd15..4394c44 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -201,7 +201,8 @@ static int add_cacheinfo(unsigned int mode, const unsigned 
char *sha1,
const char *path, int stage, int refresh, int options)
 {
struct cache_entry *ce;
-   ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, 
refresh);
+   ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path,
+ stage, refresh, NULL);
if (!ce)
return error(_(addinfo_cache failed for path '%s'), path);
return add_cache_entry(ce, options);
diff --git a/read-cache.c b/read-cache.c
index 33dd676..8f16cee 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -15,7 +15,8 @@
 #include strbuf.h
 #include varint.h
 
-static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int 
really);
+static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
+  int really, int* err);
 
 /* Mask for the name length in ce_flags in the on-disk index */
 
@@ -696,7 +697,7 @@ int add_file_to_index(struct index_state *istate, const 
char *path, int flags)
 
 struct cache_entry *make_cache_entry(unsigned int mode,
const unsigned char *sha1, const char *path, int stage,
-   int refresh)
+   int refresh, int* err)
 {
int size, len;
struct 

RE: Globbing for ignored branches?

2014-01-24 Thread Jim Garrison
 -Original Message-
 Behalf Of Markus Trippelsdorf
 Sent: Friday, January 24, 2014 1:01 AM
 Subject: Globbing for ignored branches?
 
 I would like to ignore branches that match a certain pattern, e.g.:
[snip]
 
 Is it possible to ignore all branches that match hjl?
 

If you mean ignore them when you do git branch -a, then

git branch -a |grep -v hjl

If you mean ignore in some other scenario you need to be more specific about 
what you want.

--
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/RFC 1/3] t3030-merge-recursive: Test known breakage with empty work tree

2014-01-24 Thread Jonathan Nieder
Hi,

Brad King wrote:

 Add test cases that use 'merge-recursive' plumbing with a temporary
 index and empty work tree.  Populate the index using 'read-tree' and
 'update-index --ignore-missing --refresh' to prepare for merge without
 actually checking all files out to disk.  Verify that each merge
 produces its expected tree while displaying no error diagnostics.

Following my usual review practice of lazy reading for the sake of
readers in the future who might be in a hurry, it's not clear what
problem these tests are solving or trying to detect.  Could you start
with a quick summary of the symptoms and when it came up?

The commit message doesn't need to paraphrase the actual code, since
anyone curious about the details can always look at the code.  It's
more important to explain the motivation and intended effect so people
can understand what went wrong if something ends up being broken by a
later patch.

 This approach can be used to compute tree merges while checking out only
 conflicting files to disk (which is useful for server-side scripts).
 Prior to commit 5b448b85 (merge-recursive: When we detect we can skip an
 update, actually skip it, 2011-08-11) this worked cleanly in all cases.

Do you mean something like the following?

Sometimes when working with a large repository it can be useful to
try out a merge and only check out conflicting files to disk (for
example as a speed optimization on a server).  Until v1.7.7-rc1~28^2~20
(merge-recursive: When we detect we can skip an update, actually
skip it, 2011-08-11), it was possible to do so with the following
idiom:

... summary of commands here ...

Nowadays, that still works and the exit status is the same,
but merge-recursive produces a diagnostic if our side renamed
a file:

error: addinfo_cache failed for path 'dst'

Add a test to document this regression.

[...]
 +++ b/t/t3030-merge-recursive.sh
[...]
 @@ -517,6 +518,52 @@ test_expect_success 'reset and bind merge' '
  
  '
  
 +test_expect_failure 'merge-recursive w/ empty work tree - ours has rename' '
 + (
 +  GIT_WORK_TREE=$PWD/ours-has-rename-work 

Elsewhere in the test, commands in a subshell are indented by another
tab, so these new tests should probably follow suit.  As a side
effect, that makes the indentation easier to see.

Hope that helps,
Jonathan
--
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


Mein lieber

2014-01-24 Thread Murphy Jocelyn
Hallo,
Mein Name ist Miss Jocelyn. entschied ich mich zu schreiben, weil ich wurde für 
dich interessiert und ich werde wie uns Freunde sein. ich werde gerne mehr über 
Sie wissen sehr gut, weil ich glaube, dass es schöne Menschen gibt, die die 
Werte der Freundschaft zu schätzen wissen. Alter spielt keine Rolle, denn was 
zählt, ist Liebe und Fürsorge. ich werde geehrt, um Ihre Antwort zu sehen. 
Hoffnung, von Ihnen bald zu hören
Jocelyn
--
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: Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
On 2014.01.24 at 18:07 +0100, Markus Trippelsdorf wrote:
 On 2014.01.24 at 16:37 +, Jim Garrison wrote:
   -Original Message-
   Behalf Of Markus Trippelsdorf
   Sent: Friday, January 24, 2014 1:01 AM
   Subject: Globbing for ignored branches?
   
   I would like to ignore branches that match a certain pattern, e.g.:
  [snip]
   
   Is it possible to ignore all branches that match hjl?
   
  
  If you mean ignore them when you do git branch -a, then
  
  git branch -a |grep -v hjl
  
  If you mean ignore in some other scenario you need to be more
  specific about what you want.
 
 I want to them when I run git pull.
   ignore
-- 
Markus
--
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: Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
On 2014.01.24 at 16:37 +, Jim Garrison wrote:
  -Original Message-
  Behalf Of Markus Trippelsdorf
  Sent: Friday, January 24, 2014 1:01 AM
  Subject: Globbing for ignored branches?
  
  I would like to ignore branches that match a certain pattern, e.g.:
 [snip]
  
  Is it possible to ignore all branches that match hjl?
  
 
 If you mean ignore them when you do git branch -a, then
 
 git branch -a |grep -v hjl
 
 If you mean ignore in some other scenario you need to be more
 specific about what you want.

I want to them when I run git pull.

-- 
Markus
--
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/RFC 1/3] t3030-merge-recursive: Test known breakage with empty work tree

2014-01-24 Thread Brad King
On 01/24/2014 11:51 AM, Jonathan Nieder wrote:
 a quick summary of the symptoms and when it came up?

You're suggested commit message correctly explains it:

 Do you mean something like the following?
 
   Sometimes when working with a large repository it can be useful to
   try out a merge and only check out conflicting files to disk (for
   example as a speed optimization on a server).  Until v1.7.7-rc1~28^2~20
   (merge-recursive: When we detect we can skip an update, actually
   skip it, 2011-08-11), it was possible to do so with the following
   idiom:
 
   ... summary of commands here ...
 
   Nowadays, that still works and the exit status is the same,
   but merge-recursive produces a diagnostic if our side renamed
   a file:
 
   error: addinfo_cache failed for path 'dst'
 
   Add a test to document this regression.

Yes, thanks.

 Elsewhere in the test, commands in a subshell are indented by another
 tab, so these new tests should probably follow suit.

Great.  I'll fold both of the above into the next revision of the series.

Thanks,
-Brad

--
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: Globbing for ignored branches?

2014-01-24 Thread Jeff King
On Fri, Jan 24, 2014 at 06:09:09PM +0100, Markus Trippelsdorf wrote:

   If you mean ignore in some other scenario you need to be more
   specific about what you want.
  
  I want to them when I run git pull.
ignore

I assume you mean that you do not want to fetch them at all, not that
you want to avoid merging them. The set of branches that git fetches is
configured by the fetch refspec in your config file. It usually looks
like this:

  $ git config remote.origin.fetch
  +refs/heads/*:refs/remotes/origin/*

But you can specify a specific list of branches you want to fetch
instead:

  $ git config --unset remote.origin.fetch
  $ for i in master other-branch; do
  git config --add remote.origin.fetch \
   +refs/heads/$i:refs/remotes/origin/$i
done

However, you do have to specify each branch individually. You probably
want to say all branches except X, and you cannot currently specify
a negative refspec like that.

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


Re: Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
On 2014.01.24 at 13:23 -0500, Jeff King wrote:
 On Fri, Jan 24, 2014 at 06:09:09PM +0100, Markus Trippelsdorf wrote:
 
If you mean ignore in some other scenario you need to be more
specific about what you want.
   
   I want to them when I run git pull.
 ignore
 
 I assume you mean that you do not want to fetch them at all, not that
 you want to avoid merging them. The set of branches that git fetches is
 configured by the fetch refspec in your config file. It usually looks
 like this:
 
   $ git config remote.origin.fetch
   +refs/heads/*:refs/remotes/origin/*
 
 But you can specify a specific list of branches you want to fetch
 instead:
 
   $ git config --unset remote.origin.fetch
   $ for i in master other-branch; do
   git config --add remote.origin.fetch \
+refs/heads/$i:refs/remotes/origin/$i
 done
 
 However, you do have to specify each branch individually. You probably
 want to say all branches except X, and you cannot currently specify
 a negative refspec like that.

Thanks.
Yes, that was the question I wanted to ask (, sorry for not formulating
it more clearly). 
Is this negative refspec for branches a feature that is planned for
the future?

-- 
Markus
--
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: Globbing for ignored branches?

2014-01-24 Thread Jeff King
On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:

  However, you do have to specify each branch individually. You probably
  want to say all branches except X, and you cannot currently specify
  a negative refspec like that.
 
 Yes, that was the question I wanted to ask (, sorry for not formulating
 it more clearly). 
 Is this negative refspec for branches a feature that is planned for
 the future?

It is something that has been talked about before, but I do not think
anybody is actively working on. It would probably not be too hard a
feature if you are interested in getting your feet wet in git
development. :)

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


Re: [PATCH v2 0/9] About the trailing slashes

2014-01-24 Thread Junio C Hamano
Nguyễn Thái Ngọc Duy  pclo...@gmail.com writes:

 While looking at this, I found a funny behavior of fill_directory.

   $ git init
   $ mkdir b
   $ b/c
   $ b/d
   $ git status b
   Untracked files:
   b/
   $ git status b/
   Untracked files:
   b/c b/d

 Notice how the trailing slash produces different untracked listing.
 This is because of common_prefix_len(). In the b case,
 common_prefix_len() returns empty prefix, so read_directory reads top
 directory, traverses through, reaches b and eventually calls
 treat_directory() on it, which results in b/ in the output.

 In the b/ case, common_prefix_len() found the prefix b, so
 read_directory() starts at b instead of b's parent.
 treat_directory() is never called on b itself, which results in
 b/c and b/d.

Hmm, this feels like a borderline case.

If the user asked git status ?, or even git status '?', it seems
to me that the user wanted to get git status output but with a
scope limited to top-level entries with a single letter.  And the
unlimited output asks to consolidate output for directories that
have nothing interesting.  git status b and git status '[b]' are
asking similar thing, but not just limiting the scope to any one
letter but to 'b'.  So the output you showed above looks correct to
me.  On the other hand, the other request git status b/ seems to
me that the user is very aware that 'b' is a directory and wants to
look inside, so again the output you showed looks correct to me.

How does git status '[b]/' behave?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Fwd: [PATCH/RFC 3/3] merge-recursive: Tolerate missing file when HEAD is up to date

2014-01-24 Thread newren
[The copy of my message to the list bounced; trying to resend...]

Hi,

Thanks for flagging this problem, providing a clear testcase, and working on it.

On Fri, Jan 24, 2014 at 7:01 AM, Brad King brad.k...@kitware.com wrote:

 Teach add_cacheinfo to optionally tolerate make_cache_entry failure when
 the reason is ENOENT from lstat.  Tell it to do so in the call path when
 the entry from HEAD is known to be up to date.

 This fixes the 'merge-recursive w/ empty work tree - ours has rename'
 case in t3030-merge-recursive.

While this change does work for the particular new testcase you
provided, there's a more complex case where merge-recursive is failing
that is not yet found in the testsuite and not fully reflected with
your new test.  In particular, if you combine your special case of an
empty work tree with other special cases such as renames across a D/F
conflict, then git merge will fail and your change would merely
suppress part of the error messages.

To make this concrete, try modifying the 'merging with triple rename
across D/F conflict'  testcase in t6031-merge-recursive.sh (an example
that should merge cleanly) to remove all files from the working tree
right before the merge (which shoudln't affect whether the merge is
clean).  Currently, git merge will fail with:

error: addinfo_cache failed for path 'sub1/file3'
error: addinfo_cache failed for path 'sub1/file2'
error: addinfo_cache failed for path 'sub1/file1'
sub1/file1: unmerged (ac3e272b72bbf89def8657766b855d0656630ed4)
sub1/file2: unmerged (637f0347d31dad180d6fc7f6720c187b05a8754c)
sub1/file3: unmerged (27d10cc8d0f10540c1fce1aa6de5e8f3e6b655ba)
fatal: git write-tree failed to write a tree

Your patch would remove the first 3 error messages, but leave the
deeper problem.

 diff --git a/merge-recursive.c b/merge-recursive.c
 index 4394c44..6a2b962 100644
 --- a/merge-recursive.c
 +++ b/merge-recursive.c
 @@ -198,13 +198,18 @@ static void output_commit_title(struct merge_options 
 *o, struct commit *commit)
  }

  static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
 -   const char *path, int stage, int refresh, int options)
 +const char *path, int stage, int refresh,
 +int options, int noent_okay)
  {
 struct cache_entry *ce;
 +   int cache_errno = 0;
 ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path,
 - stage, refresh, NULL);
 -   if (!ce)
 + stage, refresh, cache_errno);
 +   if (!ce) {
 +   if(cache_errno == ENOENT  noent_okay)
 +   return 0;
 return error(_(addinfo_cache failed for path '%s'), path);
 +   }
 return add_cache_entry(ce, options);
  }


This is the crux of the change and the one you referred to in the
commit message.  However, we don't really want add_cacheinfo to
tolerate failure to create a cache entry; we need one.  We just want
add_cacheinfo to be tolerant of failure to refresh the stat-timestamp
for the new cache entry if there is no associated file on disk.  Said
another way, we need a new cache entry back from make_cache_entry() in
all cases, it's just that we want the stat information refreshed if
and only if the file happens to exist in the working tree.  (We could
just stat the file in the working tree, but that seems a waste since
make_cache_entry() will stat it again when it exists.  In fact, the
stat in make_cache_entry() is also a bit of a waste because this is
the case when we know that before the merge started the file already
had the right contents and thus we ought to be able to get the right
timestamp for that particular file from the cache entry of the index
from before the merge even began.  But I don't know how to access
that.)

Elijah
--
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/RFC 3/3] merge-recursive: Tolerate missing file when HEAD is up to date

2014-01-24 Thread Junio C Hamano
Brad King brad.k...@kitware.com writes:

 Teach add_cacheinfo to optionally tolerate make_cache_entry failure when
 the reason is ENOENT from lstat.  Tell it to do so in the call path when
 the entry from HEAD is known to be up to date.

It somehow feels wrong to force callers of make_cache_entry() to be
so intimate with the implementation details of refresh_cache_ent()
by having them inspect the errno from lstat(2) so deep in the
callchain, and to force callers of make_cache_entry() that says
refresh=NoThanks to pass a useless NULL.

Looking at refresh_cache_ent(), I notice that we already have cases
where we do not bother to lstat and instead say Yeah, the cache
entry you have is good, and have to wonder if this new feature
should be modeled after them instead, namely, by introducing a new
option bit CE_MATCH_MISSING_OK that asks it to treat a path that is
missing from the working tree as if it is checked out unmodified.

--
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/RFC 3/3] merge-recursive: Tolerate missing file when HEAD is up to date

2014-01-24 Thread Brad King
On 01/24/2014 01:42 PM, Elijah Newren wrote:
 While this change does work for the particular new testcase you provided,
 there's a more complex case where merge-recursive is failing

I'm not surprised.  The change felt much like covering a symptom.

 it's just that we want the stat information refreshed if and only
 if the file happens to exist in the working tree.

We can add a refresh_flags argument to make_cache_entry to request
this behavior.  I'll send an updated series soon.

Thanks,
-Brad

--
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: Globbing for ignored branches?

2014-01-24 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:

  However, you do have to specify each branch individually. You probably
  want to say all branches except X, and you cannot currently specify
  a negative refspec like that.
 
 Yes, that was the question I wanted to ask (, sorry for not formulating
 it more clearly). 
 Is this negative refspec for branches a feature that is planned for
 the future?

 It is something that has been talked about before, but I do not think
 anybody is actively working on. It would probably not be too hard a
 feature if you are interested in getting your feet wet in git
 development. :)

The end result might be not so hard in the mechanical sense, but
designing the interface would be hard.  I do not offhand think of a
good way to do this.
--
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/RFC 3/3] merge-recursive: Tolerate missing file when HEAD is up to date

2014-01-24 Thread Brad King
On Fri, Jan 24, 2014 at 2:50 PM, Junio C Hamano gits...@pobox.com wrote:
 It somehow feels wrong to force callers of make_cache_entry() to be
 so intimate with the implementation details of refresh_cache_ent()
[snip]
 option bit CE_MATCH_MISSING_OK that asks it to treat a path that is
 missing from the working tree as if it is checked out unmodified.

I came to the same conclusion after reading Elijah's last response.
My next series revision adds an argument to make_cache_entry to
specify the refresh flags and honors REFRESH_IGNORE_MISSING.

Thanks,
-Brad
--
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 0/9] add --gpg-sign to rebase and pull

2014-01-24 Thread Junio C Hamano
Nicolas Vigier bo...@mars-attacks.org writes:

 On Fri, 24 Jan 2014, brian m. carlson wrote:

 This series was posted to the list some time back, but it fell through
 the cracks.  This is a re-send of Nicolas Vigier's work with an
 additional patch that adds --gpg-sign to pull as well.  I added my
 sign-off to his patches because SubmittingPatches (section (c)) seems to
 imply that I should, although I can rebase it out if it's a problem.

 Thanks!

 An improvement I was thinking to do on this series but had not time to
 do yet is to make the '--no-gpg-sign' option disable gpg signing when
 the commit.gpgsign config option is set to true.

By the way, a configuration variable that has no way of getting
overriden per invocation should not exist without a very good reason
(core.bare is an example of a exception with a good reason---the
bareness of the repository does not change per command invocation).
An escape hatch --no-gpg-sign is a must-have requirement, not a
nice-to-have improvement.

Thanks for not forgetting.



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


[PATCH v2 3/3] merge-recursive.c: Tolerate missing files while refreshing index

2014-01-24 Thread Brad King
Teach add_cacheinfo to tell make_cache_entry to skip refreshing stat
information when a file is missing from the work tree.  We do not want
the index to be stat-dirty after the merge but also do not want to fail
when a file happens to be missing.

This fixes the 'merge-recursive w/ empty work tree - ours has rename'
case in t3030-merge-recursive.

Suggested-by: Elijah Newren new...@gmail.com
Signed-off-by: Brad King brad.k...@kitware.com
---
 merge-recursive.c  | 3 ++-
 t/t3030-merge-recursive.sh | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/merge-recursive.c b/merge-recursive.c
index a6fe7f9..35935c5 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -201,7 +201,8 @@ static int add_cacheinfo(unsigned int mode, const unsigned 
char *sha1,
const char *path, int stage, int refresh, int options)
 {
struct cache_entry *ce;
-   ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, 
refresh, 0);
+   ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage,
+ refresh, REFRESH_IGNORE_MISSING);
if (!ce)
return error(_(addinfo_cache failed for path '%s'), path);
return add_cache_entry(ce, options);
diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
index 3db3bf6..82e1854 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -518,7 +518,7 @@ test_expect_success 'reset and bind merge' '
 
 '
 
-test_expect_failure 'merge-recursive w/ empty work tree - ours has rename' '
+test_expect_success 'merge-recursive w/ empty work tree - ours has rename' '
(
GIT_WORK_TREE=$PWD/ours-has-rename-work 
export GIT_WORK_TREE 
-- 
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


[PATCH v2 2/3] read-cache.c: Optionally tolerate missing files in make_cache_entry

2014-01-24 Thread Brad King
Add an 'int refresh_flags' argument to make_cache_entry to tell the
refresh step about caller preferences.  Teach it to honor the
REFRESH_IGNORE_MISSING flag to skip refreshing stat information when a
file is missing from the work tree on disk.

Signed-off-by: Brad King brad.k...@kitware.com
---
 builtin/apply.c|  2 +-
 builtin/checkout.c |  2 +-
 builtin/reset.c|  2 +-
 cache.h|  2 +-
 merge-recursive.c  |  2 +-
 read-cache.c   | 21 -
 resolve-undo.c |  2 +-
 7 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/builtin/apply.c b/builtin/apply.c
index b0d0986..64c04ec 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -3675,7 +3675,7 @@ static void build_fake_ancestor(struct patch *list, const 
char *filename)
die(sha1 information is lacking or useless 
(%s)., name);
 
-   ce = make_cache_entry(patch-old_mode, sha1, name, 0, 0);
+   ce = make_cache_entry(patch-old_mode, sha1, name, 0, 0, 0);
if (!ce)
die(_(make_cache_entry failed for path '%s'), name);
if (add_index_entry(result, ce, ADD_CACHE_OK_TO_ADD))
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5df3837..d3d8640 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -208,7 +208,7 @@ static int checkout_merged(int pos, struct checkout *state)
if (write_sha1_file(result_buf.ptr, result_buf.size,
blob_type, sha1))
die(_(Unable to add merge result for '%s'), path);
-   ce = make_cache_entry(mode, sha1, path, 2, 0);
+   ce = make_cache_entry(mode, sha1, path, 2, 0, 0);
if (!ce)
die(_(make_cache_entry failed for path '%s'), path);
status = checkout_entry(ce, state, NULL);
diff --git a/builtin/reset.c b/builtin/reset.c
index 6004803..ac45056 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -122,7 +122,7 @@ static void update_index_from_diff(struct diff_queue_struct 
*q,
if (one-mode  !is_null_sha1(one-sha1)) {
struct cache_entry *ce;
ce = make_cache_entry(one-mode, one-sha1, one-path,
-   0, 0);
+ 0, 0, 0);
if (!ce)
die(_(make_cache_entry failed for path '%s'),
one-path);
diff --git a/cache.h b/cache.h
index c9efe88..653ede4 100644
--- a/cache.h
+++ b/cache.h
@@ -487,7 +487,7 @@ extern int remove_file_from_index(struct index_state *, 
const char *path);
 #define ADD_CACHE_IMPLICIT_DOT 32  /* internal to git add -u/-A */
 extern int add_to_index(struct index_state *, const char *path, struct stat *, 
int flags);
 extern int add_file_to_index(struct index_state *, const char *path, int 
flags);
-extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned 
char *sha1, const char *path, int stage, int refresh);
+extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned 
char *sha1, const char *path, int stage, int refresh, int refresh_flags);
 extern int ce_same_name(const struct cache_entry *a, const struct cache_entry 
*b);
 extern int index_name_is_other(const struct index_state *, const char *, int);
 extern void *read_blob_data_from_index(struct index_state *, const char *, 
unsigned long *);
diff --git a/merge-recursive.c b/merge-recursive.c
index a18bd15..a6fe7f9 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -201,7 +201,7 @@ static int add_cacheinfo(unsigned int mode, const unsigned 
char *sha1,
const char *path, int stage, int refresh, int options)
 {
struct cache_entry *ce;
-   ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, 
refresh);
+   ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, 
refresh, 0);
if (!ce)
return error(_(addinfo_cache failed for path '%s'), path);
return add_cache_entry(ce, options);
diff --git a/read-cache.c b/read-cache.c
index 33dd676..9ce7a9f 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -15,7 +15,8 @@
 #include strbuf.h
 #include varint.h
 
-static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int 
really);
+static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int 
really,
+  int flags);
 
 /* Mask for the name length in ce_flags in the on-disk index */
 
@@ -696,7 +697,7 @@ int add_file_to_index(struct index_state *istate, const 
char *path, int flags)
 
 struct cache_entry *make_cache_entry(unsigned int mode,
const unsigned char *sha1, const char *path, int stage,
-   int refresh)
+   int refresh, int refresh_flags)
 {
int size, len;
struct cache_entry *ce;
@@ -717,7 +718,7 @@ struct cache_entry 

[PATCH v2 0/3] merge-recursive: Avoid diagnostic on empty work tree

2014-01-24 Thread Brad King
Hi Folks,

Here is the second revision of this series.  The previous
revision can be found at $gmane/241009.

Updates since the previous revision of the series:

* Patch 1 test indentation and commit message updated thanks to
  comments from Jonathan.

* Patch 2 now adds a different new argument to make_cache_entry.
  This one is to request certain refresh behavior instead of just
  to get an error value back.

* Patch 3 uses the new make_cache_entry feature in patch 2
  to fix the test case.  This approach is based on suggestions
  from Elijah and Junio.

Thanks,
-Brad

Brad King (3):
  t3030-merge-recursive: Test known breakage with empty work tree
  read-cache.c: Optionally tolerate missing files in make_cache_entry
  merge-recursive.c: Tolerate missing files while refreshing index

 builtin/apply.c|  2 +-
 builtin/checkout.c |  2 +-
 builtin/reset.c|  2 +-
 cache.h|  2 +-
 merge-recursive.c  |  3 ++-
 read-cache.c   | 21 -
 resolve-undo.c |  2 +-
 t/t3030-merge-recursive.sh | 47 ++
 8 files changed, 70 insertions(+), 11 deletions(-)

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


[PATCH v2 1/3] t3030-merge-recursive: Test known breakage with empty work tree

2014-01-24 Thread Brad King
Sometimes when working with a large repository it can be useful to try
out a merge and only check out conflicting files to disk (for example as
a speed optimization on a server).  Until v1.7.7-rc1~28^2~20
(merge-recursive: When we detect we can skip an update, actually skip
it, 2011-08-11), it was possible to do so with the following idiom:

# Prepare a temporary index and empty work tree.
GIT_INDEX_FILE=$PWD/tmp-$$-index 
export GIT_INDEX_FILE 
GIT_WORK_TREE=$PWD/tmp-$$-work 
export GIT_WORK_TREE 
mkdir $GIT_WORK_TREE 

# Convince the index that our side is on disk.
git read-tree -i -m $ours 
git update-index --ignore-missing --refresh 

# Merge their side into our side.
bases=$(git merge-base --all $ours $theirs) 
git merge-recursive $bases -- $ours $theirs 
tree=$(git write-tree)

Nowadays, that still works and the exit status is the same, but
merge-recursive produces a diagnostic if our side renamed a file:

error: addinfo_cache failed for path 'dst'

Add a test to document this regression.

Signed-off-by: Brad King brad.k...@kitware.com
---
 t/t3030-merge-recursive.sh | 47 ++
 1 file changed, 47 insertions(+)

diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
index 2f96100..3db3bf6 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -257,6 +257,7 @@ test_expect_success 'setup 8' '
git add e 
test_tick 
git commit -m rename a-e 
+   c7=$(git rev-parse --verify HEAD) 
git checkout rename-ln 
git mv a e 
test_ln_s_add e a 
@@ -517,6 +518,52 @@ test_expect_success 'reset and bind merge' '
 
 '
 
+test_expect_failure 'merge-recursive w/ empty work tree - ours has rename' '
+   (
+   GIT_WORK_TREE=$PWD/ours-has-rename-work 
+   export GIT_WORK_TREE 
+   GIT_INDEX_FILE=$PWD/ours-has-rename-index 
+   export GIT_INDEX_FILE 
+   mkdir $GIT_WORK_TREE 
+   git read-tree -i -m $c7 
+   git update-index --ignore-missing --refresh 
+   git merge-recursive $c0 -- $c7 $c3 
+   git ls-files -s actual-files
+   ) 2actual-err 
+   expected-err 
+   cat expected-files -EOF 
+   100644 $o3 0b/c
+   100644 $o0 0c
+   100644 $o0 0d/e
+   100644 $o0 0e
+   EOF
+   test_cmp expected-files actual-files 
+   test_cmp expected-err actual-err
+'
+
+test_expect_success 'merge-recursive w/ empty work tree - theirs has rename' '
+   (
+   GIT_WORK_TREE=$PWD/theirs-has-rename-work 
+   export GIT_WORK_TREE 
+   GIT_INDEX_FILE=$PWD/theirs-has-rename-index 
+   export GIT_INDEX_FILE 
+   mkdir $GIT_WORK_TREE 
+   git read-tree -i -m $c3 
+   git update-index --ignore-missing --refresh 
+   git merge-recursive $c0 -- $c3 $c7 
+   git ls-files -s actual-files
+   ) 2actual-err 
+   expected-err 
+   cat expected-files -EOF 
+   100644 $o3 0b/c
+   100644 $o0 0c
+   100644 $o0 0d/e
+   100644 $o0 0e
+   EOF
+   test_cmp expected-files actual-files 
+   test_cmp expected-err actual-err
+'
+
 test_expect_success 'merge removes empty directories' '
 
git reset --hard master 
-- 
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: [RFC PATCH 2/1] Make request-pull able to take a refspec of form local:remote

2014-01-24 Thread Junio C Hamano
Linus Torvalds torva...@linux-foundation.org writes:

 So I don't actually think anybody should need to be retrained, or
 always use the local:remote syntax. The local:remote syntax exists
 only for that special insane case where you used (the same)
 local:remote syntax to push out a branch under a different name.

 [ And yeah, maybe that behavior is more common than I think, but even
 if it is, such behavior would always be among people who are *very*
 aware of the whole local branch vs remote branch name is different
 situation. ]

As the new default for git push would push to the same name, I
agree that people who are now forced to use local:remote syntax
would be the ones who know what they are doing [*1*].

So there are two remaining items, I think.

 - After creating a tags/for-linus signed tag and pushing it to
   tags/for-linus, asking request-pull to request that tag to be
   pulled seems to lose the tag message from the output.

 - Docs.


[Footnote]

*1* Not that it is always acceptable to break the existing users as
long as they are clueful ones and they are given an escape hatch.
But this time I know I won't be in the middle of firestorm like
the one we had immediately after 1.6.0, as long as I keep the
URL of the message I am responding to in the list archive ;-)
--
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: Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
On 2014.01.24 at 12:00 -0800, Junio C Hamano wrote:
 Jeff King p...@peff.net writes:
 
  On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:
 
   However, you do have to specify each branch individually. You probably
   want to say all branches except X, and you cannot currently specify
   a negative refspec like that.
  
  Yes, that was the question I wanted to ask (, sorry for not formulating
  it more clearly). 
  Is this negative refspec for branches a feature that is planned for
  the future?
 
  It is something that has been talked about before, but I do not think
  anybody is actively working on. It would probably not be too hard a
  feature if you are interested in getting your feet wet in git
  development. :)
 
 The end result might be not so hard in the mechanical sense, but
 designing the interface would be hard.  I do not offhand think of a
 good way to do this.

I don't know if the in-tree regex engine supports negative lookaheads.
If it does, then something like the following should work (to use my
hjl example):

^(.(?!hjl))*

-- 
Markus
--
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 2/3] read-cache.c: Optionally tolerate missing files in make_cache_entry

2014-01-24 Thread Junio C Hamano
Brad King brad.k...@kitware.com writes:

 +extern struct cache_entry *make_cache_entry(unsigned int mode, const 
 unsigned char *sha1, const char *path, int stage, int refresh, int 
 refresh_flags);

Why a new parameter?  If refresh_flags can be ANY when refresh=NoThanks,
shouldn't they be a single variable that tells the callee how the entry
should be refreshed (e.g. not at all, normally, missing is ok, etc.)?

 +static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int 
 really,
 +int flags)
  {
 - return refresh_cache_ent(the_index, ce, really, NULL, NULL);
 + int not_new = (flags  REFRESH_IGNORE_MISSING) != 0;
 + int cache_errno = 0;
 + struct cache_entry *new;
 +
 + new = refresh_cache_ent(the_index, ce, really, cache_errno, NULL);
 +
 + if(!new  not_new  cache_errno == ENOENT)
 + return ce;

I think this is still one level too high in the abstraction chain.
int really might be of type signed int by historical accidents,
but it is unsigned int options for the underlying
refresh_cache_ent().  I'd suggest renaming this to unsigned int
refresh_options or something, and then define a new constatnt
similar to the existing CE_MATCH_IGNORE_*.
--
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: Globbing for ignored branches?

2014-01-24 Thread Junio C Hamano
Markus Trippelsdorf mar...@trippelsdorf.de writes:

 On 2014.01.24 at 12:00 -0800, Junio C Hamano wrote:
 Jeff King p...@peff.net writes:
 
  On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:
 
   However, you do have to specify each branch individually. You probably
   want to say all branches except X, and you cannot currently specify
   a negative refspec like that.
  
  Yes, that was the question I wanted to ask (, sorry for not formulating
  it more clearly). 
  Is this negative refspec for branches a feature that is planned for
  the future?
 
  It is something that has been talked about before, but I do not think
  anybody is actively working on. It would probably not be too hard a
  feature if you are interested in getting your feet wet in git
  development. :)
 
 The end result might be not so hard in the mechanical sense, but
 designing the interface would be hard.  I do not offhand think of a
 good way to do this.

 I don't know if the in-tree regex engine supports negative lookaheads.
 If it does, then something like the following should work (to use my
 hjl example):

 ^(.(?!hjl))*

refspec wildcards are *NOT* regular expressions.
--
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: Globbing for ignored branches?

2014-01-24 Thread Jeff King
On Fri, Jan 24, 2014 at 12:00:16PM -0800, Junio C Hamano wrote:

 Jeff King p...@peff.net writes:
 
  On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:
 
   However, you do have to specify each branch individually. You probably
   want to say all branches except X, and you cannot currently specify
   a negative refspec like that.
 [...]
 The end result might be not so hard in the mechanical sense, but
 designing the interface would be hard.  I do not offhand think of a
 good way to do this.

I had imagined a not token at the front of the refspec, like:

  git fetch origin +refs/heads/*:refs/remotes/origin/* ^refs/heads/foo

In this case, a colon in the refspec would be an error. An alternative
would be:

  git fetch origin +refs/heads/*:refs/remotes/origin/* refs/heads/foo:

I.e., to say put foo to nowhere. But generally refspecs do not affect
each other. So refs/heads/foo:refs/heads/bar would generally work _in
addition_ to the other refspec. Making the null destination work
differently might be confusing.

I dunno. I have not thought very hard on the topic, so maybe there are
some subtle cases I am missing.

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


Re: Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
On 2014.01.24 at 12:44 -0800, Junio C Hamano wrote:
 Markus Trippelsdorf mar...@trippelsdorf.de writes:
 
  On 2014.01.24 at 12:00 -0800, Junio C Hamano wrote:
  Jeff King p...@peff.net writes:
  
   On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:
  
However, you do have to specify each branch individually. You probably
want to say all branches except X, and you cannot currently specify
a negative refspec like that.
   
   Yes, that was the question I wanted to ask (, sorry for not formulating
   it more clearly). 
   Is this negative refspec for branches a feature that is planned for
   the future?
  
   It is something that has been talked about before, but I do not think
   anybody is actively working on. It would probably not be too hard a
   feature if you are interested in getting your feet wet in git
   development. :)
  
  The end result might be not so hard in the mechanical sense, but
  designing the interface would be hard.  I do not offhand think of a
  good way to do this.
 
  I don't know if the in-tree regex engine supports negative lookaheads.
  If it does, then something like the following should work (to use my
  hjl example):
 
  ^(.(?!hjl))*
 
 refspec wildcards are *NOT* regular expressions.

Yes, but that's the point. If they were, the negative refspec
interface issue would be solved.

-- 
Markus
--
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 1/9] cherry-pick, revert: add the --gpg-sign option

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

 +-S[keyid]::
 +--gpg-sign[=keyid]::
 + GPG-sign commits.
 +

Does this accept --no-gpg-sign?  If not, shouldn't it?

 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);
 + }

Here you would need to invent a new way to propagate --no-gpg-sign
to subsequent invocations, I think.



--
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] repack.c: chmod +w before rename()

2014-01-24 Thread Torsten Bögershausen
commit a1bbc6c0 repack: rewrite the shell script in C introduced
a possible regression, when a Git repo is located on a Windows network share.

When git gc is called on an already packed repository, it could fail like this:
fatal: renaming '.git/objects/pack/.tmp-xyz.pack' failed: Permission denied

Temporary *.pack and *.idx files remain in .git/objects/pack/

In a1bbc6c0 the rename() function replaced the mv -f shell command.

Obviously the -f option can also override a read-only file but
rename() can not on a network share.

Make the C-code to work similar to the shell script, by making the
files writable before calling rename().

Another solution could be to do the chmod +x in mingw_rename().
This may be done in another commit, because
a) It improves git gc only when Git for Windows is used
   on the client machine
b) Windows refuses to delete a file when the file is read-only.
   So setting a file to read-only under Windows is a way for a user
   to protect it from being deleted.
   Changing the behaviour of rename() globally may not be what we want.

Reported-by: Jochen Haag zwanzi...@googlemail.com
Signed-off-by: Torsten Bögershausen tbo...@web.de
---
 builtin/repack.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/builtin/repack.c b/builtin/repack.c
index ba66c6e..033b4c2 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -324,6 +324,10 @@ int cmd_repack(int argc, const char **argv, const char 
*prefix)
statbuffer.st_mode = ~(S_IWUSR | S_IWGRP | 
S_IWOTH);
chmod(fname_old, statbuffer.st_mode);
}
+   if (!stat(fname, statbuffer)) {
+   statbuffer.st_mode |= (S_IWUSR | S_IWGRP | 
S_IWOTH);
+   chmod(fname, statbuffer.st_mode);
+   }
if (rename(fname_old, fname))
die_errno(_(renaming '%s' failed), fname_old);
free(fname);
-- 
1.9.rc0.143.g6fd479e

--
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 1/9] cherry-pick, revert: add the --gpg-sign option

2014-01-24 Thread brian m. carlson
On Fri, Jan 24, 2014 at 01:00:06PM -0800, Junio C Hamano wrote:
 brian m. carlson sand...@crustytoothpaste.net writes:
 
  +-S[keyid]::
  +--gpg-sign[=keyid]::
  +   GPG-sign commits.
  +
 
 Does this accept --no-gpg-sign?  If not, shouldn't it?

It does not.  I took Nicolas's patches from the list and applied them to
master, so nothing from next is there, including the commit.gpgsign
stuff.

Would you prefer I rebased them on next instead?

  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);
  +   }
 
 Here you would need to invent a new way to propagate --no-gpg-sign
 to subsequent invocations, I think.

Probably.  It wouldn't be too terribly difficult.

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only
OpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187


signature.asc
Description: Digital signature


Re: Globbing for ignored branches?

2014-01-24 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 I had imagined a not token at the front of the refspec, like:

   git fetch origin +refs/heads/*:refs/remotes/origin/* ^refs/heads/foo

 In this case, a colon in the refspec would be an error. An alternative
 would be:

   git fetch origin +refs/heads/*:refs/remotes/origin/* refs/heads/foo:

 I.e., to say put foo to nowhere. But generally refspecs do not affect
 each other.

Not really.  You do not have to view it as 'not refs/heads/foo' is
affecting the previous '+refs/heads/*:refs/remotes/origin/*'.

You can think of two refspecs refs/heads/foo refs/heads/bar are
both affecting the end result; so far we only had a single way for
multiple refspecs to affect the end result and that was a union.
Introducing subtract as another mode of combining is not too bad,
I would think, at the conceptual level.

 ... Making the null destination work
 differently might be confusing.

I tend to agree that refs/heads/foo: is being too cute and may be
confusing, at least if it will be the only way to express this in
the end-user-facing UI.  Even some people were confused enough on a
very sensible push nothing to ref means deletion to make us add
another explicit way, push --delete, to ask for the same thing.
--
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 6/9] Pass directory indicator to match_pathspec_item()

2014-01-24 Thread Eric Sunshine
On Fri, Jan 24, 2014 at 8:40 AM, Nguyễn Thái Ngọc Duy pclo...@gmail.com wrote:
 diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
 index af5134b..167af53 100755
 --- a/t/t4010-diff-pathspec.sh
 +++ b/t/t4010-diff-pathspec.sh
 @@ -110,4 +110,21 @@ test_expect_success 'diff-tree -r with wildcard' '
 test_cmp expected result
  '

 +test_expect_success 'setup submodules' '
 +   test_tick 
 +   git init submod 
 +   ( cd submod  test_commit first; ) 

Unnecessary semicolon might confuse the reader into thinking something
unusual is going on here.

 +   git add submod 
 +   git commit -m first 
 +   ( cd submod  test_commit second; ) 

Ditto.

 +   git add submod 
 +   git commit -m second
 +'
 +
 +test_expect_success 'diff-cache ignores trailing slash on submodule path' '
 +   git diff --name-only HEAD^ submod expect 
 +   git diff --name-only HEAD^ submod/ 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


Re: [PATCH 5/5] implement @{publish} shorthand

2014-01-24 Thread Jeff King
On Thu, Jan 23, 2014 at 04:16:06PM -0800, Junio C Hamano wrote:

 Jeff King p...@peff.net writes:
 
  In a triangular workflow, you may have a distinct
  @{upstream} that you pull changes from, but publish by
  default (if you typed git push) to a different remote (or
  a different branch on the remote). It may sometimes be
  useful to be able to quickly refer to that publishing point
  (e.g., to see which changes you have that have not yet been
  published).
 
  This patch introduces the branch@{publish} shorthand (or
  @{pu} to be even shorter). It refers to the tracking
  branch of the remote branch to which you would push if you
  were to push the named branch. That's a mouthful to explain,
  so here's an example:
 
$ git checkout -b foo origin/master
$ git config remote.pushdefault github
$ git push
 
  Signed-off-by: Jeff King p...@peff.net
  ---
 
 As there is no @{pu} in publish_mark() as far as I can see, and also
 I found it is a bit unclear what the example in the last paragraph
 wants to illustrate, I'll reword the above as the following before
 merging it to 'next'.

Yeah, I think the @{pu} was just a silly omission from the code, though
I agree after our discussion that we should just stick with @{publish}
for now.

I am not sure why I said git push at the end. I would have thought
that:

  $ git rev-parse --symbolic-full-name @{publish}
  refs/remotes/github/foo

would have been the right command to demonstrate. The text you suggested
is fine, though I think you can simply drop the git push, as it does
not add anything.

As far as merging it to 'next', I had not really intended it to go that
far. :) It was more for Ram to use as a base. I find some of the
refactoring questionable, including:

  1. The meaning of branch-pushremote is subtly different from that of
 branch-remote. Ram's followup refactoring did a better job of
 that (but he is missing the patches on top to finish out the
 feature).

  2. We are duplicating the where to push logic here. That should
 probably be factored out so that git push and @{publish} use
 the same logic.

And of course there are no tests or documentation. It might work,
though.

I don't mind if you want to merge it and do more work in-tree, but I do
not think it should graduate as-is. And you may want check from Ram that
he is not in the middle of his own version based on the patches he sent
earlier, as reworking them on top of mine would probably just be
needless extra work.

Are you planning on having request-pull use @{publish} as a default? I
saw you cc'd me on that thread, but I didn't have any opinion besides
sounds like you could use it here.

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


Re: [PATCH] repack.c: chmod +w before rename()

2014-01-24 Thread brian m. carlson
On Fri, Jan 24, 2014 at 10:05:14PM +0100, Torsten Bögershausen wrote:
 commit a1bbc6c0 repack: rewrite the shell script in C introduced
 a possible regression, when a Git repo is located on a Windows network share.
 
 When git gc is called on an already packed repository, it could fail like 
 this:
 fatal: renaming '.git/objects/pack/.tmp-xyz.pack' failed: Permission denied
 
 Temporary *.pack and *.idx files remain in .git/objects/pack/
 
 In a1bbc6c0 the rename() function replaced the mv -f shell command.
 
 Obviously the -f option can also override a read-only file but
 rename() can not on a network share.
 
 Make the C-code to work similar to the shell script, by making the
 files writable before calling rename().
 
 Another solution could be to do the chmod +x in mingw_rename().
 This may be done in another commit, because
 a) It improves git gc only when Git for Windows is used
on the client machine
 b) Windows refuses to delete a file when the file is read-only.
So setting a file to read-only under Windows is a way for a user
to protect it from being deleted.
Changing the behaviour of rename() globally may not be what we want.
 
 Reported-by: Jochen Haag zwanzi...@googlemail.com
 Signed-off-by: Torsten Bögershausen tbo...@web.de
 ---
  builtin/repack.c | 4 
  1 file changed, 4 insertions(+)
 
 diff --git a/builtin/repack.c b/builtin/repack.c
 index ba66c6e..033b4c2 100644
 --- a/builtin/repack.c
 +++ b/builtin/repack.c
 @@ -324,6 +324,10 @@ int cmd_repack(int argc, const char **argv, const char 
 *prefix)
   statbuffer.st_mode = ~(S_IWUSR | S_IWGRP | 
 S_IWOTH);
   chmod(fname_old, statbuffer.st_mode);
   }
 + if (!stat(fname, statbuffer)) {
 + statbuffer.st_mode |= (S_IWUSR | S_IWGRP | 
 S_IWOTH);
 + chmod(fname, statbuffer.st_mode);
 + }

Are we sure that the file in question can never be a symlink?  Because
if it is, we'll end up changing the permissions on the wrong file.  In
general, I'm wary of changing permissions on a file to suit Windows's
rename because of the symlink issue and the security issues that can
result.  Hard links probably have the same issue.

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only
OpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187


signature.asc
Description: Digital signature


Re: [PATCH 5/5] implement @{publish} shorthand

2014-01-24 Thread Ramkumar Ramachandra
Jeff King wrote:
 As far as merging it to 'next', I had not really intended it to go that
 far. :) It was more for Ram to use as a base.

Sorry about not having posted a follow-up yet; I'm adjusting to a new
timezone and environment.

 I find some of the
 refactoring questionable, including:

   1. The meaning of branch-pushremote is subtly different from that of
  branch-remote. Ram's followup refactoring did a better job of
  that (but he is missing the patches on top to finish out the
  feature).

   2. We are duplicating the where to push logic here. That should
  probably be factored out so that git push and @{publish} use
  the same logic.

 And of course there are no tests or documentation. It might work,
 though.

Actually, task (2) is somewhat involved: I still haven't figured out
how to share code with 'git push'.

 I don't mind if you want to merge it and do more work in-tree, but I do
 not think it should graduate as-is. And you may want check from Ram that
 he is not in the middle of his own version based on the patches he sent
 earlier, as reworking them on top of mine would probably just be
 needless extra work.

On that note, can you hold off graduating
jk/branch-at-publish-rebased, Junio? Hopefully, I'll come up with a
replacement over the weekend.

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


Re: [PATCH] repack.c: chmod +w before rename()

2014-01-24 Thread Johannes Schindelin
Hi Brian,

On Fri, 24 Jan 2014, brian m. carlson wrote:

 On Fri, Jan 24, 2014 at 10:05:14PM +0100, Torsten Bögershausen wrote:
  diff --git a/builtin/repack.c b/builtin/repack.c
  index ba66c6e..033b4c2 100644
  --- a/builtin/repack.c
  +++ b/builtin/repack.c
  @@ -324,6 +324,10 @@ int cmd_repack(int argc, const char **argv, const char 
  *prefix)
  statbuffer.st_mode = ~(S_IWUSR | S_IWGRP | 
  S_IWOTH);
  chmod(fname_old, statbuffer.st_mode);
  }
  +   if (!stat(fname, statbuffer)) {
  +   statbuffer.st_mode |= (S_IWUSR | S_IWGRP | 
  S_IWOTH);
  +   chmod(fname, statbuffer.st_mode);
  +   }
 
 Are we sure that the file in question can never be a symlink?

On Windows: yes. Otherwise, no.

Having said that, the files in question are files generated by Git, so you
really would have to tamper with things in order to get into trouble.

 Because if it is, we'll end up changing the permissions on the wrong
 file.

In any case, I'd rather change the permissions only when the rename
failed. *And* I feel uncomfortable ignoring the return value...

 In general, I'm wary of changing permissions on a file to suit Windows's
 rename because of the symlink issue and the security issues that can
 result.

I agree on the Windows issue.

 Hard links probably have the same issue.

No, hard links have their own permissions. If you change the permissions
on a hardlink, any other hardlinks to the same content are unaffected.

Ciao,
Johannes

Re: [PATCH] l10n: de.po: translate 27 new messages

2014-01-24 Thread Jiang Xin
2014/1/24 Ralf Thielow ralf.thie...@gmail.com:
 Translate 27 new messages came from git.pot update in
 df49095 (l10n: git.pot: v1.9 round 1 (27 new, 11 removed).

 Signed-off-by: Ralf Thielow ralf.thie...@gmail.com
 ---
  po/de.po | 90 
 
  1 file changed, 45 insertions(+), 45 deletions(-)

  #: wt-status.c:275
 -#, fuzzy
  msgid new file
 -msgstr neue Datei:   %s
 +msgstr neue Datei:

  #: wt-status.c:277
  msgid copied
 -msgstr 
 +msgstr kopiert

  #: wt-status.c:279
 -#, fuzzy
  msgid deleted
  msgstr gelöscht

  #: wt-status.c:285
 -#, fuzzy
  msgid typechange
 -msgstr Typänderung: %s
 +msgstr Typänderung:

  #: wt-status.c:287
 -#, fuzzy
  msgid unknown
 -msgstr unbekannt:%s
 +msgstr unbekannt:

  #: wt-status.c:289
 -#, fuzzy
  msgid unmerged
 -msgstr zusammenführen
 +msgstr nicht zusammengeführt


Inconsistent ending colons, some have and some not.


-- 
Jiang Xin
--
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 1/9] cherry-pick, revert: add the --gpg-sign option

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

 On Fri, Jan 24, 2014 at 01:00:06PM -0800, Junio C Hamano wrote:
 brian m. carlson sand...@crustytoothpaste.net writes:
 
  +-S[keyid]::
  +--gpg-sign[=keyid]::
  +  GPG-sign commits.
  +
 
 Does this accept --no-gpg-sign?  If not, shouldn't it?

 It does not.  I took Nicolas's patches from the list and applied them to
 master, so nothing from next is there, including the commit.gpgsign
 stuff.

 Would you prefer I rebased them on next instead?

Not really.

It is debatable if it should mean that the user wants to sign
commits that are created by running other commands like am and
stash when he sets commit.gpgsign to true, but even if the answer
to that question were true, the configuration must be overridable
with e.g. git stash --no-gpg-sign, explicitly from the command
line.  Until that happens, the series with 2af2ef3c (Add the
commit.gpgsign option to sign all commits, 2013-11-05) cannot be
merged to 'master'.

A series that lets you specify positives from the command line
without any sticky configuration variable, i.e. these patches, do
not have to wait for that to happen.  So this series should come
first and then the commit.gpgsign ones can be rebased on top of
this series, I would think.

--
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] repack.c: chmod +w before rename()

2014-01-24 Thread brian m. carlson
On Fri, Jan 24, 2014 at 11:24:36PM +0100, Johannes Schindelin wrote:
  In general, I'm wary of changing permissions on a file to suit Windows's
  rename because of the symlink issue and the security issues that can
  result.
 
 I agree on the Windows issue.

I personally feel that if Windows needs help to change permissions for a
rename, that code should only ever be used on Windows.  Doesn't
mingw_rename automatically do this anyway, and if it doesn't, shouldn't
we put the code there instead?  Furthermore, it makes me very nervous to
make the file 666.  Isn't 644 enough?

  Hard links probably have the same issue.
 
 No, hard links have their own permissions. If you change the permissions
 on a hardlink, any other hardlinks to the same content are unaffected.

Not according to link(2):

  This new name may be used exactly as the old one for any operation;
  both names refer to the same file (and so have the same permissions
  and ownership) and it is impossible to tell which name was the
  original.

My testing confirms this.

More importantly, while one might not want to symlink a pack frequently,
git clone -l does use hard links.  This means that if a local clone is
made somewhere, and then the original repository is repacked and hits
this case, the clone is now vulnerable to tampering by a malicious user
(assuming that user can read the appropriate directory).  So unless I'm
reading this wrong, this patch would cause security problems on all Unix
systems.

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only
OpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187


signature.asc
Description: Digital signature


Re: [PATCH 5/5] implement @{publish} shorthand

2014-01-24 Thread Junio C Hamano
Ramkumar Ramachandra artag...@gmail.com writes:

 On that note, can you hold off graduating
 jk/branch-at-publish-rebased, Junio? Hopefully, I'll come up with a
 replacement over the weekend.

Sure.

This close to the feature freeze, I'd rather see all contributors,
not limited to you, not rush on new and shiny things, but instead
spend time looking at bugs and fixes proposed for the upcoming
release in the codepaths they were involved.

The send-email SSL issue $gmane/240479 is one of the things I'd like
to see your sanity-checking ;-)
--
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] repack.c: chmod +w before rename()

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

 Another solution could be to do the chmod +x in mingw_rename().
 This may be done in another commit, because
 a) It improves git gc only when Git for Windows is used
on the client machine
 b) Windows refuses to delete a file when the file is read-only.
So setting a file to read-only under Windows is a way for a user
to protect it from being deleted.
Changing the behaviour of rename() globally may not be what we want.

But doesn't this affect non Windows platforms in negative ways?  We
unconditionally run stat(2) and chmod(2) unnecessarily, and we leave
the resulting file writable when it originally may have been marked
read-only on purpose.

Also, it feels to me that doing this in mingw_rename() the right
approach in the first place.  If the user wants git mv a b to
rename a in the working tree and if that path is read-only, what
happens, and what should happen?  Does chmod -w on a file in the
working tree mean I want to make sure nobody accidentally writes to
it, and also I want to protect it from being renamed or deleted?

So perhaps mingw_rename() can be taught to

 - First try to just do rename(), and if it succeeds, happily return
   without doing anything extra.

 - If it fails, then

   - check if the failure is due to read-only-ness (optional: if you
 cannot reliably tell this from the error code, do not bother),
 and if not, return failure.

   - otherwise, stat() to grab the current permission bits, do the
 chmod(), retry the rename, then restore the permission bits
 with another chmod().  Return failure if any of these steps
 fail.

That way, it can cover any call to rename(), be it for packfiles or
a path in the working tree, and you would need to pay the overhead
of stat/chmod only when it matters, no?

 Reported-by: Jochen Haag zwanzi...@googlemail.com
 Signed-off-by: Torsten Bögershausen tbo...@web.de
 ---
  builtin/repack.c | 4 
  1 file changed, 4 insertions(+)

 diff --git a/builtin/repack.c b/builtin/repack.c
 index ba66c6e..033b4c2 100644
 --- a/builtin/repack.c
 +++ b/builtin/repack.c
 @@ -324,6 +324,10 @@ int cmd_repack(int argc, const char **argv, const char 
 *prefix)
   statbuffer.st_mode = ~(S_IWUSR | S_IWGRP | 
 S_IWOTH);
   chmod(fname_old, statbuffer.st_mode);
   }
 + if (!stat(fname, statbuffer)) {
 + statbuffer.st_mode |= (S_IWUSR | S_IWGRP | 
 S_IWOTH);
 + chmod(fname, statbuffer.st_mode);
 + }
   if (rename(fname_old, fname))
   die_errno(_(renaming '%s' failed), fname_old);
   free(fname);
 -- 
 1.9.rc0.143.g6fd479e

 -- 
--
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] repack.c: chmod +w before rename()

2014-01-24 Thread Junio C Hamano
Johannes Schindelin johannes.schinde...@gmx.de writes:

 In any case, I'd rather change the permissions only when the rename
 failed. *And* I feel uncomfortable ignoring the return value...

Good judgement I'd agree with 100%.

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: [ANNOUNCE] Git v1.9-rc0

2014-01-24 Thread Jeff King
On Thu, Jan 23, 2014 at 10:15:33AM -0800, Junio C Hamano wrote:

 Jeff King p...@peff.net writes:
 
  Junio, since you prepare such tarballs[1] anyway for kernel.org, it
  might be worth uploading them to the Releases page of git/git.  I
  imagine there is a programmatic way to do so via GitHub's API, but I
  don't know offhand. I can look into it if you are interested.
 
 I already have a script that takes the three tarballs and uploads
 them to two places, so adding GitHub as the third destination should
 be a natural and welcome way to automate it.

I came up with the script below, which you can use like:

  ./script v1.8.2.3 git-1.8.2.3.tar.gz

It expects the tag to already be pushed up to GitHub.  I'll leave
sticking it on the todo branch and integrating it into RelUpload to
you. This can also be used to backfill the old releases (though I looked
on k.org and it seems to have only partial coverage).

It sets the prerelease flag for -rc releases, but I did not otherwise
fill in any fields, including the summary and description. GitHub seems
to display reasonably if they are not set.

-- 8 --
#!/bin/sh
#
# usage: $0 tag tarball

repo=git/git

# replace this with however you store your oauth token
# if you don't have one, make one here:
# https://github.com/settings/tokens/new
token() {
  pass -n github.web.oauth
}

post() {
  curl -H Authorization: token $(token) $@
}

# usage: create tag-name
create() {
  case $1 in
  *-rc*)
prerelease=true
;;
  *)
prerelease=false
;;
  esac

  post -d '
  {
tag_name: '$1',
prerelease: '$prerelease'
  }' https://api.github.com/repos/$repo/releases;
}

# use: upload release-id filename
upload() {
  url=https://uploads.github.com/repos/$repo/releases/$1/assets; 
  url=$url?name=$(basename $2) 
  post -H Content-Type: $(file -b --mime-type $2) \
   --data-binary @$2 \
   $url
}

# This is a hack. If you don't mind a dependency on
# perl's JSON (or another parser), we can do a lot better.
extract_id() {
  perl -lne '/id:\s*(\d+)/ or next; print $1; exit 0'
}

create $1 release.json 
id=$(extract_id release.json) 
upload $id $2 /dev/null 
rm -f release.json
--
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] repack.c: chmod +w before rename()

2014-01-24 Thread Mike Hommey
On Fri, Jan 24, 2014 at 10:49:13PM +, brian m. carlson wrote:
 On Fri, Jan 24, 2014 at 11:24:36PM +0100, Johannes Schindelin wrote:
   In general, I'm wary of changing permissions on a file to suit Windows's
   rename because of the symlink issue and the security issues that can
   result.
  
  I agree on the Windows issue.
 
 I personally feel that if Windows needs help to change permissions for a
 rename, that code should only ever be used on Windows.  Doesn't
 mingw_rename automatically do this anyway, and if it doesn't, shouldn't
 we put the code there instead?  Furthermore, it makes me very nervous to
 make the file 666.  Isn't 644 enough?

Arguably, umask is supposed to take care of making things right. OTOH,
since it's the destination file that's the problem not the renamed file,
the equivalent to mv -f would be to unlink() that file first, not to change
its permissions. That would work properly on unix too.

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


Re: [PATCH v2 0/9] About the trailing slashes

2014-01-24 Thread Duy Nguyen
On Sat, Jan 25, 2014 at 2:22 AM, Junio C Hamano gits...@pobox.com wrote:
 How does git status '[b]/' behave?

It outputs b/ (like git status b). I think that's because
common_prefix_len() stops looking at the first wildcard char, '['. So
common prefix is empty, just like b.
-- 
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: Globbing for ignored branches?

2014-01-24 Thread Jeff King
On Fri, Jan 24, 2014 at 01:08:42PM -0800, Junio C Hamano wrote:

 Not really.  You do not have to view it as 'not refs/heads/foo' is
 affecting the previous '+refs/heads/*:refs/remotes/origin/*'.
 
 You can think of two refspecs refs/heads/foo refs/heads/bar are
 both affecting the end result; so far we only had a single way for
 multiple refspecs to affect the end result and that was a union.
 Introducing subtract as another mode of combining is not too bad,
 I would think, at the conceptual level.

OK, I buy that line of reasoning. I assume that ordering should not
matter (that is, we would apply all positive refspecs, and then subtract
all negative refspecs).

I took a quick look at the refspec code, and how bad it would be to
implement this feature. It's rather a bit of a mess. It looks like there
are three separate code paths to apply refspecs:

  - fetch uses get_ref_map, which calls get_fetch_map for each refspec;
each refspec than expands into 0, 1, or multiple refs (if it's a
pattern). You can mention a ref multiple times on the LHS of a
refspec, and it may be fetched multiple times. After we have the
whole list, we detect duplicate destinations, and either drop the
duplicates (if all sources are the same) or complain (if there are
different sources).

  - push uses match_push_refs, which calls get_ref_match for each ref
(not refspec). So the loop is inside-out from fetch, and it looks
like we do weird things with multiple matches. We seem to handle
multiple explicit matches like:

  $ git push --dry-run tmp master:foo master:bar
  To tmp
   * [new branch]  master - foo
   * [new branch]  master - bar

but we don't seem to do the same for pattern matches:

  $ git push --dry-run tmp refs/heads/*:refs/foo/* \
   refs/heads/*:refs/bar/*
  To tmp
   * [new branch]  master - refs/foo/master

we just take the first match, even though the two did not conflict.
I doubt this comes up that much, but I do not see any reason this
should not be doing the same as fetch: apply all refspecs to come up
with a complete list, then cull duplicates.

  - @{upstream} uses apply_refspecs to convert a single name. This is
also used by transport-helper's fetch_with_import and
push_with_import. Which makes me think they do not handle
overlapping refspecs at all, unlike the builtin counterparts.

There is also query_refspecs, which underlies apply_refspecs. I'm
not even sure I understand all of the uses there.

The patch below implements negative refspecs for fetch, but does nothing
for push and apply_refspecs (in fact, it probably makes them worse,
because they've learned to parse negative refspecs, but not handle them
properly).

The helpers in the patch could probably be used to build support for the
other code paths, but it really seems like there could stand to be some
refactoring. I'm not sure if I have the time/stomach for it at the
moment. But I'll post this here anyway in case somebody else is
interested.

 I tend to agree that refs/heads/foo: is being too cute and may be
 confusing, at least if it will be the only way to express this in
 the end-user-facing UI.  Even some people were confused enough on a
 very sensible push nothing to ref means deletion to make us add
 another explicit way, push --delete, to ask for the same thing.

Agreed. I went with ^refs/heads/master in the patch below, but I am
open to other suggestions.

---
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 025bc3e..47f25e9 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -363,6 +363,8 @@ static struct ref *get_ref_map(struct transport *transport,
tail = rm-next;
}
 
+   ref_map = apply_negative_refspecs(ref_map, refspecs, refspec_count);
+
return ref_remove_duplicates(ref_map);
 }
 
diff --git a/remote.c b/remote.c
index a89efab..b7b20de 100644
--- a/remote.c
+++ b/remote.c
@@ -16,6 +16,7 @@ static struct refspec s_tag_refspec = {
1,
0,
0,
+   0,
refs/tags/*,
refs/tags/*
 };
@@ -533,8 +534,14 @@ static struct refspec *parse_refspec_internal(int 
nr_refspec, const char **refsp
rs[i].force = 1;
lhs++;
}
+   else if (*lhs == '^') {
+   rs[i].negative = 1;
+   lhs++;
+   }
 
rhs = strrchr(lhs, ':');
+   if (rs[i].negative  rhs)
+   goto invalid;
 
/*
 * Before going on, special case : (or +:) as a refspec
@@ -1663,6 +1670,9 @@ int get_fetch_map(const struct ref *remote_refs,
 {
struct ref *ref_map, **rmp;
 
+   if (refspec-negative)
+   return 0;
+
if (refspec-pattern) {
ref_map = get_expanded_map(remote_refs, refspec);
} else {
@@ -1705,6 +1715,48 @@ int 

'git diff' command doesn't honor utf8 symbol boundaries, and doesn't use actual terminal width

2014-01-24 Thread Yuri

The fragment of 'git diff' output looks like this:
- translationОшибка: адрес %1 содержит запрещенные символы. 
Пожалуйста, перепро�
+ translationОшибка: адрес %1 содержит запрещённые символы. 
Пожалуйста, перепро�


Two issues here:
1. Cyrilic text in utf8 got truncated not at utf8 boundary, causing this 
garbage symbol in the end
2. Truncation is done at somewhat ~70% of the actual screen width. git 
could go all the way to the whole screen with, but it didn't. Shrinking 
terminal width causes the output truncation limit to shrink in the same 
proportion. So some bad decision about truncation size is made somewhere 
in 'git diff' command.


Suggested behavior:
1. git should respect utf8, and in case of truncation it should add … 
symbol.
2. truncation algorithm should read current terminal width and truncate 
at width-1 length to allow for the above-mentioned symbol


Yuri
--
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 with git-diff --quiet

2014-01-24 Thread Duy Nguyen
On Thu, Jan 23, 2014 at 11:45:25AM +0900, IWAMOTO Toshihiro wrote:
 I found git-diff --quiet returns a zero exit status even if there's
 a change.  The following sequence reproduces the bug:
 
   $ mkdir foo
   $ cd foo
   $ git init
   $ echo a  a.txt
   $ echo b b.txt
   $ git add ?.txt
   $ git commit
   $ echo b  b.txt
   $ touch a.txt
   $ git diff --quiet; echo $?
   
 Interestingly, if you issue git-diff --quiet again, it returns the
 expected exit status 1.

Because stat info in index is updated and diff_change() won't be
called again on a.txt.

 The problem is in the optimization code in run_diff_files().  The
 function finds a.txt has different stat(2) data from .git/index and
 calls diff_change(), which sets DIFF_OPT_HAS_CHANGES.  As the flag
 makes diff_can_quit_early() return 1, run_diff_files()'s loop finishes
 without calling diff_change() for b.txt.
 
 Then, diffcore_std() examines diff_queued_diff and clears
 DIFF_OPT_HAS_CHANGES, because a.txt is unchanged.
 This is how a change in b.txt is ignored by git-diff --quiet.

Thanks for the analysis. Perhaps we could make diff_change test
whether a.txt is unchanged so it does not set HAS_CHANGES prematurely?
Maybe something like below.

By the time diffcore_skip_stat_unmatch() is called, everything is
cached, so there's not much of performance regression. We still do
memcmp() twice (in diff_filespec_is_identical), but I think that has
less impact than removing diff_can_quit_early().

-- 8 --
diff --git a/diff.c b/diff.c
index 6b4cd0e..5226fc0 100644
--- a/diff.c
+++ b/diff.c
@@ -4697,6 +4697,33 @@ static int diff_filespec_is_identical(struct 
diff_filespec *one,
return !memcmp(one-data, two-data, one-size);
 }
 
+static int diff_filespec_check_stat_unmatch(struct diff_filepair *p)
+{
+   /*
+* 1. Entries that come from stat info dirtiness
+*always have both sides (iow, not create/delete),
+*one side of the object name is unknown, with
+*the same mode and size.  Keep the ones that
+*do not match these criteria.  They have real
+*differences.
+*
+* 2. At this point, the file is known to be modified,
+*with the same mode and size, and the object
+*name of one side is unknown.  Need to inspect
+*the identical contents.
+*/
+   if (!DIFF_FILE_VALID(p-one) || /* (1) */
+   !DIFF_FILE_VALID(p-two) ||
+   (p-one-sha1_valid  p-two-sha1_valid) ||
+   (p-one-mode != p-two-mode) ||
+   diff_populate_filespec(p-one, 1) ||
+   diff_populate_filespec(p-two, 1) ||
+   (p-one-size != p-two-size) ||
+   !diff_filespec_is_identical(p-one, p-two)) /* (2) */
+   return 1;
+   return 0;
+}
+
 static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
 {
int i;
@@ -4707,27 +4734,7 @@ static void diffcore_skip_stat_unmatch(struct 
diff_options *diffopt)
for (i = 0; i  q-nr; i++) {
struct diff_filepair *p = q-queue[i];
 
-   /*
-* 1. Entries that come from stat info dirtiness
-*always have both sides (iow, not create/delete),
-*one side of the object name is unknown, with
-*the same mode and size.  Keep the ones that
-*do not match these criteria.  They have real
-*differences.
-*
-* 2. At this point, the file is known to be modified,
-*with the same mode and size, and the object
-*name of one side is unknown.  Need to inspect
-*the identical contents.
-*/
-   if (!DIFF_FILE_VALID(p-one) || /* (1) */
-   !DIFF_FILE_VALID(p-two) ||
-   (p-one-sha1_valid  p-two-sha1_valid) ||
-   (p-one-mode != p-two-mode) ||
-   diff_populate_filespec(p-one, 1) ||
-   diff_populate_filespec(p-two, 1) ||
-   (p-one-size != p-two-size) ||
-   !diff_filespec_is_identical(p-one, p-two)) /* (2) */
+   if (diff_filespec_check_stat_unmatch(p))
diff_q(outq, p);
else {
/*
@@ -4890,6 +4897,7 @@ void diff_change(struct diff_options *options,
 unsigned old_dirty_submodule, unsigned new_dirty_submodule)
 {
struct diff_filespec *one, *two;
+   struct diff_filepair *p;
 
if (S_ISGITLINK(old_mode)  S_ISGITLINK(new_mode) 
is_submodule_ignored(concatpath, options))
@@ -4916,10 +4924,17 @@ void diff_change(struct diff_options *options,
fill_filespec(two, new_sha1, new_sha1_valid, new_mode);
one-dirty_submodule = old_dirty_submodule;
two-dirty_submodule = new_dirty_submodule;
+   p = diff_queue(diff_queued_diff, one, two);
 
-   

Re: 'git diff' command doesn't honor utf8 symbol boundaries, and doesn't use actual terminal width

2014-01-24 Thread Duy Nguyen
On Sat, Jan 25, 2014 at 10:34 AM, Yuri y...@rawbw.com wrote:
 The fragment of 'git diff' output looks like this:
 - translationОшибка: адрес %1 содержит запрещенные символы. Пожалуйста,
 перепро�
 + translationОшибка: адрес %1 содержит запрещённые символы. Пожалуйста,
 перепро�

 Two issues here:
 1. Cyrilic text in utf8 got truncated not at utf8 boundary, causing this
 garbage symbol in the end
 2. Truncation is done at somewhat ~70% of the actual screen width. git could
 go all the way to the whole screen with, but it didn't. Shrinking terminal
 width causes the output truncation limit to shrink in the same proportion.
 So some bad decision about truncation size is made somewhere in 'git diff'
 command.

 Suggested behavior:
 1. git should respect utf8, and in case of truncation it should add …
 symbol.
 2. truncation algorithm should read current terminal width and truncate at
 width-1 length to allow for the above-mentioned symbol

I don't think git diff truncates its output (it does truncate @@
lines, but not the real diff). Perhaps your pager did that?
-- 
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 v2 6/9] Pass directory indicator to match_pathspec_item()

2014-01-24 Thread Duy Nguyen
On Sat, Jan 25, 2014 at 4:22 AM, Eric Sunshine sunsh...@sunshineco.com wrote:
 On Fri, Jan 24, 2014 at 8:40 AM, Nguyễn Thái Ngọc Duy pclo...@gmail.com 
 wrote:
 diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
 index af5134b..167af53 100755
 --- a/t/t4010-diff-pathspec.sh
 +++ b/t/t4010-diff-pathspec.sh
 @@ -110,4 +110,21 @@ test_expect_success 'diff-tree -r with wildcard' '
 test_cmp expected result
  '

 +test_expect_success 'setup submodules' '
 +   test_tick 

Also the test_tick here. I thought I would need to match SHA-1 but I
did not and still forgot to take this line out.

 +   git init submod 
 +   ( cd submod  test_commit first; ) 

 Unnecessary semicolon might confuse the reader into thinking something
 unusual is going on here.

 +   git add submod 
 +   git commit -m first 
 +   ( cd submod  test_commit second; ) 

 Ditto.

 +   git add submod 
 +   git commit -m second
 +'
 +
 +test_expect_success 'diff-cache ignores trailing slash on submodule path' '
 +   git diff --name-only HEAD^ submod expect 
 +   git diff --name-only HEAD^ submod/ actual 
 +   test_cmp expect actual
 +'
 +
  test_done



-- 
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 2/3] diff: do not quit early on stat-dirty files

2014-01-24 Thread Nguyễn Thái Ngọc Duy
When QUICK is set (i.e. with --quiet) we try to do as little work as
possible, stopping after seeing the first change. stat-dirty is
considered a change but it may turn out not, if no actual content is
changed. The actual content test is performed too late in the process
and the shortcut may be taken prematurely, leading to incorrect return
code.

Assume we do git diff --quiet. If we have a stat-dirty file a and
a really dirty file b. We break the loop in run_diff_files() and
stop after a because we have got a change. Later in
diffcore_skip_stat_unmatch() we find out a is actually not
changed. But there's nothing else in the diff queue, we incorrectly
declare no change, ignoring the fact that b is changed.

This also happens to git diff --quiet HEAD when it hits
diff_can_quit_early() in oneway_diff().

This patch does the content test earlier in order to keep going if a
is unchanged. The test result is cached so that when
diffcore_skip_stat_unmatch() is done in the end, we spend no cycles on
re-testing a.

Reported-by: IWAMOTO Toshihiro iwam...@valinux.co.jp
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 diff.c| 22 +-
 diffcore.h|  2 ++
 t/t4035-diff-quiet.sh |  6 ++
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/diff.c b/diff.c
index 19460ff..ab85f7e 100644
--- a/diff.c
+++ b/diff.c
@@ -4699,6 +4699,11 @@ static int diff_filespec_is_identical(struct 
diff_filespec *one,
 
 static int diff_filespec_check_stat_unmatch(struct diff_filepair *p)
 {
+   if (p-done_skip_stat_unmatch)
+   return p-skip_stat_unmatch_result;
+
+   p-done_skip_stat_unmatch = 1;
+   p-skip_stat_unmatch_result = 0;
/*
 * 1. Entries that come from stat info dirtiness
 *always have both sides (iow, not create/delete),
@@ -4720,8 +4725,8 @@ static int diff_filespec_check_stat_unmatch(struct 
diff_filepair *p)
diff_populate_filespec(p-two, 1) ||
(p-one-size != p-two-size) ||
!diff_filespec_is_identical(p-one, p-two)) /* (2) */
-   return 1;
-   return 0;
+   p-skip_stat_unmatch_result = 1;
+   return p-skip_stat_unmatch_result;
 }
 
 static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
@@ -4897,6 +4902,7 @@ void diff_change(struct diff_options *options,
 unsigned old_dirty_submodule, unsigned new_dirty_submodule)
 {
struct diff_filespec *one, *two;
+   struct diff_filepair *p;
 
if (S_ISGITLINK(old_mode)  S_ISGITLINK(new_mode) 
is_submodule_ignored(concatpath, options))
@@ -4923,10 +4929,16 @@ void diff_change(struct diff_options *options,
fill_filespec(two, new_sha1, new_sha1_valid, new_mode);
one-dirty_submodule = old_dirty_submodule;
two-dirty_submodule = new_dirty_submodule;
+   p = diff_queue(diff_queued_diff, one, two);
 
-   diff_queue(diff_queued_diff, one, two);
-   if (!DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
-   DIFF_OPT_SET(options, HAS_CHANGES);
+   if (DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
+   return;
+
+   if (DIFF_OPT_TST(options, QUICK)  options-skip_stat_unmatch 
+   !diff_filespec_check_stat_unmatch(p))
+   return;
+
+   DIFF_OPT_SET(options, HAS_CHANGES);
 }
 
 struct diff_filepair *diff_unmerge(struct diff_options *options, const char 
*path)
diff --git a/diffcore.h b/diffcore.h
index 1c16c85..6b538bc 100644
--- a/diffcore.h
+++ b/diffcore.h
@@ -70,6 +70,8 @@ struct diff_filepair {
unsigned broken_pair : 1;
unsigned renamed_pair : 1;
unsigned is_unmerged : 1;
+   unsigned done_skip_stat_unmatch : 1;
+   unsigned skip_stat_unmatch_result : 1;
 };
 #define DIFF_PAIR_UNMERGED(p) ((p)-is_unmerged)
 
diff --git a/t/t4035-diff-quiet.sh b/t/t4035-diff-quiet.sh
index 231412d..e8ae2a0 100755
--- a/t/t4035-diff-quiet.sh
+++ b/t/t4035-diff-quiet.sh
@@ -148,4 +148,10 @@ test_expect_success 'git diff --ignore-all-space, both 
files outside repo' '
)
 '
 
+test_expect_success 'git diff --quiet ignores stat-change only entries' '
+   test-chmtime +10 a 
+   echo modified b 
+   test_expect_code 1 git diff --quiet
+'
+
 test_done
-- 
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 1/3] Move diffcore_skip_stat_unmatch core logic out for reuse later

2014-01-24 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 diff.c | 49 -
 1 file changed, 28 insertions(+), 21 deletions(-)

diff --git a/diff.c b/diff.c
index 6b4cd0e..19460ff 100644
--- a/diff.c
+++ b/diff.c
@@ -4697,6 +4697,33 @@ static int diff_filespec_is_identical(struct 
diff_filespec *one,
return !memcmp(one-data, two-data, one-size);
 }
 
+static int diff_filespec_check_stat_unmatch(struct diff_filepair *p)
+{
+   /*
+* 1. Entries that come from stat info dirtiness
+*always have both sides (iow, not create/delete),
+*one side of the object name is unknown, with
+*the same mode and size.  Keep the ones that
+*do not match these criteria.  They have real
+*differences.
+*
+* 2. At this point, the file is known to be modified,
+*with the same mode and size, and the object
+*name of one side is unknown.  Need to inspect
+*the identical contents.
+*/
+   if (!DIFF_FILE_VALID(p-one) || /* (1) */
+   !DIFF_FILE_VALID(p-two) ||
+   (p-one-sha1_valid  p-two-sha1_valid) ||
+   (p-one-mode != p-two-mode) ||
+   diff_populate_filespec(p-one, 1) ||
+   diff_populate_filespec(p-two, 1) ||
+   (p-one-size != p-two-size) ||
+   !diff_filespec_is_identical(p-one, p-two)) /* (2) */
+   return 1;
+   return 0;
+}
+
 static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
 {
int i;
@@ -4707,27 +4734,7 @@ static void diffcore_skip_stat_unmatch(struct 
diff_options *diffopt)
for (i = 0; i  q-nr; i++) {
struct diff_filepair *p = q-queue[i];
 
-   /*
-* 1. Entries that come from stat info dirtiness
-*always have both sides (iow, not create/delete),
-*one side of the object name is unknown, with
-*the same mode and size.  Keep the ones that
-*do not match these criteria.  They have real
-*differences.
-*
-* 2. At this point, the file is known to be modified,
-*with the same mode and size, and the object
-*name of one side is unknown.  Need to inspect
-*the identical contents.
-*/
-   if (!DIFF_FILE_VALID(p-one) || /* (1) */
-   !DIFF_FILE_VALID(p-two) ||
-   (p-one-sha1_valid  p-two-sha1_valid) ||
-   (p-one-mode != p-two-mode) ||
-   diff_populate_filespec(p-one, 1) ||
-   diff_populate_filespec(p-two, 1) ||
-   (p-one-size != p-two-size) ||
-   !diff_filespec_is_identical(p-one, p-two)) /* (2) */
+   if (diff_filespec_check_stat_unmatch(p))
diff_q(outq, p);
else {
/*
-- 
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 3/3] diff: turn off skip_stat_unmatch on diff --cached

2014-01-24 Thread Nguyễn Thái Ngọc Duy
skip_stat_unmatch flag is added in fb13227 (git-diff: squelch empty
diffs - 2007-08-03) to ignore empty diffs caused by stat-only
dirtiness. In diff --cached case, stat is not invovled at all. While
the code is written in a way that no expensive I/O is done, we still
need to move all file pairs from the old queue to the new queue in
diffcore_skip_stat_unmatch(). Avoid it.

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

diff --git a/builtin/diff.c b/builtin/diff.c
index 0f247d2..85f97d7 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -150,9 +150,10 @@ static int builtin_diff_index(struct rev_info *revs,
perror(read_cache_preload);
return -1;
}
-   } else if (read_cache()  0) {
-   perror(read_cache);
-   return -1;
+   } else {
+   if (read_cache()  0)
+   return error(read_cache: %s, strerror(errno));
+   revs-diffopt.skip_stat_unmatch = 0;
}
return run_diff_index(revs, cached);
 }
-- 
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