Re: [PATCH v9 5/8] config: add `git_die_config()` to the config-set API

2014-08-08 Thread Tanay Abhra


On 8/8/2014 12:25 AM, Junio C Hamano wrote:
 Tanay Abhra tanay...@gmail.com writes:
 
 diff --git a/Documentation/technical/api-config.txt 
 b/Documentation/technical/api-config.txt
 index 21f280c..0d8b99b 100644
 --- a/Documentation/technical/api-config.txt
 +++ b/Documentation/technical/api-config.txt
 @@ -155,6 +155,19 @@ as well as retrieval for the queried variable, 
 including:
  Similar to `git_config_get_string`, but expands `~` or `~user` into
  the user's home directory when found at the beginning of the path.
  
 +`git_die_config(const char *key, const char *err, ...)`::
 +
 +First prints the error message specified by the caller in `err` and then
 +dies printing the line number and the file name of the highest priority
 +value for the configuration variable `key`.
 
 Reviewed with a wider context, I notice that this entry alone lacks
 the return type.  I am assuming that this is just an oversight, and
 adding 'void ' in front of the filename to match the next entry is
 simple enough.
 

Yikes, yes, you are right, it's just an oversight. I will send an amended patch.

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


[PATCH 0/8] builtin/mv.c cleanup

2014-08-08 Thread Nguyễn Thái Ngọc Duy
I was looking at builtin/mv.c for pathspec support and ended up
cleaning it up a bit. The first patch is definitely good. The rest
could be questionable. Although the output in the end looks better in
my opinion.

Nguyễn Thái Ngọc Duy (8):
  mv: mark strings for translations
  mv: no Huh? to the user
  mv: flatten error handling code block
  mv: split submodule move preparation code out
  mv: remove an if that's always true
  mv: move index search code out
  mv: unindent one level for directory move code
  mv: combine two if(s)

 builtin/mv.c | 168 +--
 1 file changed, 84 insertions(+), 84 deletions(-)

-- 
2.1.0.rc0.78.gc0d8480

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


[PATCH 2/8] mv: no Huh? to the user

2014-08-08 Thread Nguyễn Thái Ngọc Duy
Although if we are frisky, this could do

   static NORETURN void die_builtin(const char *err, va_list params)
   {
  - vreportf(fatal: , err, params);
  + vreportf(Huh? , err, params);
exit(128);
   }

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

diff --git a/builtin/mv.c b/builtin/mv.c
index b892f63..a7e02c0 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -135,7 +135,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (first = 0) {
struct strbuf submodule_dotgit = STRBUF_INIT;
if (!S_ISGITLINK(active_cache[first]-ce_mode))
-   die (_(Huh? Directory %s is in index 
and no submodule?), src);
+   die (_(Directory %s is in index and no 
submodule?), src);
if (!is_staging_gitmodules_ok())
die (_(Please, stage your changes to 
.gitmodules or stash them to proceed));
strbuf_addf(submodule_dotgit, %s/.git, src);
@@ -153,8 +153,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 
first = cache_name_pos(src_w_slash, 
len_w_slash);
if (first = 0)
-   die (_(Huh? %.*s is in index?),
-   len_w_slash, 
src_w_slash);
+   die (_(%.*s is in index), 
len_w_slash, src_w_slash);
 
first = -1 - first;
for (last = first; last  active_nr; last++) {
-- 
2.1.0.rc0.78.gc0d8480

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


[PATCH 4/8] mv: split submodule move preparation code out

2014-08-08 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/mv.c | 35 +--
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/builtin/mv.c b/builtin/mv.c
index 5c6f58f..e192f2d 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -66,6 +66,23 @@ static void move_up_one(void *p, int nmemb, int size)
 static struct lock_file lock_file;
 #define SUBMODULE_WITH_GITDIR ((const char *)1)
 
+static void prepare_move_submodule(const char *src, int first,
+  const char **submodule_gitfile)
+{
+   struct strbuf submodule_dotgit = STRBUF_INIT;
+   if (!S_ISGITLINK(active_cache[first]-ce_mode))
+   die (_(Directory %s is in index and no submodule?), src);
+   if (!is_staging_gitmodules_ok())
+   die (_(Please, stage your changes to .gitmodules or stash them 
to proceed));
+   strbuf_addf(submodule_dotgit, %s/.git, src);
+   *submodule_gitfile = read_gitfile(submodule_dotgit.buf);
+   if (*submodule_gitfile)
+   *submodule_gitfile = xstrdup(*submodule_gitfile);
+   else
+   *submodule_gitfile = SUBMODULE_WITH_GITDIR;
+   strbuf_release(submodule_dotgit);
+}
+
 int cmd_mv(int argc, const char **argv, const char *prefix)
 {
int i, gitmodules_modified = 0;
@@ -137,20 +154,10 @@ int cmd_mv(int argc, const char **argv, const char 
*prefix)
bad = _(cannot move directory over file);
else if (src_is_dir) {
int first = cache_name_pos(src, length);
-   if (first = 0) {
-   struct strbuf submodule_dotgit = STRBUF_INIT;
-   if (!S_ISGITLINK(active_cache[first]-ce_mode))
-   die (_(Directory %s is in index and no 
submodule?), src);
-   if (!is_staging_gitmodules_ok())
-   die (_(Please, stage your changes to 
.gitmodules or stash them to proceed));
-   strbuf_addf(submodule_dotgit, %s/.git, src);
-   submodule_gitfile[i] = 
read_gitfile(submodule_dotgit.buf);
-   if (submodule_gitfile[i])
-   submodule_gitfile[i] = 
xstrdup(submodule_gitfile[i]);
-   else
-   submodule_gitfile[i] = 
SUBMODULE_WITH_GITDIR;
-   strbuf_release(submodule_dotgit);
-   } else {
+   if (first = 0)
+   prepare_move_submodule(src, first,
+  submodule_gitfile + i);
+   else {
const char *src_w_slash = add_slash(src);
int last, len_w_slash = length + 1;
 
-- 
2.1.0.rc0.78.gc0d8480

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


[PATCH 1/8] mv: mark strings for translations

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

diff --git a/builtin/mv.c b/builtin/mv.c
index 6ffe540..b892f63 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -108,7 +108,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
destination = internal_copy_pathspec(dest_path[0], argv, argc, 
DUP_BASENAME);
} else {
if (argc != 1)
-   die(destination '%s' is not a directory, 
dest_path[0]);
+   die(_(destination '%s' is not a directory), 
dest_path[0]);
destination = dest_path;
}
 
-- 
2.1.0.rc0.78.gc0d8480

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


[PATCH 3/8] mv: flatten error handling code block

2014-08-08 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/mv.c | 35 +--
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/builtin/mv.c b/builtin/mv.c
index a7e02c0..5c6f58f 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -58,6 +58,11 @@ static const char *add_slash(const char *path)
return path;
 }
 
+static void move_up_one(void *p, int nmemb, int size)
+{
+   memmove(p, (char*)p + size, nmemb * size);
+}
+
 static struct lock_file lock_file;
 #define SUBMODULE_WITH_GITDIR ((const char *)1)
 
@@ -224,24 +229,18 @@ int cmd_mv(int argc, const char **argv, const char 
*prefix)
else
string_list_insert(src_for_dst, dst);
 
-   if (bad) {
-   if (ignore_errors) {
-   if (--argc  0) {
-   memmove(source + i, source + i + 1,
-   (argc - i) * sizeof(char *));
-   memmove(destination + i,
-   destination + i + 1,
-   (argc - i) * sizeof(char *));
-   memmove(modes + i, modes + i + 1,
-   (argc - i) * sizeof(enum 
update_mode));
-   memmove(submodule_gitfile + i,
-   submodule_gitfile + i + 1,
-   (argc - i) * sizeof(char *));
-   i--;
-   }
-   } else
-   die (_(%s, source=%s, destination=%s),
-bad, src, dst);
+   if (!bad)
+   continue;
+   if (!ignore_errors)
+   die (_(%s, source=%s, destination=%s),
+bad, src, dst);
+   if (--argc  0) {
+   int n = argc - i;
+   move_up_one(source + i, n, sizeof(*source));
+   move_up_one(destination + i, n, sizeof(*destination));
+   move_up_one(modes + i, n, sizeof(*modes));
+   move_up_one(submodule_gitfile + i, n, 
sizeof(*submodule_gitfile));
+   i--;
}
}
 
-- 
2.1.0.rc0.78.gc0d8480

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


[PATCH 5/8] mv: remove an if that's always true

2014-08-08 Thread Nguyễn Thái Ngọc Duy
This is inside an else block of if (last - first  1), so we know
that last - first = 1 when we come here. No need to check
last - first  0.

While at there, save argc + last - first to a variable to shorten
the statements a bit.

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

diff --git a/builtin/mv.c b/builtin/mv.c
index e192f2d..a45226e 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -179,22 +179,14 @@ int cmd_mv(int argc, const char **argv, const char 
*prefix)
if (last - first  1)
bad = _(source directory is empty);
else {
-   int j, dst_len;
+   int j, dst_len, n;
 
-   if (last - first  0) {
-   source = xrealloc(source,
-   (argc + last - 
first)
-   * sizeof(char 
*));
-   destination = 
xrealloc(destination,
-   (argc + last - 
first)
-   * sizeof(char 
*));
-   modes = xrealloc(modes,
-   (argc + last - 
first)
-   * sizeof(enum 
update_mode));
-   submodule_gitfile = 
xrealloc(submodule_gitfile,
-   (argc + last - 
first)
-   * sizeof(char 
*));
-   }
+   n = argc + last - first;
+   source = xrealloc(source, n * 
sizeof(char *));
+   destination = xrealloc(destination, n * 
sizeof(char *));
+   modes = xrealloc(modes, n * sizeof(enum 
update_mode));
+   submodule_gitfile =
+   xrealloc(submodule_gitfile, n * 
sizeof(char *));
 
dst = add_slash(dst);
dst_len = strlen(dst);
-- 
2.1.0.rc0.78.gc0d8480

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


[PATCH 8/8] mv: combine two if(s)

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

diff --git a/builtin/mv.c b/builtin/mv.c
index a2e33b5..4eb420b 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -276,10 +276,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (gitmodules_modified)
stage_updated_gitmodules();
 
-   if (active_cache_changed) {
-   if (write_locked_index(the_index, lock_file, COMMIT_LOCK))
+   if (active_cache_changed 
+   write_locked_index(the_index, lock_file, COMMIT_LOCK))
die(_(Unable to write new index file));
-   }
 
return 0;
 }
-- 
2.1.0.rc0.78.gc0d8480

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


[PATCH 6/8] mv: move index search code out

2014-08-08 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/mv.c | 41 +
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/builtin/mv.c b/builtin/mv.c
index a45226e..f8d65e2 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -83,6 +83,29 @@ static void prepare_move_submodule(const char *src, int 
first,
strbuf_release(submodule_dotgit);
 }
 
+static int index_range_of_same_dir(const char *src, int length,
+  int *first_p, int *last_p)
+{
+   const char *src_w_slash = add_slash(src);
+   int first, last, len_w_slash = length + 1;
+
+   first = cache_name_pos(src_w_slash, len_w_slash);
+   if (first = 0)
+   die (_(%.*s is in index), len_w_slash, src_w_slash);
+
+   first = -1 - first;
+   for (last = first; last  active_nr; last++) {
+   const char *path = active_cache[last]-name;
+   if (strncmp(path, src_w_slash, len_w_slash))
+   break;
+   }
+   if (src_w_slash != src)
+   free((char *)src_w_slash);
+   *first_p = first;
+   *last_p = last;
+   return last - first;
+}
+
 int cmd_mv(int argc, const char **argv, const char *prefix)
 {
int i, gitmodules_modified = 0;
@@ -158,24 +181,10 @@ int cmd_mv(int argc, const char **argv, const char 
*prefix)
prepare_move_submodule(src, first,
   submodule_gitfile + i);
else {
-   const char *src_w_slash = add_slash(src);
-   int last, len_w_slash = length + 1;
+   int last;
 
modes[i] = WORKING_DIRECTORY;
-
-   first = cache_name_pos(src_w_slash, 
len_w_slash);
-   if (first = 0)
-   die (_(%.*s is in index), 
len_w_slash, src_w_slash);
-
-   first = -1 - first;
-   for (last = first; last  active_nr; last++) {
-   const char *path = 
active_cache[last]-name;
-   if (strncmp(path, src_w_slash, 
len_w_slash))
-   break;
-   }
-   if (src_w_slash != src)
-   free((char *)src_w_slash);
-
+   index_range_of_same_dir(src, length, first, 
last);
if (last - first  1)
bad = _(source directory is empty);
else {
-- 
2.1.0.rc0.78.gc0d8480

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


[PATCH 7/8] mv: unindent one level for directory move code

2014-08-08 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/mv.c | 47 +--
 1 file changed, 21 insertions(+), 26 deletions(-)

diff --git a/builtin/mv.c b/builtin/mv.c
index f8d65e2..a2e33b5 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -176,42 +176,37 @@ int cmd_mv(int argc, const char **argv, const char 
*prefix)
 lstat(dst, st) == 0)
bad = _(cannot move directory over file);
else if (src_is_dir) {
-   int first = cache_name_pos(src, length);
+   int first = cache_name_pos(src, length), last;
if (first = 0)
prepare_move_submodule(src, first,
   submodule_gitfile + i);
-   else {
-   int last;
-
+   else if (index_range_of_same_dir(src, length,
+first, last)  1) {
modes[i] = WORKING_DIRECTORY;
-   index_range_of_same_dir(src, length, first, 
last);
if (last - first  1)
bad = _(source directory is empty);
-   else {
-   int j, dst_len, n;
+   } else { /* last - first = 1 */
+   int j, dst_len, n;
 
-   n = argc + last - first;
-   source = xrealloc(source, n * 
sizeof(char *));
-   destination = xrealloc(destination, n * 
sizeof(char *));
-   modes = xrealloc(modes, n * sizeof(enum 
update_mode));
-   submodule_gitfile =
-   xrealloc(submodule_gitfile, n * 
sizeof(char *));
+   modes[i] = WORKING_DIRECTORY;
+   n = argc + last - first;
+   source = xrealloc(source, n * sizeof(char *));
+   destination = xrealloc(destination, n * 
sizeof(char *));
+   modes = xrealloc(modes, n * sizeof(enum 
update_mode));
+   submodule_gitfile = xrealloc(submodule_gitfile, 
n * sizeof(char *));
 
-   dst = add_slash(dst);
-   dst_len = strlen(dst);
+   dst = add_slash(dst);
+   dst_len = strlen(dst);
 
-   for (j = 0; j  last - first; j++) {
-   const char *path =
-   active_cache[first + 
j]-name;
-   source[argc + j] = path;
-   destination[argc + j] =
-   prefix_path(dst, 
dst_len,
-   path + length + 
1);
-   modes[argc + j] = INDEX;
-   submodule_gitfile[argc + j] = 
NULL;
-   }
-   argc += last - first;
+   for (j = 0; j  last - first; j++) {
+   const char *path = active_cache[first + 
j]-name;
+   source[argc + j] = path;
+   destination[argc + j] =
+   prefix_path(dst, dst_len, path 
+ length + 1);
+   modes[argc + j] = INDEX;
+   submodule_gitfile[argc + j] = NULL;
}
+   argc += last - first;
}
} else if (cache_name_pos(src, length)  0)
bad = _(not under version control);
-- 
2.1.0.rc0.78.gc0d8480

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


push from one remote to another

2014-08-08 Thread Olaf Hering
What is the correct syntax/setup to push from one remote to another?
I did something like this, to feed a github repo:

 # rm -rf $$
 # mkdir $$
 # cd $$
 # git --init
 # git remote add --tags t 
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
 # git remote add --tags o g...@github.com:user/repo.git
 # git fetch --all

This syntax does not work for me:
 # git push t master o master
 # git push --tags t master o master

Is there a way to kind of mirror without doing a checkout, to save
diskspace?

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


Re: push from one remote to another

2014-08-08 Thread Andreas Schwab
Olaf Hering o...@aepfle.de writes:

 What is the correct syntax/setup to push from one remote to another?
 I did something like this, to feed a github repo:

  # rm -rf $$
  # mkdir $$
  # cd $$
  # git --init
  # git remote add --tags t 
 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
  # git remote add --tags o g...@github.com:user/repo.git
  # git fetch --all

 This syntax does not work for me:
  # git push t master o master
  # git push --tags t master o master

$ git push o remotes/t/master:master

Andreas.

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


Re: [PATCH v8 0/8] Rewrite `git_config()` using config-set API

2014-08-08 Thread Tanay Abhra
On 8/8/2014 2:01 AM, Junio C Hamano wrote:
 Matthieu Moy matthieu@grenoble-inp.fr writes:
 
 Why is this needed? Are you now using key_value_info outside config.c?
 Or is it a leftover from a previous experiment?

 Has this been resolved in the new round?

 Tanay explained in another subthread why this was needed. For callers
 iterating over the string_list who want to get the file/line info, they
 need to be able to cast the void * pointer to struct key_value_info *.
 
 For callers that want to see all the multi-values, it would be
 preferrable for the iterator to pass the filename and the linenumber
 to the callback function, instead of exposing its implementation
 detail as a single string list and telling them to pick it apart,
 no?
 
 Not a very convincing argument, but OK for now in the sense that we
 can fix it later if we wanted to before it gets too late.


(cc to Ramsay)

The discussion in both threads (v8 and v9), boils down to this,
is the `key_value_info` struct really required to be declared public or should 
be
just an implementation detail. I will give you the context,

The usage of the above mentioned struct is only required for
git_config_get_value_multi(). With the public struct, the code flow would look
like,


-- 8 --
diff --git a/notes.c b/notes.c
index 5fe691d..b7ab115 100644
--- a/notes.c
+++ b/notes.c
@@ -961,19 +961,6 @@ void string_list_add_refs_from_colon_sep(struct 
string_list *list,
free(globs_copy);
 }

-static int notes_display_config(const char *k, const char *v, void *cb)
-{
-   int *load_refs = cb;
-
-   if (*load_refs  !strcmp(k, notes.displayref)) {
-   if (!v)
-   config_error_nonbool(k);
-   string_list_add_refs_by_glob(display_notes_refs, v);
-   }
-
-   return 0;
-}
-
 const char *default_notes_ref(void)
 {
const char *notes_ref = NULL;
@@ -1041,7 +1028,9 @@ struct notes_tree **load_notes_trees(struct string_list 
*refs)
 void init_display_notes(struct display_notes_opt *opt)
 {
char *display_ref_env;
-   int load_config_refs = 0;
+   const struct string_list *values;
+   struct key_value_info *kv_info;
+   int load_config_refs = 0, i;
display_notes_refs.strdup_strings = 1;

assert(!display_notes_trees);
@@ -1058,7 +1047,21 @@ void init_display_notes(struct display_notes_opt *opt)
load_config_refs = 1;
}

-   git_config(notes_display_config, load_config_refs);
+   if (load_config_refs) {
+   values = git_config_get_value_multi(notes.displayref);
+   if (values) {
+   for (i = 0; i  values-nr; i++) {
+   if (!values-items[i].string) {
+   kv_info = values-items[i].util;
+   
config_error_nonbool(notes.displayref);
+   
git_die_config_linenr(notes.displayref, kv_info-filename, kv_info-linenr);
+   }
+   else
+   
string_list_add_refs_by_glob(display_notes_refs,
+
values-items[i].string);
+   }
+   }
+   }

if (opt) {
struct string_list_item *item;
-- 8 --

We cannot use git_die_config() here because it is applicable to the last
value for a given variable.

Alternative solution to the problem can be a helper function like this,

git_die_config_index(key, value_index, err_msg, ...) which needs the 
value_index for a multi valued one,

+   values = git_config_get_value_multi(notes.displayref);
+   if (values) {
+   for (i = 0; i  values-nr; i++) {
+   if (!values-items[i].string)
+   
git_die_config_linenr(notes.displayref, i, no null values allowed for 
:'%s', notes.displayref);
+   else ; /* do stuff */
+   }

A callback iterator which supplies the linenr and filename to the callback
function is not helpful, because there are many variable checks in a
git_config() call where multi valued and single valued both reside, so we cannot
use a callback iterator without adding more code cruft.

What do you think, which way seems least obtrusive, or is there an another way 
out?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v8 0/8] Rewrite `git_config()` using config-set API

2014-08-08 Thread Ramsay Jones
On 08/08/14 15:07, Tanay Abhra wrote:
 On 8/8/2014 2:01 AM, Junio C Hamano wrote:
 Matthieu Moy matthieu@grenoble-inp.fr writes:

 Why is this needed? Are you now using key_value_info outside config.c?
 Or is it a leftover from a previous experiment?

 Has this been resolved in the new round?

 Tanay explained in another subthread why this was needed. For callers
 iterating over the string_list who want to get the file/line info, they
 need to be able to cast the void * pointer to struct key_value_info *.

 For callers that want to see all the multi-values, it would be
 preferrable for the iterator to pass the filename and the linenumber
 to the callback function, instead of exposing its implementation
 detail as a single string list and telling them to pick it apart,
 no?

 Not a very convincing argument, but OK for now in the sense that we
 can fix it later if we wanted to before it gets too late.

 
 (cc to Ramsay)
 
 The discussion in both threads (v8 and v9), boils down to this,
 is the `key_value_info` struct really required to be declared public or 
 should be
 just an implementation detail. I will give you the context,

No, this is not the issue for me. The patch which introduces the
struct in cache.h does not make use of that struct in any interface.
It *is* an implementation detail of some code in config.c only.

I do not know how that structure will be used in future patches. ;-)

ATB,
Ramsay Jones


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


Re: Pluggable backends for refs,wip

2014-08-08 Thread Ronnie Sahlberg
On Thu, Aug 7, 2014 at 5:57 AM, Michael Haggerty mhag...@alum.mit.edu wrote:
 On 08/05/2014 02:40 PM, Ronnie Sahlberg wrote:
 Please see
 https://github.com/rsahlberg/git/tree/backend-struct-db-2
 for an example of a pluggable backend for refs storage.

 This series contain changes to make it possible to add new backends
 for handling/storage of refs and implements one new backend :
 refs-be-be.c .

 This new backend offloads the actual refs handling to a small database
 daemon with which ita talks via a very simple rpc protocol. That
 daemon in turn then connects to the datastore and read/writes the
 values to it.
 [...]

 Ronnie,

 This is awesome!  Congratulations on your progress.

 I'm still on vacation and haven't yet looked at the code.  I will be
 back next week and hope to find time to check it out, and also to do
 some more review of the code that you have already submitted to git core.

Thanks!



 Have you thought about how to test alternate reference backends?  This
 will be very important to getting one or more of them accepted into git
 core (not to mention giving people confidence to actually *use* them!)

I have thought about it and also done some experiments.
For the initial git support, I think we first should try to get the
pluggable backend support
into git, and also the work to change the current files backend into a
built-in pluggable backend.

I.e. get everything in the
https://github.com/rsahlberg/git/tree/backend-struct-db-2
branch except the last three patches.
That brings us to a stage where we have pluggable backend support and
we have one backend, the files backend, that works just like today.

The last three patches in that series are then just confirmation that
the pluggable backend approach works and we can add that a little
later once we finish tests and other things.



For tests there are the issues with git-clone and git-init
requiring two additional arguments in order to set up and initialize a
repository to use the database daemon backend.
Other future backends I would imagine would have similar needs.
The way I handle in the experiments I did was to use two new
environment variables GIT_INIT and GIT_CLONE that would default to
git-clone and git-init respectively
and then just override them with GIT_INIT=git-init
--db-repo-name=ROCKy --db-socket=/tmp/refsd.socket when I wanted the
tests to initialize a database backend repository.
This required some updates to test-lib.sh and test-lib-functions.sh as
well as the tests themself to use ${GIT_INIT} instead of git-init
directly.

I am not sure what is the best approach here is and would love if you
could help out with this once we get the basic pluggable backend stuff
in.




 It seems to me that a few steps are needed:

 * Each backend would need a suite of backend-aware tests that verify
 proper operation *within* the backend.  These tests would mostly use
 low-level plumbing commands like update-refs to create/modify/delete
 references, and would be allowed to grub around in the filesystem, talk
 directly with the database, etc. to make sure that the commands have the
 correct effects.  For example, for the traditional filesystem backend,
 these tests would be the ones to check that creating a reference causes
 a file to spring into existence under $GIT_DIR/refs.

Yes.
Quite a few tests do muck around with the files directly. Some for
good reasons but I think there are a lot of cases where the tests do
it just out of convenience.

For this we will need to convert the tests that don't strictly need to
muck around with the files to use a backend agnostic method to do the
same checks.
For the tests that are truly testing the backend itself, such as a
hypothetical test to check that a symbolic link to a ref behaves as it
should, we will need a mechanism where we can conditionalize the tests
based on what is the current backend.
So lots of if backend == database then skip this test



 The tests for pack-refs, and all tests that care about the distinction
 between packed and loose refs, would become part of the backend-aware
 tests for the filesystem backend.

 All of the backend-aware tests should be run every time the test suite
 is run (provided, of course, that the correct prerequisites are
 available, and subject to being turned off manually).

 * The rest of the test suite has to be made backend-agnostic.  For
 example, such tests should *not* be allowed to look under $GIT_DIR for
 the existence/absence of loose reference files [1] but would rather have
 to inquire about references via git commands.

 * It should be possible for the developer to choose easily which
 reference backend to use when running the agnostic part of the test
 suite.  The chosen backend should be used to run *all* backend-agnostic
 tests.


Agree.
It would be great if we could work on this together.


 A database-backed backend might even want to be testable in two modes:
 one with the DB daemon running constantly, and one where the daemon is
 

Re: [PATCH 0/5] ref-transactions-send-pack

2014-08-08 Thread Ronnie Sahlberg
Ping

On Thu, Jul 31, 2014 at 2:39 PM, Ronnie Sahlberg sahlb...@google.com wrote:
 List,

 This small patch series adds atomic-push support to for pushes.
 By default git will use the old style non-atomic updates for pushes,
 as not to cause disruption in client scripts that may depend on that
 behaviour.

 Command line arguments are introduced to allow the client side to request/
 negotiate atomic pushes if the remote repo supports it.
 There is also a new configuration variable where a repo can set that it
 wants all pushes to become atomic whether the client requests it or not.

 This patch series is called ref-transactions-send-pack and depends on/is built
 ontop of the series called ref-transactions-req-strbuf-err


 Ronnie Sahlberg (5):
   receive-pack.c: add protocol support to negotiate atomic-push
   send-pack.c: add an --atomic-push command line argument
   receive-pack.c: use a single transaction when atomic-push is
 negotiated
   receive-pack.c: add receive.atomicpush configuration option
   push.c: add an --atomic-push argument

  Documentation/config.txt|  5 
  Documentation/git-push.txt  |  7 -
  Documentation/git-send-pack.txt |  7 -
  builtin/push.c  |  2 ++
  builtin/receive-pack.c  | 66 
 +
  builtin/send-pack.c |  6 +++-
  send-pack.c | 18 +--
  send-pack.h |  1 +
  transport.c |  1 +
  transport.h |  1 +
  10 files changed, 96 insertions(+), 18 deletions(-)

 --
 2.0.1.528.gd0e7a84

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


Re: [PATCH 0/5] ref-transactions-req-strbuf-err

2014-08-08 Thread Ronnie Sahlberg
Ping ?

On Thu, Jul 31, 2014 at 2:25 PM, Ronnie Sahlberg sahlb...@google.com wrote:
 List,

 This is the next patch series in the ref transaction work.
 This patch series is called ref-transactions-req-strbuf-err and builds ontop
 of the series called ref-transactions-req-packed-refs which is origin/pu


 This patch series mainly adds some nice strbuf arguments to some functions to
 pass errors back to callers.
 The only thing noteworthy is that we finally get to remove
 -enum action_on_err {
 -   UPDATE_REFS_MSG_ON_ERR,
 -   UPDATE_REFS_DIE_ON_ERR,
 -   UPDATE_REFS_QUIET_ON_ERR
 -};

 aside from that there is little/nothing much interesting in there.


 Ronnie Sahlberg (5):
   refs.c: replace the onerr argument in update_ref with a strbuf err
   refs.c: make add_packed_ref return an error instead of calling die
   refs.c: make lock_packed_refs take an err argument
   refs.c: add an err argument to commit_packed_refs
   refs.c: add an err argument to pack_refs

  builtin/checkout.c   |   7 ++-
  builtin/clone.c  |  23 +---
  builtin/merge.c  |  20 ---
  builtin/notes.c  |  24 +
  builtin/pack-refs.c  |   8 ++-
  builtin/reset.c  |  12 +++--
  builtin/update-ref.c |   7 ++-
  notes-cache.c|   2 +-
  notes-utils.c|   5 +-
  refs.c   | 148 
 +--
  refs.h   |  13 ++---
  transport-helper.c   |   7 ++-
  transport.c  |   9 ++--
  13 files changed, 170 insertions(+), 115 deletions(-)

 --
 2.0.1.523.g70700c9

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


Fwd: Rebase safely (Re: cherry picking and merge)

2014-08-08 Thread Mike Stump
[ sorry for the dup ]

Begin forwarded message:

On Aug 6, 2014, at 12:44 PM, Nico Williams n...@cryptonector.com wrote:
 It's not a good idea to rebase a branch in a repo that others pull from.

Well, so rebase is then out, as I don’t want to rebase _my_ tree, I want to 
rebase _the_ tree.  Recall, I don’t want to cherry pick for my tree, I want to 
cherry pick for the tree.

[ reads rest of email ]

Oh, wait, maybe I have misunderstood the prohibition.  I have:

   upstream  —— fsf
   |
\
 |
 v
Me  —   master  — coworker.

Me is a git clone of master, coworker is a git clone of master.  Master is a 
bare repo on a shared server where we put all of our work.  upstream is a bare 
git repo of the fsf git tree for gcc.  fsf is a box owned by other that hosts 
the gcc git repository.  I do a git pull fsf in upstream from time to time, and 
a corresponding git merge fsf in Me from time to time.  When I like my work I 
do a git push (to master exclusively).  To go to upstream, we submit patches by 
hand, git is not really involved.  I never pull into master from upstream 
(don’t even think that’s possible since they are both bare).

I read the prohibition as don’t rebase my branch called master on Me and push 
it to master on master as others then pull master from master.  Did I 
misunderstand?  Instead, the prohibition is you can use push/pull freely and 
you can have as many coworkers as you want, just don’t use push -f and don’t 
let anyone push/pull from your own private clone.

I had envisions that the rebase of master on Me once pushed to master and then 
pull from master to coworker is the exact case that would screw us.

 The only use-case I've seen where a rebase-based workflow doesn't work

Well, and now mine, which I claim is a the canonical open source use case.  
Can't use source, unless you import the source,  can’t be real unless you can 
change the source, once you do that, you then need to merge in newer sources, 
and if the company has or will have more than a single individual and these 
folks are ever to work together, then they need to share the source between 
them.

I’m trying to envision how anyone could ever use rebase.  If you can’t share 
your work, it isn’t work.

 is where you have multiple upstreams that you're following.

I only have a single (for this repo) upstream.

 Now, I found the stack-overflow commentary first, and all the horrors
 of it, and all the nuances.  I carefully read what people were doing,
 how what I wanted to related to what they were doing, and it sure felt
 like I was in the, don’t go there camp.
 
 A lot of people rant about rebase.  They're wrong.  They've distorted
 your perspective.

What I saw were the people that screwed their world and were trying to recover. 
 It was a question, how do I recover, and what did I do wrong.  There was no 
rant.  Or, at least, I’m impervious to rants and don’t actually see them.  I 
deal in the cold hard facts and transform the rant into what happened, what 
they did wrong, and how to avoid doing it myself.

No, you’ve set my perspective, let me quote you:

  It's not a good idea to rebase a branch in a repo that others pull from.

this matches the doc, matches the experience of users on stack overflow and 
matches what what I think is true.  You are free to correct that if I am wrong.

I don’t know why you think my perspective is distorted.  Either, I can rebase 
all my patches, all my coworkers patches, and push those up to master and have 
all my coworkers pull from master and develop (meaning branches off master as 
well as patches to master) as normal, or I can’t.

 There's just two simple rules to follow and you'll be safe:
 
 1) NEVER git push -f (--force) to a published repo/branch.

I can never use push -f.  That seems trivial.  git config --system 
receive.denyNonFastForwards true seems to be exactly what I would do to my 
master to enforce this rule.  This then seems to permanently be a non-issue.

 2) NEVER work directly in a published repo.  Instead work in a private
   clone.

I only ever work in a private to me clone, so I’m safe.  The only published 
repo is a bare repo, which can’t be worked in by design, so, again, I think I’m 
perfectly safe.

So, if that is true, why do others write such things as (from 
http://ctoinsights.wordpress.com/2012/06/29/git-flow-with-rebase/):

 The way to get the best of both worlds is to be explicit about when to use 
 one versus the other. For us the simple rules to follow are:
   • Rebase feature branches.
   • Never rebase develop or master branch. (Always merge into develop and 
 master.)
   • Never rebase public branches.
master is public, I want to rebase master.  This violates rule 3 above, but not 
any of your rules?

I develop on master, thus violating rule 2.  This does’t violate any of your 
rules?

I want to rebase master, thus, violating rule 1.  This doesn’t violate any of 
your rules?

I violate 

Re: [PATCH 3/7] Documentation: git-init: template directory: reword

2014-08-08 Thread Linus Arver
On Wed, Aug 06, 2014 at 10:21:33AM -0700, Junio C Hamano wrote:
 Linus Arver linusar...@gmail.com writes:
 
  No, the unindenting/removal of blank lines is a non-grammar change and
  is not necessary, as it doesn't have any effect on the actual output
  (html/txt/manpage).
 
  I can either keep the same coding style with the rewording, or chop this
  into two commits, one for the rewording and another for reformatting.
  Which one do you suggest?
 
 If I were doing this change, I wouldn't touch the formatting,
 because I did not find that the reformatted version would be any
 easier to read or maintain compared to the original.
 
 But I suspect that you must have thought the reformatting was a good
 thing to do for a reason, and I suspected I might have been missing
 something obvious to you, and that was why I asked.  If there is a
 good reason to reformat, then lets hear it in the commit log message
 of one of the two patches.  Otherwise we can drop the reformatting
 part.

And well, considering that the rewording makes the separate items into a
single sentence, I thought it would help readability to delete all the
whitespace.

In retrospect, I don't think this is a good enough reason to reformat.
It was more of a personal writing style judgment call. I am dropping the
reformatting part.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/7] Documentation: git-init: --separate-git-dir: clarify

2014-08-08 Thread Linus Arver
On Wed, Aug 06, 2014 at 10:35:31AM -0700, Junio C Hamano wrote:
 While I agree that it is a very good idea to state what it does,
 what it is for with the very first sentence of the paragraph,
 separate the git repository from your working tree does not say
 much more than the name of the option --separate-git-dir already
 tells the reader.

Ah, I see.

 And I do not offhand think of a better version
 (and obviously I didn't think of any when the current text was
 reviewed and committed).  The second sentence in your version is
 definitely an improvement over the first and the second sentences of
 the original (where it is supposed to be does not give any new
 information to those who don't know, and does not help those who
 already know).

OK.

 Perhaps we can simply remove the first sentence from your version?

Yes, I agree. I enjoy cutting excess verbiage.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/22] refs.c: create a public function for is_refname_available

2014-08-08 Thread Ronnie Sahlberg
Export a generic is_refname_available() function. We will need this
as a public shared function later when we add additional refs backends
since we want to keep using the same rules for ref naming across
all backends.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs.c | 29 ++---
 refs.h |  6 ++
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/refs.c b/refs.c
index 7e13c0f..4a22513 100644
--- a/refs.c
+++ b/refs.c
@@ -830,9 +830,9 @@ static int name_conflict_fn(struct ref_entry *entry, void 
*cb_data)
  * operation). skip contains a list of refs we want to skip checking for
  * conflicts with.
  */
-static int is_refname_available(const char *refname,
-   struct ref_dir *dir,
-   const char **skip, int skipnum)
+static int is_refname_available_dir(const char *refname,
+   struct ref_dir *dir,
+   const char **skip, int skipnum)
 {
struct name_conflict_cb data;
data.refname = refname;
@@ -1238,6 +1238,18 @@ static struct ref_dir *get_loose_refs(struct ref_cache 
*refs)
return get_ref_dir(refs-loose);
 }
 
+int is_refname_available(const char *refname, const char **skip, int skipnum)
+{
+   if (!is_refname_available_dir(refname, get_packed_refs(ref_cache),
+ skip, skipnum))
+   return 0;
+
+   if (!is_refname_available_dir(refname, get_loose_refs(ref_cache),
+ skip, skipnum))
+   return 0;
+   return 1;
+}
+
 /* We allow recursive symbolic refs. Only within reason, though */
 #define MAXDEPTH 5
 #define MAXREFLEN (1024)
@@ -2168,8 +2180,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char 
*refname,
 * name is a proper prefix of our refname.
 */
if (missing 
-!is_refname_available(refname, get_packed_refs(ref_cache),
-  skip, skipnum)) {
+!is_refname_available_dir(refname, get_packed_refs(ref_cache),
+  skip, skipnum)) {
last_errno = ENOTDIR;
goto error_return;
}
@@ -2676,12 +2688,7 @@ int rename_ref(const char *oldrefname, const char 
*newrefname, const char *logms
return 1;
}
 
-   if (!is_refname_available(newrefname, get_packed_refs(ref_cache),
- oldrefname, 1))
-   return 1;
-
-   if (!is_refname_available(newrefname, get_loose_refs(ref_cache),
- oldrefname, 1))
+   if (!is_refname_available(newrefname, oldrefname, 1))
return 1;
 
log = reflog_exists(oldrefname);
diff --git a/refs.h b/refs.h
index f44b5c8..7b59044 100644
--- a/refs.h
+++ b/refs.h
@@ -131,6 +131,12 @@ extern int ref_exists(const char *);
 extern int is_branch(const char *refname);
 
 /*
+ * Check is a particular refname is available for creation. skip contains
+ * a list of refnames to exclude from the refname collission tests.
+ */
+int is_refname_available(const char *refname, const char **skip, int skipnum);
+
+/*
  * If refname is a non-symbolic reference that refers to a tag object,
  * and the tag can be (recursively) dereferenced to a non-tag object,
  * store the SHA1 of the referred-to object to sha1 and return 0.  If
-- 
2.0.1.553.geee1b3e

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


[PATCH 03/22] refs-common.c: move update_ref to refs-common.c

2014-08-08 Thread Ronnie Sahlberg
This change moves update_ref() to the refs-common.c file since this function
does not contain any backend specific code.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 25 +
 refs.c| 23 ---
 2 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index 44d96d2..cb884b2 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -1,2 +1,27 @@
 /* common code for all ref backends */
+#include cache.h
+#include refs.h
+
+int update_ref(const char *action, const char *refname,
+  const unsigned char *sha1, const unsigned char *oldval,
+  int flags, struct strbuf *e)
+{
+   struct ref_transaction *t;
+   struct strbuf err = STRBUF_INIT;
+
+   t = transaction_begin(err);
+   if (!t ||
+   transaction_update_sha1(t, refname, sha1, oldval, flags,
+   !!oldval, action, err) ||
+   transaction_commit(t, err)) {
+   const char *str = update_ref failed for ref '%s': %s;
+
+   transaction_free(t);
+   if (e)
+   strbuf_addf(e, str, refname, err.buf);
+   strbuf_release(err);
+   return 1;
+   }
+   return 0;
+}
 
diff --git a/refs.c b/refs.c
index 4a22513..eb66cf7 100644
--- a/refs.c
+++ b/refs.c
@@ -3576,29 +3576,6 @@ int transaction_delete_sha1(struct ref_transaction 
*transaction,
  old_sha1, flags, have_old, msg, err);
 }
 
-int update_ref(const char *action, const char *refname,
-  const unsigned char *sha1, const unsigned char *oldval,
-  int flags, struct strbuf *e)
-{
-   struct ref_transaction *t;
-   struct strbuf err = STRBUF_INIT;
-
-   t = transaction_begin(err);
-   if (!t ||
-   transaction_update_sha1(t, refname, sha1, oldval, flags,
-   !!oldval, action, err) ||
-   transaction_commit(t, err)) {
-   const char *str = update_ref failed for ref '%s': %s;
-
-   transaction_free(t);
-   if (e)
-   strbuf_addf(e, str, refname, err.buf);
-   strbuf_release(err);
-   return 1;
-   }
-   return 0;
-}
-
 static int ref_update_compare(const void *r1, const void *r2)
 {
const struct ref_update * const *u1 = r1;
-- 
2.0.1.553.geee1b3e

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


[PATCH 06/22] refs-common.c: move read_ref_at to the refs common file

2014-08-08 Thread Ronnie Sahlberg
This change moves read_ref_at() to the refs-common.c file since this function
does not contain any backend specific code.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 114 ++
 refs.c| 114 --
 2 files changed, 114 insertions(+), 114 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index f99d83e..3d7354e 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -135,3 +135,117 @@ int rename_ref(const char *oldrefname, const char 
*newrefname, const char *logms
transaction_free(transaction);
return 1;
 }
+
+struct read_ref_at_cb {
+   const char *refname;
+   unsigned long at_time;
+   int cnt;
+   int reccnt;
+   unsigned char *sha1;
+   int found_it;
+
+   unsigned char osha1[20];
+   unsigned char nsha1[20];
+   int tz;
+   unsigned long date;
+   char **msg;
+   unsigned long *cutoff_time;
+   int *cutoff_tz;
+   int *cutoff_cnt;
+};
+
+static int read_ref_at_ent(unsigned char *osha1, unsigned char *nsha1,
+   const char *id, unsigned long timestamp, int tz,
+   const char *message, void *cb_data)
+{
+   struct read_ref_at_cb *cb = cb_data;
+
+   cb-reccnt++;
+   cb-tz = tz;
+   cb-date = timestamp;
+
+   if (timestamp = cb-at_time || cb-cnt == 0) {
+   if (cb-msg)
+   *cb-msg = xstrdup(message);
+   if (cb-cutoff_time)
+   *cb-cutoff_time = timestamp;
+   if (cb-cutoff_tz)
+   *cb-cutoff_tz = tz;
+   if (cb-cutoff_cnt)
+   *cb-cutoff_cnt = cb-reccnt - 1;
+   /*
+* we have not yet updated cb-[n|o]sha1 so they still
+* hold the values for the previous record.
+*/
+   if (!is_null_sha1(cb-osha1)) {
+   hashcpy(cb-sha1, nsha1);
+   if (hashcmp(cb-osha1, nsha1))
+   warning(Log for ref %s has gap after %s.,
+   cb-refname, show_date(cb-date, 
cb-tz, DATE_RFC2822));
+   }
+   else if (cb-date == cb-at_time)
+   hashcpy(cb-sha1, nsha1);
+   else if (hashcmp(nsha1, cb-sha1))
+   warning(Log for ref %s unexpectedly ended on %s.,
+   cb-refname, show_date(cb-date, cb-tz,
+  DATE_RFC2822));
+   hashcpy(cb-osha1, osha1);
+   hashcpy(cb-nsha1, nsha1);
+   cb-found_it = 1;
+   return 1;
+   }
+   hashcpy(cb-osha1, osha1);
+   hashcpy(cb-nsha1, nsha1);
+   if (cb-cnt  0)
+   cb-cnt--;
+   return 0;
+}
+
+static int read_ref_at_ent_oldest(unsigned char *osha1, unsigned char *nsha1,
+ const char *id, unsigned long timestamp,
+ int tz, const char *message, void *cb_data)
+{
+   struct read_ref_at_cb *cb = cb_data;
+
+   if (cb-msg)
+   *cb-msg = xstrdup(message);
+   if (cb-cutoff_time)
+   *cb-cutoff_time = timestamp;
+   if (cb-cutoff_tz)
+   *cb-cutoff_tz = tz;
+   if (cb-cutoff_cnt)
+   *cb-cutoff_cnt = cb-reccnt;
+   hashcpy(cb-sha1, osha1);
+   if (is_null_sha1(cb-sha1))
+   hashcpy(cb-sha1, nsha1);
+   /* We just want the first entry */
+   return 1;
+}
+
+int read_ref_at(const char *refname, unsigned long at_time, int cnt,
+   unsigned char *sha1, char **msg,
+   unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
+{
+   struct read_ref_at_cb cb;
+
+   memset(cb, 0, sizeof(cb));
+   cb.refname = refname;
+   cb.at_time = at_time;
+   cb.cnt = cnt;
+   cb.msg = msg;
+   cb.cutoff_time = cutoff_time;
+   cb.cutoff_tz = cutoff_tz;
+   cb.cutoff_cnt = cutoff_cnt;
+   cb.sha1 = sha1;
+
+   for_each_reflog_ent_reverse(refname, read_ref_at_ent, cb);
+
+   if (!cb.reccnt)
+   die(Log for %s is empty., refname);
+   if (cb.found_it)
+   return 0;
+
+   for_each_reflog_ent(refname, read_ref_at_ent_oldest, cb);
+
+   return 1;
+}
diff --git a/refs.c b/refs.c
index 7d579be..52ca0bb 100644
--- a/refs.c
+++ b/refs.c
@@ -2935,120 +2935,6 @@ int create_symref(const char *ref_target, const char 
*refs_heads_master,
return 0;
 }
 
-struct read_ref_at_cb {
-   const char *refname;
-   unsigned long at_time;
-   int cnt;
-   int reccnt;
-   unsigned char *sha1;
-   int found_it;
-
-   unsigned char osha1[20];
-   unsigned char nsha1[20];
-   int tz;
-   unsigned long date;
-   char **msg;
-   unsigned long *cutoff_time;
-  

[PATCH 07/22] refs-common.c: move the hidden refs functions to the common code

2014-08-08 Thread Ronnie Sahlberg
This change moves the hidden refs functions to the refs-common.c file since
these functions do not contain any backend specific code.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 44 
 refs.c| 43 ---
 2 files changed, 44 insertions(+), 43 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index 3d7354e..c40fa96 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -1,6 +1,7 @@
 /* common code for all ref backends */
 #include cache.h
 #include refs.h
+#include string-list.h
 
 int update_ref(const char *action, const char *refname,
   const unsigned char *sha1, const unsigned char *oldval,
@@ -249,3 +250,46 @@ int read_ref_at(const char *refname, unsigned long 
at_time, int cnt,
 
return 1;
 }
+
+static struct string_list *hide_refs;
+
+int parse_hide_refs_config(const char *var, const char *value, const char 
*section)
+{
+   if (!strcmp(transfer.hiderefs, var) ||
+   /* NEEDSWORK: use parse_config_key() once both are merged */
+   (starts_with(var, section)  var[strlen(section)] == '.' 
+!strcmp(var + strlen(section), .hiderefs))) {
+   char *ref;
+   int len;
+
+   if (!value)
+   return config_error_nonbool(var);
+   ref = xstrdup(value);
+   len = strlen(ref);
+   while (len  ref[len - 1] == '/')
+   ref[--len] = '\0';
+   if (!hide_refs) {
+   hide_refs = xcalloc(1, sizeof(*hide_refs));
+   hide_refs-strdup_strings = 1;
+   }
+   string_list_append(hide_refs, ref);
+   }
+   return 0;
+}
+
+int ref_is_hidden(const char *refname)
+{
+   struct string_list_item *item;
+
+   if (!hide_refs)
+   return 0;
+   for_each_string_list_item(item, hide_refs) {
+   int len;
+   if (!starts_with(refname, item-string))
+   continue;
+   len = strlen(item-string);
+   if (!refname[len] || refname[len] == '/')
+   return 1;
+   }
+   return 0;
+}
diff --git a/refs.c b/refs.c
index 52ca0bb..6181edf 100644
--- a/refs.c
+++ b/refs.c
@@ -3796,46 +3796,3 @@ char *shorten_unambiguous_ref(const char *refname, int 
strict)
free(short_name);
return xstrdup(refname);
 }
-
-static struct string_list *hide_refs;
-
-int parse_hide_refs_config(const char *var, const char *value, const char 
*section)
-{
-   if (!strcmp(transfer.hiderefs, var) ||
-   /* NEEDSWORK: use parse_config_key() once both are merged */
-   (starts_with(var, section)  var[strlen(section)] == '.' 
-!strcmp(var + strlen(section), .hiderefs))) {
-   char *ref;
-   int len;
-
-   if (!value)
-   return config_error_nonbool(var);
-   ref = xstrdup(value);
-   len = strlen(ref);
-   while (len  ref[len - 1] == '/')
-   ref[--len] = '\0';
-   if (!hide_refs) {
-   hide_refs = xcalloc(1, sizeof(*hide_refs));
-   hide_refs-strdup_strings = 1;
-   }
-   string_list_append(hide_refs, ref);
-   }
-   return 0;
-}
-
-int ref_is_hidden(const char *refname)
-{
-   struct string_list_item *item;
-
-   if (!hide_refs)
-   return 0;
-   for_each_string_list_item(item, hide_refs) {
-   int len;
-   if (!starts_with(refname, item-string))
-   continue;
-   len = strlen(item-string);
-   if (!refname[len] || refname[len] == '/')
-   return 1;
-   }
-   return 0;
-}
-- 
2.0.1.553.geee1b3e

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


[PATCH 00/22] backend-struct-db

2014-08-08 Thread Ronnie Sahlberg
List,

This series is called backend-struct-db and is also available at
https://github.com/rsahlberg/git/tree/backend-struct-db

This series is built on and follows after the series
ref-transactions-send-pack


This series does not change any logic or behaviour but mainly just shuffles
code around and adds method pointers for the backend functions.

The first patch adds a new public function for checking if a refname is
available or not. This function is needed not because we want to have
different is_refname_available semantics for different backends, we don't,
but because its implementation is quite dependant on the backend type.

15 of the patches, the refs-common.c patches, focuses on moving all backend
agnostic refs functions to a common file. This file will contain all
backend agnostic refs functions.

The last 6 patches adds a backend structure with the methods we need to
describe a pluggable backend. Currently we only have one built in backend,
the current files based backend. These patches do not change any of the
behavior other than that we now call the methods through backend specific
wrapper functions rather than calling them directly.


At this stage we now have a defined set of methods needed for a refs
backend and we can start building and adding new types of ref backends
to git.




Ronnie Sahlberg (22):
  refs.c: create a public function for is_refname_available
  refs-common.c: create a file to host all common refs code
  refs-common.c: move update_ref to refs-common.c
  refs-common.c: move delete_ref to the common code
  refs-common.c: move rename_ref to the common code
  refs-common.c: move read_ref_at to the refs common file
  refs-common.c: move the hidden refs functions to the common code
  refs-common.c: move dwim and friend functions to refs common
  refs-common.c: move warn_if_dangling_symref* to refs-common
  refs-common.c: move read_ref, read_ref_full and ref_exists to common
  refs-common.c: move resolve_refdup to common
  refs-common.c: move check_refname_component to the common code
  refs-common.c: move is_branch to the common code
  refs-common.c: move names_conflict to the common code
  refs-common.c: move prettify_refname to the common code
  refs-common.c: move ref iterators to the common code
  refs.c: add a backend method structure with transaction functions
  refs.c: add reflog backend methods
  refs.c: add methods for misc ref operations
  refs.c: add methods for head_ref*
  refs.c: add methods for the ref iterators
  refs-be-files.c: rename refs.c to refs-be-files.c

 Makefile|3 +-
 refs-be-files.c | 3343 +
 refs-common.c   |  956 +
 refs.c  | 4082 ---
 refs.h  |  117 ++
 5 files changed, 4418 insertions(+), 4083 deletions(-)
 create mode 100644 refs-be-files.c
 create mode 100644 refs-common.c
 delete mode 100644 refs.c

-- 
2.0.1.553.geee1b3e

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


[PATCH 09/22] refs-common.c: move warn_if_dangling_symref* to refs-common

2014-08-08 Thread Ronnie Sahlberg
These functions do not use any backend specific code so we can move
them to the common code.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 52 
 refs.c| 52 
 2 files changed, 52 insertions(+), 52 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index ac081e1..ab3a118 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -495,3 +495,55 @@ char *shorten_unambiguous_ref(const char *refname, int 
strict)
free(short_name);
return xstrdup(refname);
 }
+
+struct warn_if_dangling_data {
+   FILE *fp;
+   const char *refname;
+   const struct string_list *refnames;
+   const char *msg_fmt;
+};
+
+static int warn_if_dangling_symref(const char *refname, const unsigned char 
*sha1,
+  int flags, void *cb_data)
+{
+   struct warn_if_dangling_data *d = cb_data;
+   const char *resolves_to;
+   unsigned char junk[20];
+
+   if (!(flags  REF_ISSYMREF))
+   return 0;
+
+   resolves_to = resolve_ref_unsafe(refname, junk, 0, NULL);
+   if (!resolves_to
+   || (d-refname
+   ? strcmp(resolves_to, d-refname)
+   : !string_list_has_string(d-refnames, resolves_to))) {
+   return 0;
+   }
+
+   fprintf(d-fp, d-msg_fmt, refname);
+   fputc('\n', d-fp);
+   return 0;
+}
+
+void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
+{
+   struct warn_if_dangling_data data;
+
+   data.fp = fp;
+   data.refname = refname;
+   data.refnames = NULL;
+   data.msg_fmt = msg_fmt;
+   for_each_rawref(warn_if_dangling_symref, data);
+}
+
+void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct 
string_list *refnames)
+{
+   struct warn_if_dangling_data data;
+
+   data.fp = fp;
+   data.refname = NULL;
+   data.refnames = refnames;
+   data.msg_fmt = msg_fmt;
+   for_each_rawref(warn_if_dangling_symref, data);
+}
diff --git a/refs.c b/refs.c
index 56e146f..40c329b 100644
--- a/refs.c
+++ b/refs.c
@@ -1667,58 +1667,6 @@ int peel_ref(const char *refname, unsigned char *sha1)
return peel_object(base, sha1);
 }
 
-struct warn_if_dangling_data {
-   FILE *fp;
-   const char *refname;
-   const struct string_list *refnames;
-   const char *msg_fmt;
-};
-
-static int warn_if_dangling_symref(const char *refname, const unsigned char 
*sha1,
-  int flags, void *cb_data)
-{
-   struct warn_if_dangling_data *d = cb_data;
-   const char *resolves_to;
-   unsigned char junk[20];
-
-   if (!(flags  REF_ISSYMREF))
-   return 0;
-
-   resolves_to = resolve_ref_unsafe(refname, junk, 0, NULL);
-   if (!resolves_to
-   || (d-refname
-   ? strcmp(resolves_to, d-refname)
-   : !string_list_has_string(d-refnames, resolves_to))) {
-   return 0;
-   }
-
-   fprintf(d-fp, d-msg_fmt, refname);
-   fputc('\n', d-fp);
-   return 0;
-}
-
-void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
-{
-   struct warn_if_dangling_data data;
-
-   data.fp = fp;
-   data.refname = refname;
-   data.refnames = NULL;
-   data.msg_fmt = msg_fmt;
-   for_each_rawref(warn_if_dangling_symref, data);
-}
-
-void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct 
string_list *refnames)
-{
-   struct warn_if_dangling_data data;
-
-   data.fp = fp;
-   data.refname = NULL;
-   data.refnames = refnames;
-   data.msg_fmt = msg_fmt;
-   for_each_rawref(warn_if_dangling_symref, data);
-}
-
 /*
  * Call fn for each reference in the specified ref_cache, omitting
  * references not in the containing_dir of base.  fn is called for all
-- 
2.0.1.553.geee1b3e

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


[PATCH 20/22] refs.c: add methods for head_ref*

2014-08-08 Thread Ronnie Sahlberg
Add methods for the head_ref* functions.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 15 +++
 refs.c| 10 +++---
 refs.h|  8 
 3 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index 45e6fca..d9308a3 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -903,3 +903,18 @@ int resolve_gitlink_ref(const char *path, const char 
*refname,
 {
return refs-resolve_gitlink_ref(path, refname, sha1);
 }
+
+int head_ref(each_ref_fn fn, void *cb_data)
+{
+   return refs-head_ref(fn, cb_data);
+}
+
+int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
+{
+   return refs-head_ref_submodule(submodule, fn, cb_data);
+}
+
+int head_ref_namespaced(each_ref_fn fn, void *cb_data)
+{
+   return refs-head_ref_namespaced(fn, cb_data);
+}
diff --git a/refs.c b/refs.c
index c4076f3..94d6160 100644
--- a/refs.c
+++ b/refs.c
@@ -1600,12 +1600,12 @@ static int do_head_ref(const char *submodule, 
each_ref_fn fn, void *cb_data)
return 0;
 }
 
-int head_ref(each_ref_fn fn, void *cb_data)
+static int files_head_ref(each_ref_fn fn, void *cb_data)
 {
return do_head_ref(NULL, fn, cb_data);
 }
 
-int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
+static int files_head_ref_submodule(const char *submodule, each_ref_fn fn, 
void *cb_data)
 {
return do_head_ref(submodule, fn, cb_data);
 }
@@ -1636,7 +1636,7 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data)
return do_for_each_ref(ref_cache, refs/replace/, fn, 13, 0, cb_data);
 }
 
-int head_ref_namespaced(each_ref_fn fn, void *cb_data)
+static int files_head_ref_namespaced(each_ref_fn fn, void *cb_data)
 {
struct strbuf buf = STRBUF_INIT;
int ret = 0;
@@ -3326,6 +3326,10 @@ struct ref_be refs_files = {
.peel_ref   = files_peel_ref,
.create_symref  = files_create_symref,
.resolve_gitlink_ref= files_resolve_gitlink_ref,
+
+   .head_ref   = files_head_ref,
+   .head_ref_submodule = files_head_ref_submodule,
+   .head_ref_namespaced= files_head_ref_namespaced,
 };
 
 struct ref_be *refs = refs_files;
diff --git a/refs.h b/refs.h
index c56bfcd..b35c406 100644
--- a/refs.h
+++ b/refs.h
@@ -397,6 +397,11 @@ typedef int (*create_symref_fn)(const char *ref_target,
 typedef int (*resolve_gitlink_ref_fn)(const char *path, const char *refname,
  unsigned char *sha1);
 
+typedef int (*head_ref_fn)(each_ref_fn fn, void *cb_data);
+typedef int (*head_ref_submodule_fn)(const char *submodule, each_ref_fn fn,
+void *cb_data);
+typedef int (*head_ref_namespaced_fn)(each_ref_fn fn, void *cb_data);
+
 struct ref_be {
transaction_begin_fn transaction_begin;
transaction_update_sha1_fn transaction_update_sha1;
@@ -420,6 +425,9 @@ struct ref_be {
create_symref_fn create_symref;
resolve_gitlink_ref_fn resolve_gitlink_ref;
 
+   head_ref_fn head_ref;
+   head_ref_submodule_fn head_ref_submodule;
+   head_ref_namespaced_fn head_ref_namespaced;
 };
 
 extern struct ref_be *refs;
-- 
2.0.1.553.geee1b3e

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


[PATCH 11/22] refs-common.c: move resolve_refdup to common

2014-08-08 Thread Ronnie Sahlberg
This function can be shared across all refs backends so move it
to the common code.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 6 ++
 refs.c| 6 --
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index 37d3d14..655a1a0 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -565,3 +565,9 @@ int ref_exists(const char *refname)
unsigned char sha1[20];
return !!resolve_ref_unsafe(refname, sha1, RESOLVE_REF_READING, NULL);
 }
+
+char *resolve_refdup(const char *ref, unsigned char *sha1, int flags, int 
*ref_flag)
+{
+   const char *ret = resolve_ref_unsafe(ref, sha1, flags, ref_flag);
+   return ret ? xstrdup(ret) : NULL;
+}
diff --git a/refs.c b/refs.c
index a94378e..ed7bc61 100644
--- a/refs.c
+++ b/refs.c
@@ -1501,12 +1501,6 @@ const char *resolve_ref_unsafe(const char *refname, 
unsigned char *sha1, int fla
}
 }
 
-char *resolve_refdup(const char *ref, unsigned char *sha1, int flags, int 
*ref_flag)
-{
-   const char *ret = resolve_ref_unsafe(ref, sha1, flags, ref_flag);
-   return ret ? xstrdup(ret) : NULL;
-}
-
 /* The argument to filter_refs */
 struct ref_filter {
const char *pattern;
-- 
2.0.1.553.geee1b3e

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


[PATCH 08/22] refs-common.c: move dwim and friend functions to refs common

2014-08-08 Thread Ronnie Sahlberg
These functions do not contain any backend specific code so we can move
them to the common code and share across all backends.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 202 ++
 refs.c| 202 --
 2 files changed, 202 insertions(+), 202 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index c40fa96..ac081e1 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -293,3 +293,205 @@ int ref_is_hidden(const char *refname)
}
return 0;
 }
+
+static const char *ref_rev_parse_rules[] = {
+   %.*s,
+   refs/%.*s,
+   refs/tags/%.*s,
+   refs/heads/%.*s,
+   refs/remotes/%.*s,
+   refs/remotes/%.*s/HEAD,
+   NULL
+};
+
+int refname_match(const char *abbrev_name, const char *full_name)
+{
+   const char **p;
+   const int abbrev_name_len = strlen(abbrev_name);
+
+   for (p = ref_rev_parse_rules; *p; p++) {
+   if (!strcmp(full_name, mkpath(*p, abbrev_name_len, 
abbrev_name))) {
+   return 1;
+   }
+   }
+
+   return 0;
+}
+
+/*
+ * *string and *len will only be substituted, and *string returned (for
+ * later free()ing) if the string passed in is a magic short-hand form
+ * to name a branch.
+ */
+static char *substitute_branch_name(const char **string, int *len)
+{
+   struct strbuf buf = STRBUF_INIT;
+   int ret = interpret_branch_name(*string, *len, buf);
+
+   if (ret == *len) {
+   size_t size;
+   *string = strbuf_detach(buf, size);
+   *len = size;
+   return (char *)*string;
+   }
+
+   return NULL;
+}
+
+int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
+{
+   char *last_branch = substitute_branch_name(str, len);
+   const char **p, *r;
+   int refs_found = 0;
+
+   *ref = NULL;
+   for (p = ref_rev_parse_rules; *p; p++) {
+   char fullref[PATH_MAX];
+   unsigned char sha1_from_ref[20];
+   unsigned char *this_result;
+   int flag;
+
+   this_result = refs_found ? sha1_from_ref : sha1;
+   mksnpath(fullref, sizeof(fullref), *p, len, str);
+   r = resolve_ref_unsafe(fullref, this_result,
+  RESOLVE_REF_READING, flag);
+   if (r) {
+   if (!refs_found++)
+   *ref = xstrdup(r);
+   if (!warn_ambiguous_refs)
+   break;
+   } else if ((flag  REF_ISSYMREF)  strcmp(fullref, HEAD)) {
+   warning(ignoring dangling symref %s., fullref);
+   } else if ((flag  REF_ISBROKEN)  strchr(fullref, '/')) {
+   warning(ignoring broken ref %s., fullref);
+   }
+   }
+   free(last_branch);
+   return refs_found;
+}
+
+int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
+{
+   char *last_branch = substitute_branch_name(str, len);
+   const char **p;
+   int logs_found = 0;
+
+   *log = NULL;
+   for (p = ref_rev_parse_rules; *p; p++) {
+   unsigned char hash[20];
+   char path[PATH_MAX];
+   const char *ref, *it;
+
+   mksnpath(path, sizeof(path), *p, len, str);
+   ref = resolve_ref_unsafe(path, hash, RESOLVE_REF_READING, NULL);
+   if (!ref)
+   continue;
+   if (reflog_exists(path))
+   it = path;
+   else if (strcmp(ref, path)  reflog_exists(ref))
+   it = ref;
+   else
+   continue;
+   if (!logs_found++) {
+   *log = xstrdup(it);
+   hashcpy(sha1, hash);
+   }
+   if (!warn_ambiguous_refs)
+   break;
+   }
+   free(last_branch);
+   return logs_found;
+}
+
+char *shorten_unambiguous_ref(const char *refname, int strict)
+{
+   int i;
+   static char **scanf_fmts;
+   static int nr_rules;
+   char *short_name;
+
+   if (!nr_rules) {
+   /*
+* Pre-generate scanf formats from ref_rev_parse_rules[].
+* Generate a format suitable for scanf from a
+* ref_rev_parse_rules rule by interpolating %s at the
+* location of the %.*s.
+*/
+   size_t total_len = 0;
+   size_t offset = 0;
+
+   /* the rule list is NULL terminated, count them first */
+   for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++)
+   /* -2 for strlen(%.*s) - strlen(%s); +1 for NUL */
+   total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 
+ 1;
+
+   

[PATCH 18/22] refs.c: add reflog backend methods

2014-08-08 Thread Ronnie Sahlberg
Add methods for the reflog functions.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 32 
 refs.c| 19 +--
 refs.h| 18 ++
 3 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index d4782ad..083964f 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -838,3 +838,35 @@ void transaction_free(struct ref_transaction *transaction)
 {
return refs-transaction_free(transaction);
 }
+
+int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
+   void *cb_data)
+{
+   return refs-for_each_reflog_ent_reverse(refname, fn, cb_data);
+}
+
+int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
+   void *cb_data)
+{
+   return refs-for_each_reflog_ent(refname, fn, cb_data);
+}
+
+int for_each_reflog(each_ref_fn fn, void *cb_data)
+{
+   return refs-for_each_reflog(fn, cb_data);
+}
+
+int reflog_exists(const char *refname)
+{
+   return refs-reflog_exists(refname);
+}
+
+int create_reflog(const char *refname)
+{
+   return refs-create_reflog(refname);
+}
+
+int delete_reflog(const char *refname)
+{
+   return refs-delete_reflog(refname);
+}
diff --git a/refs.c b/refs.c
index bfb42d8..49fd360 100644
--- a/refs.c
+++ b/refs.c
@@ -2266,7 +2266,7 @@ static int copy_msg(char *buf, const char *msg)
 }
 
 /* This function must set a meaningful errno on failure */
-int create_reflog(const char *refname)
+static int files_create_reflog(const char *refname)
 {
int logfd, oflags = O_APPEND | O_WRONLY;
char logfile[PATH_MAX];
@@ -2531,7 +2531,7 @@ int create_symref(const char *ref_target, const char 
*refs_heads_master,
return 0;
 }
 
-int reflog_exists(const char *refname)
+static int files_reflog_exists(const char *refname)
 {
struct stat st;
 
@@ -2539,7 +2539,7 @@ int reflog_exists(const char *refname)
S_ISREG(st.st_mode);
 }
 
-int delete_reflog(const char *refname)
+static int files_delete_reflog(const char *refname)
 {
return remove_path(git_path(logs/%s, refname));
 }
@@ -2583,7 +2583,7 @@ static char *find_beginning_of_line(char *bob, char *scan)
return scan;
 }
 
-int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, 
void *cb_data)
+static int files_for_each_reflog_ent_reverse(const char *refname, 
each_reflog_ent_fn fn, void *cb_data)
 {
struct strbuf sb = STRBUF_INIT;
FILE *logfp;
@@ -2660,7 +2660,7 @@ int for_each_reflog_ent_reverse(const char *refname, 
each_reflog_ent_fn fn, void
return ret;
 }
 
-int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void 
*cb_data)
+static int files_for_each_reflog_ent(const char *refname, each_reflog_ent_fn 
fn, void *cb_data)
 {
FILE *logfp;
struct strbuf sb = STRBUF_INIT;
@@ -2721,7 +2721,7 @@ static int do_for_each_reflog(struct strbuf *name, 
each_ref_fn fn, void *cb_data
return retval;
 }
 
-int for_each_reflog(each_ref_fn fn, void *cb_data)
+static int files_for_each_reflog(each_ref_fn fn, void *cb_data)
 {
int retval;
struct strbuf name;
@@ -3310,6 +3310,13 @@ struct ref_be refs_files = {
.transaction_update_reflog  = files_transaction_update_reflog,
.transaction_commit = files_transaction_commit,
.transaction_free   = files_transaction_free,
+
+   .for_each_reflog_ent= files_for_each_reflog_ent,
+   .for_each_reflog_ent_reverse= files_for_each_reflog_ent_reverse,
+   .for_each_reflog= files_for_each_reflog,
+   .reflog_exists  = files_reflog_exists,
+   .create_reflog  = files_create_reflog,
+   .delete_reflog  = files_delete_reflog,
 };
 
 struct ref_be *refs = refs_files;
diff --git a/refs.h b/refs.h
index 7b92241..f630e20 100644
--- a/refs.h
+++ b/refs.h
@@ -373,6 +373,17 @@ typedef int (*transaction_commit_fn)(struct 
ref_transaction *transaction,
   struct strbuf *err);
 typedef void (*transaction_free_fn)(struct ref_transaction *transaction);
 
+typedef int (*for_each_reflog_ent_fn)(const char *refname,
+ each_reflog_ent_fn fn,
+ void *cb_data);
+typedef int (*for_each_reflog_ent_reverse_fn)(const char *refname,
+ each_reflog_ent_fn fn,
+ void *cb_data);
+typedef int (*for_each_reflog_fn)(each_ref_fn fn, void *cb_data);
+typedef int (*reflog_exists_fn)(const char *refname);
+typedef int (*create_reflog_fn)(const char *refname);
+typedef int (*delete_reflog_fn)(const char *refname);
+
 struct ref_be {
transaction_begin_fn transaction_begin;
transaction_update_sha1_fn transaction_update_sha1;
@@ 

[PATCH 17/22] refs.c: add a backend method structure with transaction functions

2014-08-08 Thread Ronnie Sahlberg
Add a ref structure for backend methods. Start by adding method pointers
for the transaction functions.

Rename the existing transaction functions to files_* and make them static.
Add new transaction functions that just pass through to the appropriate
methods for the backend.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 54 +++
 refs.c| 68 +++
 refs.h| 35 ++
 3 files changed, 130 insertions(+), 27 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index 3b20db3..d4782ad 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -784,3 +784,57 @@ int check_refname_format(const char *refname, int flags)
return -1; /* Refname has only one component. */
return 0;
 }
+
+/* backend functions */
+struct ref_transaction *transaction_begin(struct strbuf *err)
+{
+   return refs-transaction_begin(err);
+}
+
+int transaction_update_sha1(struct ref_transaction *transaction,
+   const char *refname, const unsigned char *new_sha1,
+   const unsigned char *old_sha1, int flags,
+   int have_old, const char *msg, struct strbuf *err)
+{
+   return refs-transaction_update_sha1(transaction, refname, new_sha1,
+old_sha1, flags, have_old, msg,
+err);
+}
+
+int transaction_create_sha1(struct ref_transaction *transaction,
+   const char *refname, const unsigned char *new_sha1,
+   int flags, const char *msg, struct strbuf *err)
+{
+   return refs-transaction_create_sha1(transaction, refname, new_sha1,
+flags, msg, err);
+}
+int transaction_delete_sha1(struct ref_transaction *transaction,
+   const char *refname, const unsigned char *old_sha1,
+   int flags, int have_old, const char *msg,
+   struct strbuf *err)
+{
+   return refs-transaction_delete_sha1(transaction, refname, old_sha1,
+flags, have_old, msg, err);
+}
+
+int transaction_update_reflog(struct ref_transaction *transaction,
+ const char *refname,
+ const unsigned char *new_sha1,
+ const unsigned char *old_sha1,
+ struct reflog_committer_info *ci,
+ const char *msg, int flags,
+ struct strbuf *err)
+{
+   return refs-transaction_update_reflog(transaction, refname, new_sha1,
+  old_sha1, ci, msg, flags, err);
+}
+
+int transaction_commit(struct ref_transaction *transaction, struct strbuf *err)
+{
+   return refs-transaction_commit(transaction, err);
+}
+
+void transaction_free(struct ref_transaction *transaction)
+{
+   return refs-transaction_free(transaction);
+}
diff --git a/refs.c b/refs.c
index 9aa88ef..bfb42d8 100644
--- a/refs.c
+++ b/refs.c
@@ -2792,12 +2792,12 @@ struct ref_transaction {
enum ref_transaction_state state;
 };
 
-struct ref_transaction *transaction_begin(struct strbuf *err)
+static struct ref_transaction *files_transaction_begin(struct strbuf *err)
 {
return xcalloc(1, sizeof(struct ref_transaction));
 }
 
-void transaction_free(struct ref_transaction *transaction)
+static void files_transaction_free(struct ref_transaction *transaction)
 {
int i;
 
@@ -2827,13 +2827,13 @@ static struct ref_update *add_update(struct 
ref_transaction *transaction,
return update;
 }
 
-int transaction_update_reflog(struct ref_transaction *transaction,
- const char *refname,
- const unsigned char *new_sha1,
- const unsigned char *old_sha1,
- struct reflog_committer_info *ci,
- const char *msg, int flags,
- struct strbuf *err)
+static int files_transaction_update_reflog(struct ref_transaction *transaction,
+  const char *refname,
+  const unsigned char *new_sha1,
+  const unsigned char *old_sha1,
+  struct reflog_committer_info *ci,
+  const char *msg, int flags,
+  struct strbuf *err)
 {
struct ref_update *update;
int i;
@@ -2880,12 +2880,13 @@ int transaction_update_reflog(struct ref_transaction 
*transaction,
return 0;
 }
 
-int transaction_update_sha1(struct ref_transaction *transaction,
-   const 

[PATCH 13/22] refs-common.c: move is_branch to the common code

2014-08-08 Thread Ronnie Sahlberg
Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 5 +
 refs.c| 5 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index f8b79e0..5f83d7e 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -3,6 +3,11 @@
 #include refs.h
 #include string-list.h
 
+int is_branch(const char *refname)
+{
+   return !strcmp(refname, HEAD) || starts_with(refname, refs/heads/);
+}
+
 int update_ref(const char *action, const char *refname,
   const unsigned char *sha1, const unsigned char *oldval,
   int flags, struct strbuf *e)
diff --git a/refs.c b/refs.c
index 55bced9..70c034c 100644
--- a/refs.c
+++ b/refs.c
@@ -2483,11 +2483,6 @@ static int log_ref_write(const char *refname, const 
unsigned char *old_sha1,
return 0;
 }
 
-int is_branch(const char *refname)
-{
-   return !strcmp(refname, HEAD) || starts_with(refname, refs/heads/);
-}
-
 static int write_sha1_update_reflog(struct ref_lock *lock,
const unsigned char *sha1, const char *logmsg)
 {
-- 
2.0.1.553.geee1b3e

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


[PATCH 16/22] refs-common.c: move ref iterators to the common code

2014-08-08 Thread Ronnie Sahlberg
Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 81 +++
 refs.c| 81 ---
 2 files changed, 81 insertions(+), 81 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index d8a295c..3b20db3 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -668,6 +668,87 @@ out:
return cp - refname;
 }
 
+/* The argument to filter_refs */
+struct ref_filter {
+   const char *pattern;
+   each_ref_fn *fn;
+   void *cb_data;
+};
+
+static int filter_refs(const char *refname, const unsigned char *sha1, int 
flags,
+  void *data)
+{
+   struct ref_filter *filter = (struct ref_filter *)data;
+   if (wildmatch(filter-pattern, refname, 0, NULL))
+   return 0;
+   return filter-fn(refname, sha1, flags, filter-cb_data);
+}
+
+int for_each_tag_ref(each_ref_fn fn, void *cb_data)
+{
+   return for_each_ref_in(refs/tags/, fn, cb_data);
+}
+
+int for_each_tag_ref_submodule(const char *submodule, each_ref_fn fn, void 
*cb_data)
+{
+   return for_each_ref_in_submodule(submodule, refs/tags/, fn, cb_data);
+}
+
+int for_each_branch_ref(each_ref_fn fn, void *cb_data)
+{
+   return for_each_ref_in(refs/heads/, fn, cb_data);
+}
+
+int for_each_branch_ref_submodule(const char *submodule, each_ref_fn fn, void 
*cb_data)
+{
+   return for_each_ref_in_submodule(submodule, refs/heads/, fn, cb_data);
+}
+
+int for_each_remote_ref(each_ref_fn fn, void *cb_data)
+{
+   return for_each_ref_in(refs/remotes/, fn, cb_data);
+}
+
+int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void 
*cb_data)
+{
+   return for_each_ref_in_submodule(submodule, refs/remotes/, fn, 
cb_data);
+}
+
+int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
+   const char *prefix, void *cb_data)
+{
+   struct strbuf real_pattern = STRBUF_INIT;
+   struct ref_filter filter;
+   int ret;
+
+   if (!prefix  !starts_with(pattern, refs/))
+   strbuf_addstr(real_pattern, refs/);
+   else if (prefix)
+   strbuf_addstr(real_pattern, prefix);
+   strbuf_addstr(real_pattern, pattern);
+
+   if (!has_glob_specials(pattern)) {
+   /* Append implied '/' '*' if not present. */
+   if (real_pattern.buf[real_pattern.len - 1] != '/')
+   strbuf_addch(real_pattern, '/');
+   /* No need to check for '*', there is none. */
+   strbuf_addch(real_pattern, '*');
+   }
+
+   filter.pattern = real_pattern.buf;
+   filter.fn = fn;
+   filter.cb_data = cb_data;
+   ret = for_each_ref(filter_refs, filter);
+
+   strbuf_release(real_pattern);
+   return ret;
+}
+
+int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
+{
+   return for_each_glob_ref_in(fn, pattern, NULL, cb_data);
+}
+
 int check_refname_format(const char *refname, int flags)
 {
int component_len, component_count = 0;
diff --git a/refs.c b/refs.c
index fb9c614..9aa88ef 100644
--- a/refs.c
+++ b/refs.c
@@ -1377,22 +1377,6 @@ const char *resolve_ref_unsafe(const char *refname, 
unsigned char *sha1, int fla
}
 }
 
-/* The argument to filter_refs */
-struct ref_filter {
-   const char *pattern;
-   each_ref_fn *fn;
-   void *cb_data;
-};
-
-static int filter_refs(const char *refname, const unsigned char *sha1, int 
flags,
-  void *data)
-{
-   struct ref_filter *filter = (struct ref_filter *)data;
-   if (wildmatch(filter-pattern, refname, 0, NULL))
-   return 0;
-   return filter-fn(refname, sha1, flags, filter-cb_data);
-}
-
 enum peel_status {
/* object was peeled successfully: */
PEEL_PEELED = 0,
@@ -1646,36 +1630,6 @@ int for_each_ref_in_submodule(const char *submodule, 
const char *prefix,
return do_for_each_ref(get_ref_cache(submodule), prefix, fn, 
strlen(prefix), 0, cb_data);
 }
 
-int for_each_tag_ref(each_ref_fn fn, void *cb_data)
-{
-   return for_each_ref_in(refs/tags/, fn, cb_data);
-}
-
-int for_each_tag_ref_submodule(const char *submodule, each_ref_fn fn, void 
*cb_data)
-{
-   return for_each_ref_in_submodule(submodule, refs/tags/, fn, cb_data);
-}
-
-int for_each_branch_ref(each_ref_fn fn, void *cb_data)
-{
-   return for_each_ref_in(refs/heads/, fn, cb_data);
-}
-
-int for_each_branch_ref_submodule(const char *submodule, each_ref_fn fn, void 
*cb_data)
-{
-   return for_each_ref_in_submodule(submodule, refs/heads/, fn, cb_data);
-}
-
-int for_each_remote_ref(each_ref_fn fn, void *cb_data)
-{
-   return for_each_ref_in(refs/remotes/, fn, cb_data);
-}
-
-int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void 
*cb_data)
-{
-   return for_each_ref_in_submodule(submodule, refs/remotes/, fn, 
cb_data);
-}
-
 int for_each_replace_ref(each_ref_fn fn, void 

[PATCH 21/22] refs.c: add methods for the ref iterators

2014-08-08 Thread Ronnie Sahlberg
Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 36 
 refs.c| 22 +++---
 refs.h| 20 
 3 files changed, 71 insertions(+), 7 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index d9308a3..11c3660 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -918,3 +918,39 @@ int head_ref_namespaced(each_ref_fn fn, void *cb_data)
 {
return refs-head_ref_namespaced(fn, cb_data);
 }
+ 
+int for_each_ref(each_ref_fn fn, void *cb_data)
+{
+   return refs-for_each_ref(fn, cb_data);
+}
+
+int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void 
*cb_data)
+{
+   return refs-for_each_ref_submodule(submodule, fn, cb_data);
+}
+
+int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
+{
+   return refs-for_each_ref_in(prefix, fn, cb_data);
+}
+
+int for_each_ref_in_submodule(const char *submodule, const char *prefix,
+ each_ref_fn fn, void *cb_data)
+{
+   return refs-for_each_ref_in_submodule(submodule, prefix, fn, cb_data);
+}
+
+int for_each_rawref(each_ref_fn fn, void *cb_data)
+{
+   return refs-for_each_rawref(fn, cb_data);
+}
+
+int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
+{
+   return refs-for_each_namespaced_ref(fn, cb_data);
+}
+
+int for_each_replace_ref(each_ref_fn fn, void *cb_data)
+{
+   return refs-for_each_replace_ref(fn, cb_data);
+}
diff --git a/refs.c b/refs.c
index 94d6160..1b2272d 100644
--- a/refs.c
+++ b/refs.c
@@ -1610,28 +1610,28 @@ static int files_head_ref_submodule(const char 
*submodule, each_ref_fn fn, void
return do_head_ref(submodule, fn, cb_data);
 }
 
-int for_each_ref(each_ref_fn fn, void *cb_data)
+static int files_for_each_ref(each_ref_fn fn, void *cb_data)
 {
return do_for_each_ref(ref_cache, , fn, 0, 0, cb_data);
 }
 
-int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void 
*cb_data)
+static int files_for_each_ref_submodule(const char *submodule, each_ref_fn fn, 
void *cb_data)
 {
return do_for_each_ref(get_ref_cache(submodule), , fn, 0, 0, cb_data);
 }
 
-int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
+static int files_for_each_ref_in(const char *prefix, each_ref_fn fn, void 
*cb_data)
 {
return do_for_each_ref(ref_cache, prefix, fn, strlen(prefix), 0, 
cb_data);
 }
 
-int for_each_ref_in_submodule(const char *submodule, const char *prefix,
+static int files_for_each_ref_in_submodule(const char *submodule, const char 
*prefix,
each_ref_fn fn, void *cb_data)
 {
return do_for_each_ref(get_ref_cache(submodule), prefix, fn, 
strlen(prefix), 0, cb_data);
 }
 
-int for_each_replace_ref(each_ref_fn fn, void *cb_data)
+static int files_for_each_replace_ref(each_ref_fn fn, void *cb_data)
 {
return do_for_each_ref(ref_cache, refs/replace/, fn, 13, 0, cb_data);
 }
@@ -1651,7 +1651,7 @@ static int files_head_ref_namespaced(each_ref_fn fn, void 
*cb_data)
return ret;
 }
 
-int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
+static int files_for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
 {
struct strbuf buf = STRBUF_INIT;
int ret;
@@ -1661,7 +1661,7 @@ int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
return ret;
 }
 
-int for_each_rawref(each_ref_fn fn, void *cb_data)
+static int files_for_each_rawref(each_ref_fn fn, void *cb_data)
 {
return do_for_each_ref(ref_cache, , fn, 0,
   DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
@@ -3330,6 +3330,14 @@ struct ref_be refs_files = {
.head_ref   = files_head_ref,
.head_ref_submodule = files_head_ref_submodule,
.head_ref_namespaced= files_head_ref_namespaced,
+
+   .for_each_ref   = files_for_each_ref,
+   .for_each_ref_submodule = files_for_each_ref_submodule,
+   .for_each_ref_in= files_for_each_ref_in,
+   .for_each_ref_in_submodule  = files_for_each_ref_in_submodule,
+   .for_each_rawref= files_for_each_rawref,
+   .for_each_namespaced_ref= files_for_each_namespaced_ref,
+   .for_each_replace_ref   = files_for_each_replace_ref,
 };
 
 struct ref_be *refs = refs_files;
diff --git a/refs.h b/refs.h
index b35c406..61b6728 100644
--- a/refs.h
+++ b/refs.h
@@ -402,6 +402,18 @@ typedef int (*head_ref_submodule_fn)(const char 
*submodule, each_ref_fn fn,
 void *cb_data);
 typedef int (*head_ref_namespaced_fn)(each_ref_fn fn, void *cb_data);
 
+typedef int (*for_each_ref_fn)(each_ref_fn fn, void *cb_data);
+typedef int (*for_each_ref_submodule_fn)(const char *submodule, each_ref_fn fn,
+void *cb_data);
+typedef int (*for_each_ref_in_fn)(const char *prefix, each_ref_fn fn,
+ void 

[PATCH 12/22] refs-common.c: move check_refname_component to the common code

2014-08-08 Thread Ronnie Sahlberg
This function does not contain any backend specific code so we
can move it to the common code.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 110 ++
 refs.c| 110 --
 2 files changed, 110 insertions(+), 110 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index 655a1a0..f8b79e0 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -571,3 +571,113 @@ char *resolve_refdup(const char *ref, unsigned char 
*sha1, int flags, int *ref_f
const char *ret = resolve_ref_unsafe(ref, sha1, flags, ref_flag);
return ret ? xstrdup(ret) : NULL;
 }
+
+/*
+ * How to handle various characters in refnames:
+ * 0: An acceptable character for refs
+ * 1: End-of-component
+ * 2: ., look for a preceding . to reject .. in refs
+ * 3: {, look for a preceding @ to reject @{ in refs
+ * 4: A bad character: ASCII control characters, ~, ^, : or SP
+ */
+static unsigned char refname_disposition[256] = {
+   1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+   4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+   4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 1,
+   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4,
+   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 0,
+   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4
+};
+
+/*
+ * Try to read one refname component from the front of refname.
+ * Return the length of the component found, or -1 if the component is
+ * not legal.  It is legal if it is something reasonable to have under
+ * .git/refs/; We do not like it if:
+ *
+ * - any path component of it begins with ., or
+ * - it has double dots .., or
+ * - it has ASCII control character, ~, ^, : or SP, anywhere, or
+ * - it ends with a /.
+ * - it ends with .lock
+ * - it contains a \ (backslash)
+ */
+static int check_refname_component(const char *refname, int flags)
+{
+   const char *cp;
+   char last = '\0';
+
+   for (cp = refname; ; cp++) {
+   int ch = *cp  255;
+   unsigned char disp = refname_disposition[ch];
+   switch (disp) {
+   case 1:
+   goto out;
+   case 2:
+   if (last == '.')
+   return -1; /* Refname contains ... */
+   break;
+   case 3:
+   if (last == '@')
+   return -1; /* Refname contains @{. */
+   break;
+   case 4:
+   return -1;
+   }
+   last = ch;
+   }
+out:
+   if (cp == refname)
+   return 0; /* Component has zero length. */
+   if (refname[0] == '.') {
+   if (!(flags  REFNAME_DOT_COMPONENT))
+   return -1; /* Component starts with '.'. */
+   /*
+* Even if leading dots are allowed, don't allow .
+* as a component (.. is prevented by a rule above).
+*/
+   if (refname[1] == '\0')
+   return -1; /* Component equals .. */
+   }
+   if (cp - refname = 5  !memcmp(cp - 5, .lock, 5))
+   return -1; /* Refname ends with .lock. */
+   return cp - refname;
+}
+
+int check_refname_format(const char *refname, int flags)
+{
+   int component_len, component_count = 0;
+
+   if (!strcmp(refname, @))
+   /* Refname is a single character '@'. */
+   return -1;
+
+   while (1) {
+   /* We are at the start of a path component. */
+   component_len = check_refname_component(refname, flags);
+   if (component_len = 0) {
+   if ((flags  REFNAME_REFSPEC_PATTERN) 
+   refname[0] == '*' 
+   (refname[1] == '\0' || refname[1] == 
'/')) {
+   /* Accept one wildcard as a full refname 
component. */
+   flags = ~REFNAME_REFSPEC_PATTERN;
+   component_len = 1;
+   } else {
+   return -1;
+   }
+   }
+   component_count++;
+   if (refname[component_len] == '\0')
+   break;
+   /* Skip to next component. */
+   refname += component_len + 1;
+   }
+
+   if (refname[component_len - 1] == '.')
+   return -1; /* Refname ends with '.'. */
+   if (!(flags  REFNAME_ALLOW_ONELEVEL)  component_count  2)
+   return -1; /* Refname has only one component. */
+   return 0;
+}
diff --git a/refs.c b/refs.c
index ed7bc61..55bced9 100644
--- a/refs.c
+++ b/refs.c
@@ -6,25 

[PATCH 15/22] refs-common.c: move prettify_refname to the common code

2014-08-08 Thread Ronnie Sahlberg
Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 9 +
 refs.c| 9 -
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index 6eef80b..d8a295c 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -3,6 +3,15 @@
 #include refs.h
 #include string-list.h
 
+const char *prettify_refname(const char *name)
+{
+   return name + (
+   starts_with(name, refs/heads/) ? 11 :
+   starts_with(name, refs/tags/) ? 10 :
+   starts_with(name, refs/remotes/) ? 13 :
+   0);
+}
+
 int names_conflict(const char *refname1, const char *refname2)
 {
for (; *refname1  *refname1 == *refname2; refname1++, refname2++)
diff --git a/refs.c b/refs.c
index 6542969..fb9c614 100644
--- a/refs.c
+++ b/refs.c
@@ -1747,15 +1747,6 @@ int for_each_rawref(each_ref_fn fn, void *cb_data)
   DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
 }
 
-const char *prettify_refname(const char *name)
-{
-   return name + (
-   starts_with(name, refs/heads/) ? 11 :
-   starts_with(name, refs/tags/) ? 10 :
-   starts_with(name, refs/remotes/) ? 13 :
-   0);
-}
-
 static void unlock_ref(struct ref_lock *lock)
 {
/* Do not free lock-lk -- atexit() still looks at them */
-- 
2.0.1.553.geee1b3e

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


[PATCH 10/22] refs-common.c: move read_ref, read_ref_full and ref_exists to common

2014-08-08 Thread Ronnie Sahlberg
These functions do not depend on the backend implementation so we
can move them to the common code.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 18 ++
 refs.c| 18 --
 2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index ab3a118..37d3d14 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -547,3 +547,21 @@ void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, 
const struct string_li
data.msg_fmt = msg_fmt;
for_each_rawref(warn_if_dangling_symref, data);
 }
+
+int read_ref_full(const char *refname, unsigned char *sha1, int flags, int 
*ref_flag)
+{
+   if (resolve_ref_unsafe(refname, sha1, flags, ref_flag))
+   return 0;
+   return -1;
+}
+
+int read_ref(const char *refname, unsigned char *sha1)
+{
+   return read_ref_full(refname, sha1, RESOLVE_REF_READING, NULL);
+}
+
+int ref_exists(const char *refname)
+{
+   unsigned char sha1[20];
+   return !!resolve_ref_unsafe(refname, sha1, RESOLVE_REF_READING, NULL);
+}
diff --git a/refs.c b/refs.c
index 40c329b..a94378e 100644
--- a/refs.c
+++ b/refs.c
@@ -1514,24 +1514,6 @@ struct ref_filter {
void *cb_data;
 };
 
-int read_ref_full(const char *refname, unsigned char *sha1, int flags, int 
*ref_flag)
-{
-   if (resolve_ref_unsafe(refname, sha1, flags, ref_flag))
-   return 0;
-   return -1;
-}
-
-int read_ref(const char *refname, unsigned char *sha1)
-{
-   return read_ref_full(refname, sha1, RESOLVE_REF_READING, NULL);
-}
-
-int ref_exists(const char *refname)
-{
-   unsigned char sha1[20];
-   return !!resolve_ref_unsafe(refname, sha1, RESOLVE_REF_READING, NULL);
-}
-
 static int filter_refs(const char *refname, const unsigned char *sha1, int 
flags,
   void *data)
 {
-- 
2.0.1.553.geee1b3e

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


[PATCH 14/22] refs-common.c: move names_conflict to the common code

2014-08-08 Thread Ronnie Sahlberg
Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c |  8 
 refs.c| 14 --
 refs.h|  9 +
 3 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index 5f83d7e..6eef80b 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -3,6 +3,14 @@
 #include refs.h
 #include string-list.h
 
+int names_conflict(const char *refname1, const char *refname2)
+{
+   for (; *refname1  *refname1 == *refname2; refname1++, refname2++)
+   ;
+   return (*refname1 == '\0'  *refname2 == '/')
+   || (*refname1 == '/'  *refname2 == '\0');
+}
+
 int is_branch(const char *refname)
 {
return !strcmp(refname, HEAD) || starts_with(refname, refs/heads/);
diff --git a/refs.c b/refs.c
index 70c034c..6542969 100644
--- a/refs.c
+++ b/refs.c
@@ -676,20 +676,6 @@ static void prime_ref_dir(struct ref_dir *dir)
prime_ref_dir(get_ref_dir(entry));
}
 }
-/*
- * Return true iff refname1 and refname2 conflict with each other.
- * Two reference names conflict if one of them exactly matches the
- * leading components of the other; e.g., foo/bar conflicts with
- * both foo and with foo/bar/baz but not with foo/bar or
- * foo/barbados.
- */
-static int names_conflict(const char *refname1, const char *refname2)
-{
-   for (; *refname1  *refname1 == *refname2; refname1++, refname2++)
-   ;
-   return (*refname1 == '\0'  *refname2 == '/')
-   || (*refname1 == '/'  *refname2 == '\0');
-}
 
 struct name_conflict_cb {
const char *refname;
diff --git a/refs.h b/refs.h
index 7b59044..5577824 100644
--- a/refs.h
+++ b/refs.h
@@ -128,6 +128,15 @@ int pack_refs(unsigned int flags, struct strbuf *err);
 
 extern int ref_exists(const char *);
 
+/*
+ * Return true iff refname1 and refname2 conflict with each other.
+ * Two reference names conflict if one of them exactly matches the
+ * leading components of the other; e.g., foo/bar conflicts with
+ * both foo and with foo/bar/baz but not with foo/bar or
+ * foo/barbados.
+ */
+int names_conflict(const char *refname1, const char *refname2);
+
 extern int is_branch(const char *refname);
 
 /*
-- 
2.0.1.553.geee1b3e

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


[PATCH 02/22] refs-common.c: create a file to host all common refs code

2014-08-08 Thread Ronnie Sahlberg
Create refs-common.c which will hold all backend agnostic refs code.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 Makefile  | 1 +
 refs-common.c | 2 ++
 2 files changed, 3 insertions(+)
 create mode 100644 refs-common.c

diff --git a/Makefile b/Makefile
index 07ea105..7705136 100644
--- a/Makefile
+++ b/Makefile
@@ -858,6 +858,7 @@ LIB_OBJS += reachable.o
 LIB_OBJS += read-cache.o
 LIB_OBJS += reflog-walk.o
 LIB_OBJS += refs.o
+LIB_OBJS += refs-common.o
 LIB_OBJS += remote.o
 LIB_OBJS += replace_object.o
 LIB_OBJS += rerere.o
diff --git a/refs-common.c b/refs-common.c
new file mode 100644
index 000..44d96d2
--- /dev/null
+++ b/refs-common.c
@@ -0,0 +1,2 @@
+/* common code for all ref backends */
+
-- 
2.0.1.553.geee1b3e

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


[PATCH 19/22] refs.c: add methods for misc ref operations

2014-08-08 Thread Ronnie Sahlberg
Add ref backend methods for
resolve_ref_unsafe_fn resolve_ref_unsafe;
is_refname_available_fn is_refname_available;
pack_refs_fn pack_refs;
peel_ref_fn peel_ref;
create_symref_fn create_symref;
resolve_gitlink_ref_fn resolve_gitlink_ref;

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 33 +
 refs.c| 23 ---
 refs.h| 21 +
 3 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index 083964f..45e6fca 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -870,3 +870,36 @@ int delete_reflog(const char *refname)
 {
return refs-delete_reflog(refname);
 }
+
+const char *resolve_ref_unsafe(const char *ref, unsigned char *sha1,
+  int reading, int *flag)
+{
+   return refs-resolve_ref_unsafe(ref, sha1, reading, flag);
+}
+
+int is_refname_available(const char *refname, const char **skip, int skipnum)
+{
+   return refs-is_refname_available(refname, skip, skipnum);
+}
+
+int pack_refs(unsigned int flags, struct strbuf *err)
+{
+   return refs-pack_refs(flags, err);
+}
+
+int peel_ref(const char *refname, unsigned char *sha1)
+{
+   return refs-peel_ref(refname, sha1);
+}
+
+int create_symref(const char *ref_target, const char *refs_heads_master,
+ const char *logmsg)
+{
+   return refs-create_symref(ref_target, refs_heads_master, logmsg);
+}
+
+int resolve_gitlink_ref(const char *path, const char *refname,
+   unsigned char *sha1)
+{
+   return refs-resolve_gitlink_ref(path, refname, sha1);
+}
diff --git a/refs.c b/refs.c
index 49fd360..c4076f3 100644
--- a/refs.c
+++ b/refs.c
@@ -1114,7 +1114,8 @@ static struct ref_dir *get_loose_refs(struct ref_cache 
*refs)
return get_ref_dir(refs-loose);
 }
 
-int is_refname_available(const char *refname, const char **skip, int skipnum)
+static int files_is_refname_available(const char *refname, const char **skip,
+ int skipnum)
 {
if (!is_refname_available_dir(refname, get_packed_refs(ref_cache),
  skip, skipnum))
@@ -1188,7 +1189,7 @@ static int resolve_gitlink_ref_recursive(struct ref_cache 
*refs,
return resolve_gitlink_ref_recursive(refs, p, sha1, recursion+1);
 }
 
-int resolve_gitlink_ref(const char *path, const char *refname, unsigned char 
*sha1)
+static int files_resolve_gitlink_ref(const char *path, const char *refname, 
unsigned char *sha1)
 {
int len = strlen(path), retval;
char *submodule;
@@ -1247,7 +1248,7 @@ static const char *handle_missing_loose_ref(const char 
*refname,
 }
 
 /* This function needs to return a meaningful errno on failure */
-const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int 
flags, int *ref_flag)
+static const char *files_resolve_ref_unsafe(const char *refname, unsigned char 
*sha1, int flags, int *ref_flag)
 {
int depth = MAXDEPTH;
ssize_t len;
@@ -1466,7 +1467,7 @@ static enum peel_status peel_entry(struct ref_entry 
*entry, int repeel)
return status;
 }
 
-int peel_ref(const char *refname, unsigned char *sha1)
+static int files_peel_ref(const char *refname, unsigned char *sha1)
 {
int flag;
unsigned char base[20];
@@ -2095,7 +2096,7 @@ static void prune_refs(struct ref_to_prune *r)
}
 }
 
-int pack_refs(unsigned int flags, struct strbuf *err)
+static int files_pack_refs(unsigned int flags, struct strbuf *err)
 {
struct pack_refs_cb_data cbdata;
 
@@ -2468,8 +2469,9 @@ static int write_ref_sha1(struct ref_lock *lock,
return 0;
 }
 
-int create_symref(const char *ref_target, const char *refs_heads_master,
- const char *logmsg)
+static int files_create_symref(const char *ref_target,
+  const char *refs_heads_master,
+  const char *logmsg)
 {
const char *lockpath;
char ref[1000];
@@ -3317,6 +3319,13 @@ struct ref_be refs_files = {
.reflog_exists  = files_reflog_exists,
.create_reflog  = files_create_reflog,
.delete_reflog  = files_delete_reflog,
+
+   .resolve_ref_unsafe = files_resolve_ref_unsafe,
+   .is_refname_available   = files_is_refname_available,
+   .pack_refs  = files_pack_refs,
+   .peel_ref   = files_peel_ref,
+   .create_symref  = files_create_symref,
+   .resolve_gitlink_ref= files_resolve_gitlink_ref,
 };
 
 struct ref_be *refs = refs_files;
diff --git a/refs.h b/refs.h
index f630e20..c56bfcd 100644
--- a/refs.h
+++ b/refs.h
@@ -384,6 +384,19 @@ typedef int (*reflog_exists_fn)(const char *refname);
 typedef int (*create_reflog_fn)(const char *refname);
 typedef int 

[PATCH 05/22] refs-common.c: move rename_ref to the common code

2014-08-08 Thread Ronnie Sahlberg
This change moves rename_ref() to the refs-common.c file since this function
does not contain any backend specific code.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 92 +++
 refs.c| 92 ---
 2 files changed, 92 insertions(+), 92 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index 71ad358..f99d83e 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -43,3 +43,95 @@ int delete_ref(const char *refname, const unsigned char 
*sha1, int delopt)
transaction_free(transaction);
return 0;
 }
+
+struct rename_reflog_cb {
+   struct ref_transaction *transaction;
+   const char *refname;
+   struct strbuf *err;
+};
+
+static int rename_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
+const char *id, unsigned long timestamp, int tz,
+const char *message, void *cb_data)
+{
+   struct rename_reflog_cb *cb = cb_data;
+   struct reflog_committer_info ci;
+
+   memset(ci, 0, sizeof(ci));
+   ci.id = id;
+   ci.timestamp = timestamp;
+   ci.tz = tz;
+   return transaction_update_reflog(cb-transaction, cb-refname,
+nsha1, osha1, ci, message, 0,
+cb-err);
+}
+
+int rename_ref(const char *oldrefname, const char *newrefname, const char 
*logmsg)
+{
+   unsigned char sha1[20];
+   int flag = 0, log;
+   struct ref_transaction *transaction = NULL;
+   struct strbuf err = STRBUF_INIT;
+   const char *symref = NULL;
+   struct rename_reflog_cb cb;
+   struct reflog_committer_info ci;
+
+   memset(ci, 0, sizeof(ci));
+   ci.committer_info = git_committer_info(0);
+
+   symref = resolve_ref_unsafe(oldrefname, sha1,
+   RESOLVE_REF_READING, flag);
+   if (flag  REF_ISSYMREF) {
+   error(refname %s is a symbolic ref, renaming it is not 
supported,
+   oldrefname);
+   return 1;
+   }
+   if (!symref) {
+   error(refname %s not found, oldrefname);
+   return 1;
+   }
+
+   if (!is_refname_available(newrefname, oldrefname, 1))
+   return 1;
+
+   log = reflog_exists(oldrefname);
+   transaction = transaction_begin(err);
+   if (!transaction)
+   goto fail;
+
+   if (strcmp(oldrefname, newrefname)) {
+   if (log  transaction_update_reflog(transaction, newrefname,
+sha1, sha1, ci, NULL,
+REFLOG_TRUNCATE, err))
+   goto fail;
+   cb.transaction = transaction;
+   cb.refname = newrefname;
+   cb.err = err;
+   if (log  for_each_reflog_ent(oldrefname, rename_reflog_ent,
+  cb))
+   goto fail;
+
+   if (transaction_delete_sha1(transaction, oldrefname, sha1,
+   REF_NODEREF,
+   1, NULL, err))
+   goto fail;
+   }
+   if (transaction_update_sha1(transaction, newrefname, sha1,
+   NULL, 0, 0, NULL, err))
+   goto fail;
+   if (log  transaction_update_reflog(transaction, newrefname, sha1,
+sha1, ci, logmsg,
+REFLOG_COMMITTER_INFO_IS_VALID,
+err))
+   goto fail;
+   if (transaction_commit(transaction, err))
+   goto fail;
+   transaction_free(transaction);
+   return 0;
+
+ fail:
+   error(rename_ref failed: %s, err.buf);
+   strbuf_release(err);
+   transaction_free(transaction);
+   return 1;
+}
diff --git a/refs.c b/refs.c
index faf794c..7d579be 100644
--- a/refs.c
+++ b/refs.c
@@ -2622,98 +2622,6 @@ static int delete_ref_loose(struct ref_lock *lock, int 
flag, struct strbuf *err)
return 0;
 }
 
-struct rename_reflog_cb {
-   struct ref_transaction *transaction;
-   const char *refname;
-   struct strbuf *err;
-};
-
-static int rename_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
-const char *id, unsigned long timestamp, int tz,
-const char *message, void *cb_data)
-{
-   struct rename_reflog_cb *cb = cb_data;
-   struct reflog_committer_info ci;
-
-   memset(ci, 0, sizeof(ci));
-   ci.id = id;
-   ci.timestamp = timestamp;
-   ci.tz = tz;
-   return transaction_update_reflog(cb-transaction, cb-refname,
-nsha1, osha1, ci, message, 0,
-  

[PATCH 04/22] refs-common.c: move delete_ref to the common code

2014-08-08 Thread Ronnie Sahlberg
This change moves delete_ref() to the refs-common.c file since this function
does not contain any backend specific code.

Signed-off-by: Ronnie Sahlberg sahlb...@google.com
---
 refs-common.c | 18 ++
 refs.c| 19 ---
 2 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/refs-common.c b/refs-common.c
index cb884b2..71ad358 100644
--- a/refs-common.c
+++ b/refs-common.c
@@ -25,3 +25,21 @@ int update_ref(const char *action, const char *refname,
return 0;
 }
 
+int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
+{
+   struct ref_transaction *transaction;
+   struct strbuf err = STRBUF_INIT;
+
+   transaction = transaction_begin(err);
+   if (!transaction ||
+   transaction_delete_sha1(transaction, refname, sha1, delopt,
+   sha1  !is_null_sha1(sha1), NULL, err) ||
+   transaction_commit(transaction, err)) {
+   error(%s, err.buf);
+   transaction_free(transaction);
+   strbuf_release(err);
+   return 1;
+   }
+   transaction_free(transaction);
+   return 0;
+}
diff --git a/refs.c b/refs.c
index eb66cf7..faf794c 100644
--- a/refs.c
+++ b/refs.c
@@ -2622,25 +2622,6 @@ static int delete_ref_loose(struct ref_lock *lock, int 
flag, struct strbuf *err)
return 0;
 }
 
-int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
-{
-   struct ref_transaction *transaction;
-   struct strbuf err = STRBUF_INIT;
-
-   transaction = transaction_begin(err);
-   if (!transaction ||
-   transaction_delete_sha1(transaction, refname, sha1, delopt,
-   sha1  !is_null_sha1(sha1), NULL, err) ||
-   transaction_commit(transaction, err)) {
-   error(%s, err.buf);
-   transaction_free(transaction);
-   strbuf_release(err);
-   return 1;
-   }
-   transaction_free(transaction);
-   return 0;
-}
-
 struct rename_reflog_cb {
struct ref_transaction *transaction;
const char *refname;
-- 
2.0.1.553.geee1b3e

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


Re: Transaction patch series overview

2014-08-08 Thread Ronnie Sahlberg
List, please see here an overview and ordering of the ref transaction
patch series.
These series build on each other and needs to be applied in the order
listed below.

This is an update.




rs/ref-transaction-0
---
Early part of the ref transaction topic.

* rs/ref-transaction-0:
  refs.c: change ref_transaction_update() to do error checking and
return status
  refs.c: remove the onerr argument to ref_transaction_commit
  update-ref: use err argument to get error from ref_transaction_commit
  refs.c: make update_ref_write update a strbuf on failure
  refs.c: make ref_update_reject_duplicates take a strbuf argument
for errors
  refs.c: log_ref_write should try to return meaningful errno
  refs.c: make resolve_ref_unsafe set errno to something meaningful on error
  refs.c: commit_packed_refs to return a meaningful errno on failure
  refs.c: make remove_empty_directories always set errno to something sane
  refs.c: verify_lock should set errno to something meaningful
  refs.c: make sure log_ref_setup returns a meaningful errno
  refs.c: add an err argument to repack_without_refs
  lockfile.c: make lock_file return a meaningful errno on failurei
  lockfile.c: add a new public function unable_to_lock_message
  refs.c: add a strbuf argument to ref_transaction_commit for error logging
  refs.c: allow passing NULL to ref_transaction_free
  refs.c: constify the sha arguments for
ref_transaction_create|delete|update
  refs.c: ref_transaction_commit should not free the transaction
  refs.c: remove ref_transaction_rollback

Has been merged into next.



ref-transaction-1 (2014-07-16) 20 commits
-
Second batch of ref transactions

 - refs.c: make delete_ref use a transaction
 - refs.c: make prune_ref use a transaction to delete the ref
 - refs.c: remove lock_ref_sha1
 - refs.c: remove the update_ref_write function
 - refs.c: remove the update_ref_lock function
 - refs.c: make lock_ref_sha1 static
 - walker.c: use ref transaction for ref updates
 - fast-import.c: use a ref transaction when dumping tags
 - receive-pack.c: use a reference transaction for updating the refs
 - refs.c: change update_ref to use a transaction
 - branch.c: use ref transaction for all ref updates
 - fast-import.c: change update_branch to use ref transactions
 - sequencer.c: use ref transactions for all ref updates
 - commit.c: use ref transactions for updates
 - replace.c: use the ref transaction functions for updates
 - tag.c: use ref transactions when doing updates
 - refs.c: add transaction.status and track OPEN/CLOSED/ERROR
 - refs.c: make ref_transaction_begin take an err argument
 - refs.c: update ref_transaction_delete to check for error and return status
 - refs.c: change ref_transaction_create to do error checking and return status
 (this branch is used by rs/ref-transaction, rs/ref-transaction-multi,
rs/ref-transaction-reflog and rs/ref-transaction-rename.)

 The second batch of the transactional ref update series.

Has been merged into pu



rs/ref-transaction (2014-07-17) 12 commits
-
 - refs.c: fix handling of badly named refs
 - refs.c: make write_ref_sha1 static
 - fetch.c: change s_update_ref to use a ref transaction
 - refs.c: propagate any errno==ENOTDIR from _commit back to the callers
 - refs.c: pass a skip list to name_conflict_fn
 - refs.c: call lock_ref_sha1_basic directly from commit
 - refs.c: move the check for valid refname to lock_ref_sha1_basic
 - refs.c: pass NULL as *flags to read_ref_full
 - refs.c: pass the ref log message to _create/delete/update instead of _commit
 - refs.c: add an err argument to delete_ref_loose
 - wrapper.c: add a new function unlink_or_msg
 - wrapper.c: simplify warn_if_unremovable
 (this branch is used by rs/ref-transaction-multi,
rs/ref-transaction-reflog and rs/ref-transaction-rename; uses
rs/ref-transaction-1.)

The third and final part of the basic ref-transaction work.

Has been merged into pu.




rs/ref-transaction-reflog (2014-07-23) 15 commits
---
 - refs.c: allow deleting refs with a broken sha1
 - refs.c: remove lock_any_ref_for_update
 - refs.c: make unlock_ref/close_ref/commit_ref static
 - refs.c: rename log_ref_setup to create_reflog
 - reflog.c: use a reflog transaction when writing during expire
 - refs.c: allow multiple reflog updates during a single transaction
 - refs.c: only write reflog update if msg is non-NULL
 - refs.c: add a flag to allow reflog updates to truncate the log
 - refs.c: add a transaction function to append a reflog entry
 - lockfile.c: make hold_lock_file_for_append preserve meaningful errno
 - refs.c: add a function to append a reflog entry to a fd
 - refs.c: add a new update_type field to ref_update
 - refs.c: rename the transaction functions
 - 

Re: [PATCH 7/7] Documentation: git-init: flesh out example

2014-08-08 Thread Linus Arver
On Wed, Aug 06, 2014 at 10:41:10AM -0700, Junio C Hamano wrote:
 Linus Arver linusar...@gmail.com writes:
 
  On Tue, Aug 05, 2014 at 03:14:48PM -0700, Junio C Hamano wrote:
  Linus Arver linusar...@gmail.com writes:
  
   Signed-off-by: Linus Arver linusar...@gmail.com
   ---
Documentation/git-init.txt | 6 --
1 file changed, 4 insertions(+), 2 deletions(-)
  
   diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
   index b94d165..16e9f9c 100644
   --- a/Documentation/git-init.txt
   +++ b/Documentation/git-init.txt
   @@ -138,10 +138,12 @@ Start a new Git repository for an existing code 
   base::
$ cd /path/to/my/codebase
$ git init  1
$ git add . 2
   +$ git commit3
  
  I agree it is a good discipline to make the initial pristine
  import immediately after git add . without doing anything else.
  Perhaps the description below wants to make it more explicit?
  
 
  I could add a comment like the following:
 
  For new repositories, creating a commit immediately after git add
  . is good practice as it will cleanly separate any preexisting work
  (done under some other VCS, for example) from any new work done with
  git.
 
  Does this make sense? I am not sure how explicit you want it to be, or
  whether I captured what you wanted to be explained.
 
 I was thinking more along the lines of
 
 3 Record the pristine state as the first commit in the history.
 
 which should suffice without becoming excessively verbose.

Ah yes, I like the brevity.

  Actually, I would like to know if anything is special about the
  root-commit...
 
 As far as Git is concerned, they are just ordinary commits without
 any parents.  A commit in Git can have zero or more parents, so from
 that structural point of view, they are not that special.
 
 They are considered special by users because they represent the
 beginning of the project history.

Thank you for the insight. I won't bother adding a blurb about
root-commit and what it means because they are not that special, as
you said so yourself.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 01/22] refs.c: create a public function for is_refname_available

2014-08-08 Thread David Turner
On Fri, 2014-08-08 at 09:44 -0700, Ronnie Sahlberg wrote:
 + * Check is a particular refname is available for creation. skip
 contains

s/Check is/Check that/'

 + * a list of refnames to exclude from the refname collission tests.

collision

 + */
 +int is_refname_available(const char *refname, const char **skip, int
 skipnum);
 +
 +/*


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


[PATCH v2 2/7] Documentation: git-init: list items facelift

2014-08-08 Thread Linus Arver
No textual change.

Signed-off-by: Linus Arver linusar...@gmail.com
---
 Documentation/git-init.txt | 49 ++
 1 file changed, 28 insertions(+), 21 deletions(-)

diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index f1f920e..c02ccd0 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -72,30 +72,37 @@ repository.  When specified, the config variable 
core.sharedRepository is
 set so that files and directories under `$GIT_DIR` are created with the
 requested permissions.  When not specified, Git will use permissions reported
 by umask(2).
-
++
 The option can have the following values, defaulting to 'group' if no value
 is given:
++
+--
+'umask' (or 'false')::
+
+Use permissions reported by umask(2). The default, when `--shared` is not
+specified.
+
+'group' (or 'true')::
 
- - 'umask' (or 'false'): Use permissions reported by umask(2). The default,
-   when `--shared` is not specified.
-
- - 'group' (or 'true'): Make the repository group-writable, (and g+sx, since
-   the git group may be not the primary group of all users).
-   This is used to loosen the permissions of an otherwise safe umask(2) value.
-   Note that the umask still applies to the other permission bits (e.g. if
-   umask is '0022', using 'group' will not remove read privileges from other
-   (non-group) users). See '0xxx' for how to exactly specify the repository
-   permissions.
-
- - 'all' (or 'world' or 'everybody'): Same as 'group', but make the repository
-   readable by all users.
-
- - '0xxx': '0xxx' is an octal number and each file will have mode '0xxx'.
-   '0xxx' will override users' umask(2) value (and not only loosen permissions
-   as 'group' and 'all' does). '0640' will create a repository which is
-   group-readable, but not group-writable or accessible to others. '0660' will
-   create a repo that is readable and writable to the current user and group,
-   but inaccessible to others.
+Make the repository group-writable, (and g+sx, since the git group may be not
+the primary group of all users). This is used to loosen the permissions of an
+otherwise safe umask(2) value. Note that the umask still applies to the other
+permission bits (e.g. if umask is '0022', using 'group' will not remove read
+privileges from other (non-group) users). See '0xxx' for how to exactly specify
+the repository permissions.
+
+'all' (or 'world' or 'everybody')::
+
+Same as 'group', but make the repository readable by all users.
+
+'0xxx'::
+
+'0xxx' is an octal number and each file will have mode '0xxx'. '0xxx' will
+override users' umask(2) value (and not only loosen permissions as 'group' and
+'all' does). '0640' will create a repository which is group-readable, but not
+group-writable or accessible to others. '0660' will create a repo that is
+readable and writable to the current user and group, but inaccessible to 
others.
+--
 
 By default, the configuration flag `receive.denyNonFastForwards` is enabled
 in shared repositories, so that you cannot force a non fast-forwarding push
-- 
2.0.4

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


[PATCH v2 1/7] Documentation: git-init: typographical fixes

2014-08-08 Thread Linus Arver
Use backticks when we quote something that the user should literally
use.

Signed-off-by: Linus Arver linusar...@gmail.com
---
 Documentation/git-init.txt | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index afd721e..f1f920e 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -43,7 +43,7 @@ OPTIONS
 -q::
 --quiet::
 
-Only print error and warning messages, all other output will be suppressed.
+Only print error and warning messages; all other output will be suppressed.
 
 --bare::
 
@@ -97,7 +97,7 @@ is given:
create a repo that is readable and writable to the current user and group,
but inaccessible to others.
 
-By default, the configuration flag receive.denyNonFastForwards is enabled
+By default, the configuration flag `receive.denyNonFastForwards` is enabled
 in shared repositories, so that you cannot force a non fast-forwarding push
 into it.
 
@@ -106,14 +106,13 @@ line, the command is run inside the directory (possibly 
after creating it).
 
 --
 
-
 TEMPLATE DIRECTORY
 --
 
 The template directory contains files and directories that will be copied to
 the `$GIT_DIR` after it is created.
 
-The template directory used will (in order):
+The template directory used will be (in order):
 
  - The argument given with the `--template` option.
 
@@ -138,8 +137,8 @@ $ git init  1
 $ git add . 2
 
 +
-1 prepare /path/to/my/codebase/.git directory
-2 add all existing file to the index
+1 Create a /path/to/my/codebase/.git directory.
+2 Add all existing files to the index.
 
 GIT
 ---
-- 
2.0.4

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


[PATCH v2] lots of documentation fixes/rewordings in git-init(1)

2014-08-08 Thread Linus Arver
Hello,

Aside from the changes stemming from the discussion, I have also separated out
some typographical changes from patches 3 and 7, and squashed them into patch
1. So, those commits are cleaner now.

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


[PATCH v2 5/7] Documentation: git-init: reword parenthetical statements

2014-08-08 Thread Linus Arver
Signed-off-by: Linus Arver linusar...@gmail.com
---
 Documentation/git-init.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 3f4e46a..21e5ad9 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -108,8 +108,8 @@ By default, the configuration flag 
`receive.denyNonFastForwards` is enabled
 in shared repositories, so that you cannot force a non fast-forwarding push
 into it.
 
-If you name a (possibly non-existent) directory at the end of the command
-line, the command is run inside the directory (possibly after creating it).
+If you provide a 'directory', the command is run inside it. If this directory
+does not exist, it will be created.
 
 --
 
-- 
2.0.4

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


[PATCH v2 3/7] Documentation: git-init: template directory: reword

2014-08-08 Thread Linus Arver
Signed-off-by: Linus Arver linusar...@gmail.com
---
 Documentation/git-init.txt | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index c02ccd0..6ffe721 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -119,15 +119,15 @@ TEMPLATE DIRECTORY
 The template directory contains files and directories that will be copied to
 the `$GIT_DIR` after it is created.
 
-The template directory used will be (in order):
+The template directory will be one of the following (in order):
 
- - The argument given with the `--template` option.
+ - the argument given with the `--template` option;
 
- - The contents of the `$GIT_TEMPLATE_DIR` environment variable.
+ - the contents of the `$GIT_TEMPLATE_DIR` environment variable;
 
- - The `init.templatedir` configuration variable.
+ - the `init.templatedir` configuration variable; or
 
- - The default template directory: `/usr/share/git-core/templates`.
+ - the default template directory: `/usr/share/git-core/templates`.
 
 The default template directory includes some directory structure, some
 suggested exclude patterns, and copies of sample hook files.
-- 
2.0.4

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


[PATCH v2 4/7] Documentation: git-init: --separate-git-dir: clarify

2014-08-08 Thread Linus Arver
Use shorter sentences to describe what actually happens. We describe
what the term Git symbolic link actually means.

Also, we separate out the description of the behavioral change upon
reinitialization into its own paragraph.

Signed-off-by: Linus Arver linusar...@gmail.com
---
 Documentation/git-init.txt | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 6ffe721..3f4e46a 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -57,12 +57,12 @@ DIRECTORY section below.)
 
 --separate-git-dir=git dir::
 
-Instead of initializing the repository where it is supposed to be,
-place a filesytem-agnostic Git symbolic link there, pointing to the
-specified path, and initialize a Git repository at the path. The
-result is Git repository can be separated from working tree. If this
-is reinitialization, the repository will be moved to the specified
-path.
+Instead of initializing the repository as a directory to either `$GIT_DIR` or
+`./.git/`, create a text file there containing the path to the actual
+repository.  This file acts as filesystem-agnostic Git symbolic link to the
+repository.
++
+If this is reinitialization, the repository will be moved to the specified 
path.
 
 --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
 
-- 
2.0.4

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


[PATCH v2 6/7] Documentation: git-init: template directory: reword and cross-reference

2014-08-08 Thread Linus Arver
Signed-off-by: Linus Arver linusar...@gmail.com
---
 Documentation/git-init.txt | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 21e5ad9..9f2c7d8 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -129,9 +129,8 @@ The template directory will be one of the following (in 
order):
 
  - the default template directory: `/usr/share/git-core/templates`.
 
-The default template directory includes some directory structure, some
-suggested exclude patterns, and copies of sample hook files.
-The suggested patterns and hook files are all modifiable and extensible.
+The default template directory includes some directory structure, suggested
+exclude patterns (see linkgit:gitignore[5]), and sample hook files (see 
linkgit:githooks[5]).
 
 EXAMPLES
 
-- 
2.0.4

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


[PATCH v2 7/7] Documentation: git-init: flesh out example

2014-08-08 Thread Linus Arver
Add a third step `git commit` after adding files for the first time.

Signed-off-by: Linus Arver linusar...@gmail.com
---
 Documentation/git-init.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 9f2c7d8..369f889 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -141,10 +141,12 @@ Start a new Git repository for an existing code base::
 $ cd /path/to/my/codebase
 $ git init  1
 $ git add . 2
+$ git commit3
 
 +
 1 Create a /path/to/my/codebase/.git directory.
 2 Add all existing files to the index.
+3 Record the pristine state as the first commit in the history.
 
 GIT
 ---
-- 
2.0.4

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


Re: Rebase safely (Re: cherry picking and merge)

2014-08-08 Thread Mike Stump
On Aug 6, 2014, at 10:11 PM, Nico Williams n...@cryptonector.com wrote:
 Nah.  Sun managed this for decades without a hitch, and for products
 much larger than GCC.  See above.

Ok.  Ah, ok, perfect.  I see how that method of working would cure the 
cherry-pick and merge don’t work problem mentioned at the top of the thread.

 Do some experiments based on the above hardcopy.  If that doesn't
 convince you that it works, oh well, I'll have given it a good try.

Thank you for taking the time to diagram that as it appears to violate 
everyones how to use git guide.   I see the workflow does an onto, which was 
the ‘fix’ people talked about on stack overflow, and I see just how things 
would work.

If the old master branches are deleted and gc is run, then all the old 
references go away, and then the refs from email and bugzilla then don’t work.  
Did you guys ever remove them and then prune (or gc)?

Now, the biggest issue, if that is recognized as `fixing’ the cherry-pick 
problem, then certainly the problem is understood to be a problem.  If one 
recognized it as a problem, then one can envision cherry-pick and merge working 
together so that the problem doesn’t need fixing in the first place.  And, if 
it doesn’t need fixing, then the cost of the solution isn’t needed either.  The 
biggest problem with git, is that two features don’t work nicely together when 
they could; in this case, cherry-pick and merge).  Because they don’t, it makes 
it hard for people to predict what will happen when they use it.  This makes it 
more expensive to use and less suitable than a system that is more predictable. 
 You improve git, by fixing the problem and making the features work nicely 
together and making it predicable.

I still favor fixing the underlying problem with cherry-pick and merge not 
working.  :-)  That said, I see how to work around the bug with rebase, if I 
need to.

I wish the top google hit were your guide and I wish I never saw all the other 
pages…  I see now your position, and I see why all the guides are wrong, if you 
know just how to use rebase.  I wish the git documentation were improved to say 
as the first sentence under cherry-pick, this feature sucks and doesn’t really 
work well, it can cause excess merge conflicts.  rebase can be used to work 
around the bugs in cherry-pick for now.  And under rebase, instead of saying 
what it said now, that how one can can trivially and effortlessly use git, 
instead of saying, Do not rebase commits that you have pushed to a public 
repository which I now see is wrong.--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/8] mv: no Huh? to the user

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

 Although if we are frisky, this could do

static NORETURN void die_builtin(const char *err, va_list params)
{
   -   vreportf(fatal: , err, params);
   +   vreportf(Huh? , err, params);
   exit(128);
}

;-)

While at it we may want to remove the extra SP between dies and
their opening parentheses.

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

 diff --git a/builtin/mv.c b/builtin/mv.c
 index b892f63..a7e02c0 100644
 --- a/builtin/mv.c
 +++ b/builtin/mv.c
 @@ -135,7 +135,7 @@ int cmd_mv(int argc, const char **argv, const char 
 *prefix)
   if (first = 0) {
   struct strbuf submodule_dotgit = STRBUF_INIT;
   if (!S_ISGITLINK(active_cache[first]-ce_mode))
 - die (_(Huh? Directory %s is in index 
 and no submodule?), src);
 + die (_(Directory %s is in index and no 
 submodule?), src);
   if (!is_staging_gitmodules_ok())
   die (_(Please, stage your changes to 
 .gitmodules or stash them to proceed));
   strbuf_addf(submodule_dotgit, %s/.git, src);
 @@ -153,8 +153,7 @@ int cmd_mv(int argc, const char **argv, const char 
 *prefix)
  
   first = cache_name_pos(src_w_slash, 
 len_w_slash);
   if (first = 0)
 - die (_(Huh? %.*s is in index?),
 - len_w_slash, 
 src_w_slash);
 + die (_(%.*s is in index), 
 len_w_slash, src_w_slash);
  
   first = -1 - first;
   for (last = first; last  active_nr; last++) {
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/8] mv: flatten error handling code block

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

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

 diff --git a/builtin/mv.c b/builtin/mv.c
 index a7e02c0..5c6f58f 100644
 --- a/builtin/mv.c
 +++ b/builtin/mv.c
 @@ -58,6 +58,11 @@ static const char *add_slash(const char *path)
   return path;
  }
  
 +static void move_up_one(void *p, int nmemb, int size)
 +{
 + memmove(p, (char*)p + size, nmemb * size);
 +}
 +
  static struct lock_file lock_file;
  #define SUBMODULE_WITH_GITDIR ((const char *)1)
  
 @@ -224,24 +229,18 @@ int cmd_mv(int argc, const char **argv, const char 
 *prefix)
   else
   string_list_insert(src_for_dst, dst);
  
 - if (bad) {
 - if (ignore_errors) {
 - if (--argc  0) {
 - memmove(source + i, source + i + 1,
 - (argc - i) * sizeof(char *));
 - memmove(destination + i,
 - destination + i + 1,
 - (argc - i) * sizeof(char *));
 - memmove(modes + i, modes + i + 1,
 - (argc - i) * sizeof(enum 
 update_mode));
 - memmove(submodule_gitfile + i,
 - submodule_gitfile + i + 1,
 - (argc - i) * sizeof(char *));
 - i--;
 - }
 - } else
 - die (_(%s, source=%s, destination=%s),
 -  bad, src, dst);
 + if (!bad)
 + continue;
 + if (!ignore_errors)
 + die (_(%s, source=%s, destination=%s),
 +  bad, src, dst);
 + if (--argc  0) {
 + int n = argc - i;
 + move_up_one(source + i, n, sizeof(*source));
 + move_up_one(destination + i, n, sizeof(*destination));
 + move_up_one(modes + i, n, sizeof(*modes));
 + move_up_one(submodule_gitfile + i, n, 
 sizeof(*submodule_gitfile));
 + i--;

The resulting end-of-loop code structure certainly looks a lot
better, even if the original memmove()s were left inline without the
helper.

The helper itself however looks a bit half-hearted.  It may be more
appropriate to go one step further to have a macro whose use looks
like this, perhaps, to avoid the last remaining repetition?

MOVE_UP_BY_ONE(source, i, n);


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


Re: [PATCH 17/22] refs.c: add a backend method structure with transaction functions

2014-08-08 Thread David Turner
On Fri, 2014-08-08 at 09:45 -0700, Ronnie Sahlberg wrote:

 +struct ref_be refs_files = {
 + .transaction_begin  = files_transaction_begin,
 + .transaction_update_sha1= files_transaction_update_sha1,
 + .transaction_create_sha1= files_transaction_create_sha1,
 + .transaction_delete_sha1= files_transaction_delete_sha1,
 + .transaction_update_reflog  = files_transaction_update_reflog,
 + .transaction_commit = files_transaction_commit,
 + .transaction_free   = files_transaction_free,
 +};

C99 designated initializers are unfortunately forbidden by
CodingGuidelines.

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


Re: Rebase safely (Re: cherry picking and merge)

2014-08-08 Thread Nico Williams
On Fri, Aug 08, 2014 at 10:34:43AM -0700, Mike Stump wrote:
 On Aug 6, 2014, at 10:11 PM, Nico Williams n...@cryptonector.com wrote:
  Nah.  Sun managed this for decades without a hitch, and for products
  much larger than GCC.  See above.
 
 Ok.  Ah, ok, perfect.  I see how that method of working would cure the
 cherry-pick and merge don’t work problem mentioned at the top of the
 thread.
 
  Do some experiments based on the above hardcopy.  If that doesn't
  convince you that it works, oh well, I'll have given it a good try.
 
 Thank you for taking the time to diagram that as it appears to violate
 everyones how to use git guide.   I see the workflow does an onto,
 which was the ‘fix’ people talked about on stack overflow, and I see
 just how things would work.

There's nothing scary about --onto.  You're saying figure out which are
my local commits (the ones on top of the previous upstream) and pick
them onto the new upstream.

We only need to do it manually (though it can be scripted[*]) because
git doesn't track rebase history so that it can be done automatically.

[*] And then there's Tony Finch's
https://git.csx.cam.ac.uk/x/ucs/git/git-repub.git , which is kinda
awesome!

 If the old master branches are deleted and gc is run, then all the old
 references go away, and then the refs from email and bugzilla then
 don’t work.  Did you guys ever remove them and then prune (or gc)?

Product gates' repos and snapshots stuck around forever, though it was
Teamware, and finding really old ones wasn't necessarily easy,
particularly since their names didn't always reflect product names.

Prominent project gate repos and their snapshots also stuck around
forever.

Lesser project gate repos tended to be as ephemeral as the project.

 Now, the biggest issue, if that is recognized as `fixing’ the
 cherry-pick problem, then certainly the problem is understood to be a
 problem.  If one recognized it as a problem, then one can envision

Not really.  This isn't about git.  We followed a rebase-only workflow
with VCSes that nominally didn't support rebase.  We did it because it
was easier on everyone and kept history in the upstream clean.  We
didn't do it because git has issues when combining merge and
cherry-pick.

 cherry-pick and merge working together so that the problem doesn’t
 need fixing in the first place.  And, if it doesn’t need fixing, then

If you buy into the Sun model then this is all a non-issue.  If you
don't then I think you have other problems (because I have bought into
the Sun model) :)

 the cost of the solution isn’t needed either.  The biggest problem
 with git, is that two features don’t work nicely together when they
 [...]

The Sun model has no additional cost.  It moves costs around so that the
people dealing with conflicts are the downstreams, not the upstreams,
and that's exactly as it should be.

(Keep in mind that Solaris gates tended to have large numbers of commits
on any given day, so it was quite common that one would have to rebase
multiple times before successfully pushing.  For large projects with
long test cycles the gates would close to avoid the need to rebase and
re-test.)

 I still favor fixing the underlying problem with cherry-pick and merge
 not working.  :-)  That said, I see how to work around the bug with
 rebase, if I need to.

IMO it could be done, but I can't help that.

 I wish the top google hit were your guide and I wish I never saw all
 the other pages…  I see now your position, and I see why all the

Me too!  I should blog it.

 guides are wrong, if you know just how to use rebase.  I wish the git
 documentation were improved to say as the first sentence under

The Sun model is not the only way to use git though.

 cherry-pick, this feature sucks and doesn’t really work well, it can
 cause excess merge conflicts.  rebase can be used to work around the
 bugs in cherry-pick for now.  And under rebase, instead of saying what
 it said now, that how one can can trivially and effortlessly use git,
 instead of saying, Do not rebase commits that you have pushed to a
 public repository which I now see is wrong.

I'm glad you understand the Sun model now.  You should evaluate its
applicability to your use case on its own merits.  Don't use it just to
workaround a problem in git; use it because it's good, or don't use it
because it doesn't fit your team's needs.

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


Re: [PATCH v2 04/23] rebase -i: hide interactive command messages in verbose mode

2014-08-08 Thread Thomas Rast
Fabian Ruch baf...@gmail.com writes:

 @@ -923,6 +923,8 @@ EOF
   ;;
  esac
  
 +mkdir -p $state_dir || die Could not create temporary $state_dir
 +
  git var GIT_COMMITTER_IDENT /dev/null ||
   die You need to set your committer info first
  
 @@ -938,7 +940,6 @@ then
  fi
  
  orig_head=$(git rev-parse --verify HEAD) || die No HEAD?
 -mkdir -p $state_dir || die Could not create temporary $state_dir
  
  :  $state_dir/interactive || die Could not mark as interactive
  write_basic_state

Why this change?  I can't figure out how it relates to the output
change.

 @@ -873,9 +873,8 @@ test_expect_success 'running git rebase -i --exec git 
 show HEAD' '
   (
   FAKE_LINES=1 exec_git_show_HEAD 2 exec_git_show_HEAD 
   export FAKE_LINES 
 - git rebase -i HEAD~2 expect
 + git rebase -i HEAD~2 expected
   ) 
 - sed -e 1,9d expect expected 
   test_cmp expected actual
  '

Getting rid of these magic removals is a very nice change, thank you.

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


Re: [PATCH v2 08/23] rebase -i: reword executes pre-commit hook on interim commit

2014-08-08 Thread Thomas Rast
Fabian Ruch baf...@gmail.com writes:

 Subject: Re: [PATCH v2 08/23] rebase -i: reword executes pre-commit hook on 
 interim commit

I think the change makes sense, but can you reword the subjects that it
describes the state after the commit (i.e. what you are doing), instead
of before the commit?

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


Re: [PATCH v2 23/23] rebase -i: enable options --signoff, --reset-author for pick, reword

2014-08-08 Thread Thomas Rast
Fabian Ruch baf...@gmail.com writes:

 @@ -634,21 +644,24 @@ do_replay () {
   comment_for_reflog pick
  
   mark_action_done
 - do_pick $sha1 || die_with_patch $sha1 Could not apply $sha1... 
 $rest
 + eval do_pick $opts $sha1 \
 + || die_with_patch $sha1 Could not apply $sha1... $rest

You had me a little puzzled at the switch to 'eval' here.  That is
necessary to match the quoting added in 20/23, not for any change in
this commit.  This commit is simply the first one to trigger this.
Also, are you sure $sha1 does not require quoting through an eval?


Please add tests to this patch.

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


Re: [PATCH v2 20/23] rebase -i: parse to-do list command line options

2014-08-08 Thread Thomas Rast
Fabian Ruch baf...@gmail.com writes:

[...]
 are not supported at the moment. Neither are options that contain
 spaces because the shell expansion of `args` in `do_next` interprets
 white space characters as argument separator, that is a command line
 like

 pick --author A U Thor fa1afe1 Some change

 is parsed as the pick command

 pick --author

 and the commit hash

 A

 which obviously results in an unknown revision error. For the sake of
 completeness, in the example above the message title variable `rest`
 is assigned the string 'U Thor fa1afe1 Some change' (without the
 single quotes).

You could probably trim down the non-example a bit and instead give an
example :-)

 Print an error message for unknown or unsupported command line
 options, which means an error for all specified options at the
 moment.

Can you add a test that verifies we catch an obvious unknown option
(such as --unknown-option)?

 Cleanly break the `do_next` loop by assigning the special
 value 'unknown' to the local variable `command`, which triggers the
 unknown command case in `do_cmd`.
[...]
  do_replay () {
   command=$1
 - sha1=$2
 - rest=$3
 + shift
 +
 + opts=
 + while test $# -gt 0
 + do
 + case $1 in
 + -*)
 + warn Unknown option: $1
 + command=unknown
 + ;;
 + *)
 + break
 + ;;

This seems a rather hacky solution to me.  Doesn't this now print

  warning: Unknown option: --unknown-option
  warning: Unknown command: pick --unknown-option

?

It shouldn't claim the command is unknown if the command itself was
valid.

Also, you speak of do_cmd above, but the unknown command handling seems
to be part of do_replay?

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


[PATCH] Update hard-coded header dependencies

2014-08-08 Thread Jonathan Nieder
The fall-back rules used when compilers don't support the -MMD switch
to generate makefile rules based on #includes have been out of date
since v1.7.12.1~22^2~8 (move git_version_string into version.c,
2012-06-02).

Checked with 'make CHECK_HEADER_DEPENDENCIES=yes'.

Signed-off-by: Jonathan Nieder jrnie...@gmail.com
---
Maybe it's worth switching to plain

LIB_H += $(wildcard *.h)

?  People using ancient compilers that never change headers wouldn't
be hurt, people using modern compilers that do change headers also
wouldn't be hurt, and we could stop pretending to maintain an
up-to-date list.

 Makefile | 8 
 1 file changed, 8 insertions(+)

diff --git a/Makefile b/Makefile
index 2320de5..18f0fad 100644
--- a/Makefile
+++ b/Makefile
@@ -646,15 +646,19 @@ LIB_H += cache.h
 LIB_H += color.h
 LIB_H += column.h
 LIB_H += commit.h
+LIB_H += commit-slab.h
+LIB_H += compat/apple-common-crypto.h
 LIB_H += compat/bswap.h
 LIB_H += compat/mingw.h
 LIB_H += compat/obstack.h
 LIB_H += compat/poll/poll.h
 LIB_H += compat/precompose_utf8.h
 LIB_H += compat/terminal.h
+LIB_H += compat/win32/alloca.h
 LIB_H += compat/win32/dirent.h
 LIB_H += compat/win32/pthread.h
 LIB_H += compat/win32/syslog.h
+LIB_H += connect.h
 LIB_H += connected.h
 LIB_H += convert.h
 LIB_H += credential.h
@@ -678,6 +682,7 @@ LIB_H += grep.h
 LIB_H += hashmap.h
 LIB_H += help.h
 LIB_H += http.h
+LIB_H += khash.h
 LIB_H += kwset.h
 LIB_H += levenshtein.h
 LIB_H += line-log.h
@@ -721,6 +726,7 @@ LIB_H += sha1-lookup.h
 LIB_H += shortlog.h
 LIB_H += sideband.h
 LIB_H += sigchain.h
+LIB_H += split-index.h
 LIB_H += strbuf.h
 LIB_H += streaming.h
 LIB_H += string-list.h
@@ -728,6 +734,7 @@ LIB_H += submodule.h
 LIB_H += tag.h
 LIB_H += tar.h
 LIB_H += thread-utils.h
+LIB_H += trace.h
 LIB_H += transport.h
 LIB_H += tree-walk.h
 LIB_H += tree.h
@@ -744,6 +751,7 @@ LIB_H += vcs-svn/repo_tree.h
 LIB_H += vcs-svn/sliding_window.h
 LIB_H += vcs-svn/svndiff.h
 LIB_H += vcs-svn/svndump.h
+LIB_H += version.h
 LIB_H += walker.h
 LIB_H += wildmatch.h
 LIB_H += wt-status.h
-- 
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[ANNOUNCE] Git v2.1.0-rc2

2014-08-08 Thread Junio C Hamano
A release candidate Git v2.1.0-rc2 is now available for testing
at the usual places.

The tarballs are found at:

https://www.kernel.org/pub/software/scm/git/testing/

The following public repositories all have a copy of the 'v2.1.0-rc2'
tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://code.google.com/p/git-core/
  url = git://git.sourceforge.jp/gitroot/git-core/git.git
  url = git://git-core.git.sourceforge.net/gitroot/git-core/git-core
  url = https://github.com/gitster/git

Git v2.1 Release Notes (draft)
==

Backward compatibility notes


 * The default value we give to the environment variable LESS has been
   changed from FRSX to FRX, losing S (chop long lines instead
   of wrapping).  Existing users who prefer not to see line-wrapped
   output may want to set

 $ git config core.pager less -S

   to restore the traditional behaviour.  It is expected that people
   find output from most subcommands easier to read with the new
   default, except for blame which tends to produce really long
   lines.  To override the new default only for git blame, you can
   do this:

 $ git config pager.blame less -S

 * A few disused directories in contrib/ have been retired.


Updates since v2.0
--

UI, Workflows  Features

 * Since the very beginning of Git, we gave the LESS environment a
   default value FRSX when we spawn less as the pager.  S (chop
   long lines instead of wrapping) has been removed from this default
   set of options, because it is more or less a personal taste thing,
   as opposed to the others that have good justifications (i.e. R is
   very much justified because many kinds of output we produce are
   colored and FX is justified because output we produce is often
   shorter than a page).

 * The logic and data used to compute the display width needed for
   UTF-8 strings have been updated to match Unicode 7.0 better.

 * HTTP-based transports learned to better propagate the error messages from
   the webserver to the client coming over the HTTP transport.

 * The completion script for bash (in contrib/) has been updated to
   better handle aliases that define a complex sequence of commands.

 * The core.preloadindex configuration variable is enabled by default,
   allowing modern platforms to take advantage of their
   multiple cores.

 * git clone applies the if cloning from a local disk, physically
   copy the repository using hardlinks, unless otherwise told not to with
   --no-local optimization when the url.*.insteadOf mechanism rewrites a
   remote-repository git clone $URL into a
   clone from a local disk.

 * git commit --date=date option learned more
   timestamp formats, including --date=now.

 * The `core.commentChar` configuration variable is used to specify a
   custom comment character (other than the default #) for
   the commit message editor.  This can be set to `auto` to attempt to
   choose a different character that does not conflict with any that
   already starts a line in the message being edited, for cases like
   git commit --amend.

 * git format-patch learned --signature-file=file to add the contents
   of a file as a signature to the mail message it produces.

 * git grep learned the grep.fullname configuration variable to force
   --full-name to be the default.  This may cause regressions for
   scripted users who do not expect this new behaviour.

 * git imap-send learned to ask the credential helper for auth
   material.

 * git log and friends now understand the value auto for the
   log.decorate configuration variable to enable the --decorate
   option automatically when the output is sent to tty.

 * git merge without an argument, even when there is an upstream
   defined for the current branch, refused to run until
   merge.defaultToUpstream is set to true.  Flip the default of that
   configuration variable to true.

 * git mergetool learned to drive the vimdiff3 backend.

 * mergetool.prompt used to default to 'true', always asking do you
   really want to run the tool on this path?.  The default has been
   changed to 'false'.  However, the prompt will still appear if
   mergetool used its autodetection system to guess which tool to use.
   Users who explicitly specify or configure a tool will no longer see
   the prompt by default.

   Strictly speaking, this is a backward incompatible change and
   users need to explicitly set the variable to 'true' if they want
   to be prompted to confirm running the tool on each path.

 * git replace learned the --edit subcommand to create a
   replacement by editing an existing object.

 * git replace learned a --graft option to rewrite the parents of a
   commit.

 * git send-email learned --to-cover and --cc-cover options, to
   tell it to copy To: and Cc: headers found in the first input file
   when emitting later 

What's cooking in git.git (Aug 2014, #02; Fri, 8)

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

The second release candidate snapshot is out.  Hopefully after a
week of a calm pre-release bugfix-only period, we can do the 2.1
final late next week.

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

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

--
[Graduated to master]

* ta/doc-config (2014-07-30) 1 commit
  (merged to 'next' on 2014-07-31 at ec577fa)
 + add documentation for writing config files


* tf/maint-doc-push (2014-07-31) 1 commit
  (merged to 'next' on 2014-07-31 at 6a8ef70)
 + git-push: fix link in man page

--
[New Topics]

* tf/imap-send-create (2014-08-01) 3 commits
 - SQUASH??? varargs form of issue-imap-cmd is no longer used
 - imap-send: create target mailbox if it is missing
 - imap-send: clarify CRAM-MD5 vs LOGIN documentation

 Will merge to 'next' after dealing with the SQUASH??? fix-up.


* bc/archive-pax-header-mode (2014-08-04) 1 commit
 - archive: honor tar.umask even for pax headers

 Implementations of tar that do not understand an extended pax
 header would extract the contents of it in a regular file; make
 sure the permission bits of this file follows the same tar.umask
 configuration setting.

 Will merge to 'next'.


* bc/imap-send-doc (2014-08-05) 1 commit
 - imap-send doc: omit confusing to use imap-send modifier

 Will merge to 'next'.


* jc/apply-ws-prefix (2014-08-07) 3 commits
 - apply: omit ws check for excluded paths
 - apply: hoist use_patch() helper for path exclusion up
 - apply: use the right attribute for paths in non-Git patches

 Applying a patch not generated by Git in a subdirectory used to
 check the whitespace breakage using the attributes for incorrect
 paths. Also whitespace checks were performed even for paths
 excluded via git apply --exclude=path mechanism.

 Will merge to 'next'.


* jk/command-line-config-empty-string (2014-08-05) 1 commit
 - config: teach git -c to recognize an empty string

 git -c section.var command and git -c section.var= command
 should pass the configuration differently (the former should be
 a boolean true, the latter should be an empty string).

 Will merge to 'next'.


* jk/pack-bitmap (2014-08-04) 1 commit
 - pack-bitmap: do not use gcc packed attribute

 Will merge to 'next'.


* jk/pretty-empty-format (2014-07-30) 3 commits
 - pretty: make empty userformats truly empty
 - pretty: treat --format= as an empty userformat
 - revision: drop useless string offset when parsing --pretty

 git log --pretty/format= with an empty format string did not mean
 the more obvious No output whatsoever but Use default format,
 which was counterintuitive.

 Will merge to 'next'.


* la/init-doc (2014-08-08) 7 commits
 - Documentation: git-init: flesh out example
 - Documentation: git-init: template directory: reword and cross-reference
 - Documentation: git-init: reword parenthetical statements
 - Documentation: git-init: --separate-git-dir: clarify
 - Documentation: git-init: template directory: reword
 - Documentation: git-init: list items facelift
 - Documentation: git-init: typographical fixes

 Will merge to 'next'.


* lf/bundle-exclusion (2014-08-07) 1 commit
 - bundle: fix exclusion of annotated tags

 Will merge to 'next'.


* mm/log-branch-desc-plug-leak (2014-08-07) 1 commit
 - builtin/log.c: fix minor memory leak

 Will merge to 'next'.


* ta/config-set-1 (2014-08-07) 8 commits
 - add tests for `git_config_get_string_const()`
 - add a test for semantic errors in config files
 - rewrite git_config() to use the config-set API
 - config: add `git_die_config()` to the config-set API
 - change `git_config()` return value to void
 - add line number and file name info to `config_set`
 - config.c: fix accuracy of line number in errors
 - config.c: mark error and warnings strings for translation
 (this branch is used by ta/config-set-2; uses ta/config-set.)


* ta/config-set-2 (2014-08-07) 11 commits
 - branch.c: replace `git_config()` with `git_config_get_string()
 - alias.c: replace `git_config()` with `git_config_get_string()`
 - imap-send.c: replace `git_config()` with `git_config_get_*()` family
 - pager.c: replace `git_config()` with `git_config_get_value()`
 - builtin/gc.c: replace `git_config()` with `git_config_get_*()` family
 - rerere.c: replace `git_config()` with `git_config_get_*()` family
 - fetchpack.c: replace `git_config()` with `git_config_get_*()` family
 - archive.c: replace `git_config()` with `git_config_get_bool()` family
 - read-cache.c: replace `git_config()` with `git_config_get_*()` family
 - http-backend.c: replace `git_config()` with `git_config_get_bool()` family
 - daemon.c: replace `git_config()` with `git_config_get_bool()` family
 (this branch uses ta/config-set and 

Re: What's cooking in git.git (Aug 2014, #02; Fri, 8)

2014-08-08 Thread Duy Nguyen
On Sat, Aug 9, 2014 at 5:18 AM, Junio C Hamano gits...@pobox.com wrote:
 * nd/lock-paths-absolute (2014-08-01) 3 commits
  - lockfile.c: store absolute path
  - lockfile.c: remove PATH_MAX limit in resolve_symlink()
  - lockfile.c: remove PATH_MAX limitation (except in resolve_symlink)
  (this branch uses rs/strbuf-getcwd.)

  Will merge to 'next'.

You may want to hold this back for a while until Michael has a chance
to look and decides what to do with it and his mh/lockfile series.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Kedves Email felhasználói;

2014-08-08 Thread Sistem Administrator®2014



-- 
Kedves Email felhasználói;

Túllépte a határt 23.432 tárolás az e-postafiók beállítva a
WEB SERVICE / Adminisztrátor, és akkor sikerül a küld#337;
és a bejöv#337; üzenetek, amíg újra érvényesíti az e-mail címét. A
szükséges eljárások
nyújtottak be, az alábbi a véleménye, ellen#337;rizze kattintva
az alábbi linkre és töltse ki az adatokat, hogy érvényesítse az e-mail címét.

Kérjük, kattintson ide http://mailupdat.jigsy.com


Hogy növelje az e-mail kvótát az e-mail.
Figyelmeztetés !!!
Ennek elmulasztása azt eredményezi, hogy korlátozott hozzáférést a postafiók.
elmulasztotta frissíteni fiókjába számított három napon belül a frissítés
értesítést, akkor figyelembe kell végleg.

Tisztelettel,
rendszer Administrator®

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


Re: [BUG] parse_object() does not behave as documented

2014-08-08 Thread Samuel Bronson
Ping?

Samuel Bronson naes...@gmail.com writes:

 [Hmm, nobody seems ot have commented on this analysis; maybe reposting
 it with a subject containing [BUG] will help?]

 Samuel Bronson naes...@gmail.com writes:

 The following message is a courtesy copy of an article
 that has been posted to gmane.comp.version-control.git as well.

 Oh, I forgot to provide any analysis of the problem.  Oops.

 It may be just as well, though; I was tired enough that I might have
 botched it in any case.  So, have an analysis:

 While inflate errors are obviously NOT GOOD, and should perhaps be
 instantly fatal for most commands, git fsck is something of a special
 case because it is useful to have *it* report as many corrupt objects as
 possible in one run.

 Unfortunately, this is not currently the case, as shown by the provided
 testcase.

 The output for this testcase is:

 ,
 | checking known breakage:
 | hash1= 
 | hash2=fffe 
 | mkdir -p .git/objects/ff 
 | echo not-zlib $(sha1_file $hash1) 
 | test_when_finished remove_object $hash1 
 | echo not-zlib $(sha1_file $hash2) 
 | test_when_finished remove_object $hash2 
 | 
 | # Return value is not documented
 | test_might_fail git fsck 2out 
 | cat out  echo == 
 | grep $hash1.*corrupt out 
 | grep $hash2.*corrupt out
 | 
 | error: inflate: data stream error (incorrect header check)
 | error: unable to unpack  header
 | error: inflate: data stream error (incorrect header check)
 | fatal: loose object  (stored
 | in .git/objects/ff/ff) is
 | corrupt
 | ==
 | fatal: loose object  (stored
 | in .git/objects/ff/ff) is
 | corrupt
 | not ok 5 - fsck survives inflate errors # TODO known breakage
 `

 If I flip it from expect_failure to expect_success and run the test with
 -i, then go into the trash directory and run gdb ../../git-fsck, I can
 obtain this (thoroughly rehearsed  trimmed) gdb transcript:

 ,
 | % gdb ../../git-fsck
 | GNU gdb (Debian 7.7.1-3) 7.7.1
 ...
 | Reading symbols from ../../git-fsck...done.
 | (gdb) break error
 | Breakpoint 1 at 0x813d24c: file usage.c, line 143.
 | (gdb) break die
 | Breakpoint 2 at 0x813d152: file usage.c, line 94.
 | (gdb) run
 | Starting program: /home/naesten/hacking/git/git-fsck
 | [Thread debugging using libthread_db enabled]
 | Using host libthread_db library
 | /lib/i386-linux-gnu/i686/cmov/libthread_db.so.1.
 | Checking object directories: 100% (256/256), done.
 | 
 | Breakpoint 1, error (err=0x8182f7a inflate: %s (%s)) at usage.c:143
 | 143 {
 | (gdb) bt
 | #0  error (err=0x8182f7a inflate: %s (%s)) at usage.c:143
 | #1  0x081452ff in git_inflate (strm=0xbfffe6b8, flush=0)
 | at zlib.c:144
 | #2  0x08125367 in unpack_sha1_header (stream=optimized out,
 | map=optimized out, mapsize=optimized out,
 | buffer=optimized out, bufsiz=optimized out)
 | at sha1_file.c:1515
 | #3  0x08125546 in sha1_loose_object_info (
 | sha1=sha1@entry=0x82659d4 '\377' repeats 20 times,
 | oi=oi@entry=0xbfffe788) at sha1_file.c:2528
 | #4  0x08126b2d in sha1_object_info_extended (
 | sha1=0x82659d4 '\377' repeats 20 times, oi=0xbfffe788, flags=1)
 | at sha1_file.c:2565
 | #5  0x0812666f in sha1_object_info (
 | sha1=0x82659d4 '\377' repeats 20 times, sizep=0x0)
 | at sha1_file.c:2601
 | #6  0x080f6941 in parse_object (
 | sha1=0x82659d4 '\377' repeats 20 times) at object.c:247
 | #7  0x080758ac in fsck_sha1 (
 | sha1=sha1@entry=0x82659d4 '\377' repeats 20 times)
 | at builtin/fsck.c:333
 ...
 | (gdb) c
 | Continuing.
 | error: inflate: data stream error (incorrect header check)
 | 
 | Breakpoint 1, error (err=0x817c525 unable to unpack %s header)
 | at usage.c:143
 | 143 {
 | (gdb) bt
 | #0  error (err=0x817c525 unable to unpack %s header) at usage.c:143
 | #1  0x08125564 in sha1_loose_object_info (
 | sha1=sha1@entry=0x82659d4 '\377' repeats 20 times,
 | oi=oi@entry=0xbfffe788) at sha1_file.c:2529
 | #2  0x08126b2d in sha1_object_info_extended (
 | sha1=0x82659d4 '\377' repeats 20 times, oi=0xbfffe788, flags=1)
 | at sha1_file.c:2565
 | #3  0x0812666f in sha1_object_info (
 | sha1=0x82659d4 '\377' repeats 20 times, sizep=0x0)
 | at sha1_file.c:2601
 | #4  0x080f6941 in parse_object (
 | sha1=0x82659d4 '\377' repeats 20 times) at object.c:247
 ...
 | (gdb) frame 4
 | #4  0x080f6941 in parse_object (
 | sha1=0x82659d4 '\377' repeats 20 times) at object.c:247
 | warning: Source file is more recent than executable.
 | 247 sha1_object_info(sha1, NULL) == OBJ_BLOB)) { // -- first error
 | (gdb) down
 | #3  0x0812666f in sha1_object_info (
 | sha1=0x82659d4 '\377' repeats 20