Un-paged commit messages in git filter-branch's commit-filter?

2016-06-12 Thread Stefan Tauner
Hello,

I am trying to do a major cleanup of the repository in one of my
projects (and switch from git-svn to native git). I have developed a
commit-filter script over the last months that massages partially
dreadful commit messages into something acceptable. While I am not 100%
sure I think that upgrading git has broken it partially. AFAICT since
the update the commit-filter does not get the original message anymore
but at least the subject/first paragraph is run through a pager or
something similar:
The first line is broken into multiple lines (i.e. some line breaks are
inserted about every 72 characters where none have been before).

I have tried to run "git --no-pager filter-branch ..." to no avail. I
have briefly looked at the source but could not find any proofs...
Any hints would be appreciated. This is how I run my script:

tmpvar="$(http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/4] dir: introduce file_size() to check the size of file

2016-06-12 Thread Pranit Bauva
Hey Torsten,

On Sun, Jun 12, 2016 at 4:14 PM, Torsten Bögershausen  wrote:
>>> So what I understand, you want something like this:
>>>
>>> +ssize_t file_size_not_zero(const char *filename)
>>> +{
>>> +   struct stat st;
>>> +   if (stat(filename, &st) < 0)
>>> +   return -1;
>>> +   return !!st.st_size);
>>> +}
>>
>> For the purpose of bisect_reset(), Yes. BTW a similar function exist
>> in builtin/am.c with the name is_empty_file(). But as Christian points
>> out file_size() could help to refactor other parts of code.
>>
>
> Please allow one or more late comments:

That's perfectly fine.

> If is_empty_file() does what you need, then it can be moved into wrapper.c
> and simply be re-used in your code.

Thanks for informing. I was unaware about the use of wrapper.c

> If you want to introduce a new function, that can be used for other 
> refactoring,
> then the whole thing would ideally go into a single commit,
> or into a single series.
> That may probably be out of the scope for your current efforts ?

On re-thinking, I think introducing file_size() is out of the scope
for the current efforts and I will stick to is_empty_file(). Will move
it to wrapper.c and then use it in my code. I am not sure but I think
a few other parts could also use is_empty_file(). I will check on that
probably after GSoC as a cleanup.

> What really makes me concern is the mixture of signed - and unsigned:
> ssize_t file_size(const char *filename)
> +{
> +   struct stat st;
> +   if (stat(filename, &st) < 0)
> +   return -1;
> +   return xsize_t(st.st_size);
> +}
>
> To my understanding a file size is either 0, or a positive integer.
> Returning -1 is of course impossible with a positive integer.

True.

> So either the function is changed like this:
>
> int file_size(const char *filename, size_t *len)
> +{
> +   struct stat st;
> +   if (stat(filename, &st) < 0)
> +   return -1;
> +   *len = xsize_t(st.st_size);
> +   return 0;
> +}
>
> Or, if that works for you:
>
> size_t file_size(const char *filename)
> +{
> +   struct stat st;
> +   if (stat(filename, &st) < 0)
> +   return 0;
> +   return xsize_t(st.st_size);
> +}
>
> Or, more git-ish:
>
> size_t file_size(const char *filename)
> +{
> +   struct stat st;
> +   if (stat(filename, &st))
> +   return 0;
> +   return xsize_t(st.st_size);
> +}
>
> (And then builtin/am.c  can be changed to use the new function.

I think I will just skip file_size() for now.

Thanks for your comments!

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


DONATION OF $ 1.5 MILLION DOLLARS!!!

2016-06-12 Thread Colin & Chris Weir
My wife and I have awarded you with a donation of $ 1.5 million Dollars from 
part of our Jackpot Lottery of 161,653,000 Million Pounds, send your 
name,address, phone for claims.

View http://www.bbc.co.uk/news/uk-scotland-glasgow-west-18801698

We await your earliest response and God Bless you.

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


[PATCH 2/3] interpret-trailers: don't duplicate option strings

2016-06-12 Thread Jeff King
There's no need to do so; the argv strings will last until
the end of the program.

Signed-off-by: Jeff King 
---
 builtin/interpret-trailers.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c
index b99ae4b..175f147 100644
--- a/builtin/interpret-trailers.c
+++ b/builtin/interpret-trailers.c
@@ -20,7 +20,7 @@ int cmd_interpret_trailers(int argc, const char **argv, const 
char *prefix)
 {
int in_place = 0;
int trim_empty = 0;
-   struct string_list trailers = STRING_LIST_INIT_DUP;
+   struct string_list trailers = STRING_LIST_INIT_NODUP;
 
struct option options[] = {
OPT_BOOL(0, "in-place", &in_place, N_("edit files in place")),
-- 
2.9.0.rc2.149.gd580ccd

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


[PATCH 3/3] blame,shortlog: don't make local option variables static

2016-06-12 Thread Jeff King
There's no need for these option variables to be static,
except that they are referenced by the options array itself,
which is static. But having all of this static is simply
unnecessary and confusing (and inconsistent with most other
commands, which either use a static global option list or a
true function-local one).

Note that in some cases we may need to actually initialize
the variables (since we cannot rely on BSS to do so). This
is a net improvement to readability, though, as we can use
the more verbose initializers for our string_lists.

Signed-off-by: Jeff King 
---
 builtin/blame.c| 12 ++--
 builtin/shortlog.c |  6 +++---
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index 21f42b0..80d2431 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -2522,12 +2522,12 @@ int cmd_blame(int argc, const char **argv, const char 
*prefix)
enum object_type type;
struct commit *final_commit = NULL;
 
-   static struct string_list range_list;
-   static int output_option = 0, opt = 0;
-   static int show_stats = 0;
-   static const char *revs_file = NULL;
-   static const char *contents_from = NULL;
-   static const struct option options[] = {
+   struct string_list range_list = STRING_LIST_INIT_NODUP;
+   int output_option = 0, opt = 0;
+   int show_stats = 0;
+   const char *revs_file = NULL;
+   const char *contents_from = NULL;
+   const struct option options[] = {
OPT_BOOL(0, "incremental", &incremental, N_("Show blame entries 
as we find them, incrementally")),
OPT_BOOL('b', NULL, &blank_boundary, N_("Show blank SHA-1 for 
boundary commits (Default: off)")),
OPT_BOOL(0, "root", &show_root, N_("Do not treat root commits 
as boundaries (Default: off)")),
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index bfc082e..f83984e 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -233,11 +233,11 @@ void shortlog_init(struct shortlog *log)
 
 int cmd_shortlog(int argc, const char **argv, const char *prefix)
 {
-   static struct shortlog log;
-   static struct rev_info rev;
+   struct shortlog log = { STRING_LIST_INIT_NODUP };
+   struct rev_info rev;
int nongit = !startup_info->have_repository;
 
-   static const struct option options[] = {
+   const struct option options[] = {
OPT_BOOL('n', "numbered", &log.sort_by_number,
 N_("sort output according to the number of commits per 
author")),
OPT_BOOL('s', "summary", &log.summary,
-- 
2.9.0.rc2.149.gd580ccd
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] parse_opt_string_list: stop allocating new strings

2016-06-12 Thread Jeff King
The parse_opt_string_list callback is basically a thin
wrapper to string_list_append() any string options we get.
However, it calls:

  string_list_append(v, xstrdup(arg));

which duplicates the option value. This is wrong for two
reasons:

  1. If the string list has strdup_strings set, then we are
 making an extra copy, which is simply leaked.

  2. If the string list does not have strdup_strings set,
 then we pass memory ownership to the string list, but
 it does not realize this. If we later call
 string_list_clear(), which can happen if "--no-foo" is
 passed, then we will leak all of the existing entries.

Instead, we should just pass the argument straight to
string_list_append, and it can decide whether to copy or not
based on its strdup_strings flag.

It's possible that some (buggy) caller could be relying on
this extra copy (e.g., because it parses some options from
an allocated argv array and then frees the array), but it's
not likely. For one, we generally only use parse_options on
the argv given to us in main(). And two, such a caller is
broken anyway, because other option types like OPT_STRING()
do not make such a copy.  This patch brings us in line with
them.

Noticed-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Jeff King 
---
 parse-options-cb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/parse-options-cb.c b/parse-options-cb.c
index 239898d..ba5acf3 100644
--- a/parse-options-cb.c
+++ b/parse-options-cb.c
@@ -144,7 +144,7 @@ int parse_opt_string_list(const struct option *opt, const 
char *arg, int unset)
if (!arg)
return -1;
 
-   string_list_append(v, xstrdup(arg));
+   string_list_append(v, arg);
return 0;
 }
 
-- 
2.9.0.rc2.149.gd580ccd

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


[PATCH 0/3] fix parse-opt string_list leaks

2016-06-12 Thread Jeff King
On Mon, Jun 13, 2016 at 07:08:55AM +0700, Duy Nguyen wrote:

> > So if we are doing the conservative thing, then I think the resulting
> > code should either look like:
> >
> >   if (!v->strdup_strings)
> > die("BUG: OPT_STRING_LIST should always use strdup_strings");
> >   string_list_append(v, arg);
> 
> I agree with the analysis. But this die() would hit all callers
> (except interpret-trailers) because they all initialize with _NODUP
> and setting strdup_strings may require auditing all access to the
> string list in question, e.g. to change string_list_append(v,
> xstrdup(xxx)) to string_list_append(xxx). it may cause side effects if
> we are not careful.

Yep. It is not really fixing anything, so much as alerting us to broken
callers. We'd still have to fix the callers. :)

> So far all callers are in builtin/, I think it will not take much time
> to verify that they all call parse_options() with global argv, then we
> can just lose extra xstrdup() and stick to string_list_append().
> OPTION_STRING already assumes that argument strings are stable because
> they are passed back as-is. Can we go with an easier route, adding a
> comment on top of parse_options() stating that argv[] pointers may be
> passed back as-is and it's up to the caller to xstrdup() appropriately
> before argv[] memory is freed?

Yeah, the two options I laid out were the "conservative" side, where we
didn't make any assumptions about what is in passed into parse_options.
But I agree in practice that it's not likely to be a problem to just
point to the existing strings, and the fact that OPTION_STRING does so
already makes me even more confident.

So I'd suggest these patches:

  [1/3]: parse_opt_string_list: stop allocating new strings
  [2/3]: interpret-trailers: don't duplicate option strings
  [3/3]: blame,shortlog: don't make local option variables static

The first one is what we've been discussing, and the others are just
follow-on cleanups.  I stopped short of a fourth patch to convert more
cases of:

  static struct string_list foo;

to:

  static struct string_list foo = STRING_LIST_INIT_NODUP;

The two are equivalent (mostly due to historical reasons). I tend to
think explicit is better than implicit for something like this (not
because BSS auto-initialization isn't OK, but because there is an
explicit choice of dup/nodup that the writer made, and it is good to
communicate that). But maybe people don't want the extra noise.

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


Re: Repacking a repository uses up all available disk space

2016-06-12 Thread Jeff King
On Mon, Jun 13, 2016 at 07:24:51AM +0700, Duy Nguyen wrote:

> >> - git fsck --full
> >> - git repack -Adl -b --pack-kept-objects
> >> - git pack-refs --all
> >> - git prune
> >>
> >> The reason it's split into repack + prune instead of just gc is because
> >> we use alternates to save on disk space and try not to prune repos that
> >> are used as alternates by other repos in order to avoid potential
> >> corruption.
> 
> Isn't this what extensions.preciousObjects is for? It looks like prune
> just refuses to run in precious objects mode though, and repack is
> skipped by gc, but if that repack command works, maybe we should do
> something like that in git-gc?

Sort of. preciousObjects is a fail-safe so that you do not ever
accidentally run an object-deleting operation where you shouldn't (e.g.,
in the shared repository used by others as an alternate). So the
important step there is that before running "repack", you would want to
make sure you have taken into account the reachability of anybody
sharing from you.

So you could do something like (in your shared repository):

  git config core.repositoryFormatVersion 1
  git config extension.preciousObjects true

  # this will fail, because it's dangerous!
  git gc

  # but we can do it safely if we take into account the other repos
  for repo in $(somehow_get_list_of_shared_repos); do
git fetch $repo +refs/*:refs/shared/$repo/*
  done
  git config extension.preciousObjects false
  git gc
  git config extension.preciousObjects true

So it really is orthogonal to running the various gc commands yourself;
it's just here to prevent you shooting yourself in the foot.

It may still be useful in such a case to split up the commands in your
own script, though. In my case, you'll note that the commands above are
racy (what happens if somebody pushes a reference to a shared object
between your fetch and the gc invocation?). So we use a custom "repack
-k" to get around that (it just keeps everything).

You _could_ have gc automatically switch to "-k" in a preciousObjects
repository. That's at least safe. But note that it doesn't really solve
all of the problems (you do still want to have ref tips from the leaf
repositories, because it affects things like bitmaps, and packing
order).

> BTW Jeff, I think we need more documentation for
> extensions.preciousObjects. It's only documented in technical/ which
> is practically invisible to all users. Maybe
> include::repository-version.txt in config.txt, or somewhere close to
> alternates?

I'm a little hesitant to document it for end users because it's still
pretty experimental. In fact, even we are not using it at GitHub
currently. We don't have a big problem with "oops, I accidentally ran
something destructive in the shared repository", because nothing except
the maintenance script ever even goes into the shared repository.

The reason I introduced it in the first place is that I was
experimenting with the idea of actually symlinking "objects/" in the
leaf repos into the shared repository. That eliminates the object
writing in the "fetch" step above, which can be a bottleneck in some
cases (not just the I/O, but the shared repo ends up having a _lot_ of
refs, and fetch can be pretty slow).

But in that case, anything that deletes an object in one of the leaf
repos is very dangerous, as it has no idea that its object store is
shared with other leaf repos. So I really wanted a fail safe so that
running "git gc" wasn't catastrophic.

I still think that's a viable approach, but my experiments got
side-tracked and I never produced anything worth looking at. So until
there's something end users can actually make use of, I'm hesitant to
push that stuff into the regular-user documentation. Anybody who is
playing with it at this point probably _should_ be familiar with what's
in Documentation/technical.

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


[PATCH 3/3] repack: extend --keep-unreachable to loose objects

2016-06-12 Thread Jeff King
If you use "repack -adk" currently, we will pack all objects
that are already packed into the new pack, and then drop the
old packs. However, loose unreachable objects will be left
as-is. In theory these are meant to expire eventually with
"git prune". But if you are using "repack -k", you probably
want to keep things forever and therefore do not run "git
prune" at all. Meaning those loose objects may build up over
time and end up fooling any object-count heuristics (such as
the one done by "gc --auto", though since git-gc does not
support "repack -k", this really applies to whatever custom
scripts people might have driving "repack -k").

With this patch, we instead stuff any loose unreachable
objects into the pack along with the already-packed
unreachable objects. This may seem wasteful, but it is
really no more so than using "repack -k" in the first place.
We are at a slight disadvantage, in that we have no useful
ordering for the result, or names to hand to the delta code.
However, this is again no worse than what "repack -k" is
already doing for the packed objects. The packing of these
objects doesn't matter much because they should not be
accessed frequently (unless they actually _do_ become
referenced, but then they would get moved to a different
part of the packfile during the next repack).

Signed-off-by: Jeff King 
---
 Documentation/git-repack.txt |  3 ++-
 builtin/pack-objects.c   | 31 +++
 builtin/repack.c |  1 +
 t/t7701-repack-unpack-unreachable.sh | 13 +
 4 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index 68702ea..b58b6b5 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -138,7 +138,8 @@ other objects in that pack they already have locally.
 --keep-unreachable::
When used with `-ad`, any unreachable objects from existing
packs will be appended to the end of the packfile instead of
-   being removed.
+   being removed. In addition, any unreachable loose objects will
+   be packed (and their loose counterparts removed).
 
 Configuration
 -
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 8f5e358..a2f8cfd 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -44,6 +44,7 @@ static int non_empty;
 static int reuse_delta = 1, reuse_object = 1;
 static int keep_unreachable, unpack_unreachable, include_tag;
 static unsigned long unpack_unreachable_expiration;
+static int pack_loose_unreachable;
 static int local;
 static int incremental;
 static int ignore_packed_keep;
@@ -2378,6 +2379,32 @@ static void add_objects_in_unpacked_packs(struct 
rev_info *revs)
free(in_pack.array);
 }
 
+static int add_loose_object(const unsigned char *sha1, const char *path,
+   void *data)
+{
+   enum object_type type = sha1_object_info(sha1, NULL);
+
+   if (type < 0) {
+   warning("loose object at %s could not be examined", path);
+   return 0;
+   }
+
+   add_object_entry(sha1, type, "", 0);
+   return 0;
+}
+
+/*
+ * We actually don't even have to worry about reachability here.
+ * add_object_entry will weed out duplicates, so we just add every
+ * loose object we find.
+ */
+static void add_unreachable_loose_objects(void)
+{
+   for_each_loose_file_in_objdir(get_object_directory(),
+ add_loose_object,
+ NULL, NULL, NULL);
+}
+
 static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)
 {
static struct packed_git *last_found = (void *)1;
@@ -2547,6 +2574,8 @@ static void get_object_list(int ac, const char **av)
 
if (keep_unreachable)
add_objects_in_unpacked_packs(&revs);
+   if (pack_loose_unreachable)
+   add_unreachable_loose_objects();
if (unpack_unreachable)
loosen_unused_packed_objects(&revs);
 
@@ -2647,6 +2676,8 @@ int cmd_pack_objects(int argc, const char **argv, const 
char *prefix)
 N_("include tag objects that refer to objects to be 
packed")),
OPT_BOOL(0, "keep-unreachable", &keep_unreachable,
 N_("keep unreachable objects")),
+   OPT_BOOL(0, "pack-loose-unreachable", &pack_loose_unreachable,
+N_("pack loose unreachable objects")),
{ OPTION_CALLBACK, 0, "unpack-unreachable", NULL, N_("time"),
  N_("unpack unreachable objects newer than "),
  PARSE_OPT_OPTARG, option_parse_unpack_unreachable },
diff --git a/builtin/repack.c b/builtin/repack.c
index 573e66c..f7b7409 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -248,6 +248,7 @@ int cmd_repack(int argc, const char **argv, const char 
*prefix)
"--unpack-unreachable");

[PATCH 2/3] repack: add --keep-unreachable option

2016-06-12 Thread Jeff King
The usual way to do a full repack (and what is done by
git-gc) is to run "repack -Ad --unpack-unreachable=",
which will loosen any unreachable objects newer than
"", and drop any older ones.

This is a safer alternative to "repack -ad", because
"" becomes a grace period during which we will not
drop any new objects that are about to be referenced.
However, it isn't perfectly safe. It's always possible that
a process is about to reference an old object. Even if that
process were to take care to update the timestamp on the
object, there is no atomicity with a simultaneously running
"repack" process.

So while unlikely, there is a small race wherein we may drop
an object that is in the process of being referenced. If you
do automated repacking on a large number of active
repositories, you may hit it eventually, and the result is a
corrupted repository.

It would be nice to fix that race in the long run, but it's
complicated.  In the meantime, there is a much simpler
strategy for automated repository maintenance: do not drop
objects at all. We already have a "--keep-unreachable"
option in pack-objects; we just need to plumb it through
from git-repack.

Note that this _isn't_ plumbed through from git-gc, so at
this point it's strictly a tool for people doing their own
advanced repository maintenance strategy.

Signed-off-by: Jeff King 
---
 Documentation/git-repack.txt |  6 ++
 builtin/repack.c |  9 +
 t/t7701-repack-unpack-unreachable.sh | 15 +++
 3 files changed, 30 insertions(+)

diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index cde7b44..68702ea 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -134,6 +134,12 @@ other objects in that pack they already have locally.
the write of any objects that would be immediately pruned by
a follow-up `git prune`.
 
+-k::
+--keep-unreachable::
+   When used with `-ad`, any unreachable objects from existing
+   packs will be appended to the end of the packfile instead of
+   being removed.
+
 Configuration
 -
 
diff --git a/builtin/repack.c b/builtin/repack.c
index 858db38..573e66c 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -146,6 +146,7 @@ int cmd_repack(int argc, const char **argv, const char 
*prefix)
int pack_everything = 0;
int delete_redundant = 0;
const char *unpack_unreachable = NULL;
+   int keep_unreachable = 0;
const char *window = NULL, *window_memory = NULL;
const char *depth = NULL;
const char *max_pack_size = NULL;
@@ -175,6 +176,8 @@ int cmd_repack(int argc, const char **argv, const char 
*prefix)
N_("write bitmap index")),
OPT_STRING(0, "unpack-unreachable", &unpack_unreachable, 
N_("approxidate"),
N_("with -A, do not loosen objects older than 
this")),
+   OPT_BOOL('k', "keep-unreachable", &keep_unreachable,
+   N_("with -a, repack unreachable objects")),
OPT_STRING(0, "window", &window, N_("n"),
N_("size of the window used for delta 
compression")),
OPT_STRING(0, "window-memory", &window_memory, N_("bytes"),
@@ -196,6 +199,10 @@ int cmd_repack(int argc, const char **argv, const char 
*prefix)
if (delete_redundant && repository_format_precious_objects)
die(_("cannot delete packs in a precious-objects repo"));
 
+   if (keep_unreachable &&
+   (unpack_unreachable || (pack_everything & LOOSEN_UNREACHABLE)))
+   die(_("--keep-unreachable and -A are incompatible"));
+
if (pack_kept_objects < 0)
pack_kept_objects = write_bitmaps;
 
@@ -239,6 +246,8 @@ int cmd_repack(int argc, const char **argv, const char 
*prefix)
} else if (pack_everything & LOOSEN_UNREACHABLE) {
argv_array_push(&cmd.args,
"--unpack-unreachable");
+   } else if (keep_unreachable) {
+   argv_array_push(&cmd.args, 
"--keep-unreachable");
} else {
argv_array_push(&cmd.env_array, 
"GIT_REF_PARANOIA=1");
}
diff --git a/t/t7701-repack-unpack-unreachable.sh 
b/t/t7701-repack-unpack-unreachable.sh
index b66e383..f13df43 100755
--- a/t/t7701-repack-unpack-unreachable.sh
+++ b/t/t7701-repack-unpack-unreachable.sh
@@ -122,4 +122,19 @@ test_expect_success 'keep packed objects found only in 
index' '
git cat-file blob :file
 '
 
+test_expect_success 'repack -k keeps unreachable packed objects' '
+   # create packed-but-unreachable object
+   sha1=$(echo unreachable-packed | git hash-object -w --stdin) &&
+   pack=$(echo $sha1 | git pack-objects .git/objects/pack/pack) &&
+   git prune-packed

[PATCH 1/3] repack: document --unpack-unreachable option

2016-06-12 Thread Jeff King
This was added back in 7e52f56 (gc: do not explode objects
which will be immediately pruned, 2012-04-07), but not
documented at the time, since it was an internal detail
between git-gc and git-repack. However, as people with
complicated setups may want to effectively reimplement the
steps of git-gc themselves, it is nice for us to document
these interfaces.

Signed-off-by: Jeff King 
---
 Documentation/git-repack.txt | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index b9c02ce..cde7b44 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -128,6 +128,12 @@ other objects in that pack they already have locally.
with `-b` or `repack.writeBitmaps`, as it ensures that the
bitmapped packfile has the necessary objects.
 
+--unpack-unreachable=::
+   When loosening unreachable objects, do not bother loosening any
+   objects older than ``. This can be used to optimize out
+   the write of any objects that would be immediately pruned by
+   a follow-up `git prune`.
+
 Configuration
 -
 
-- 
2.9.0.rc2.149.gd580ccd

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


[PATCH 0/3] repack --keep-unreachable

2016-06-12 Thread Jeff King
On Sun, Jun 12, 2016 at 07:43:27PM -0600, Nasser Grainawi wrote:

> On Jun 12, 2016, at 4:13 PM, Jeff King  wrote:
> > 
> >At GitHub we actually have a patch to `repack` that keeps all
> >objects, reachable or not, in the pack, and use it for all of our
> >automated maintenance. Since we don't drop objects at all, we can't
> >ever have such a race. Aside from some pathological cases, it wastes
> >much less space than you'd expect. We turn the flag off for special
> >cases (e.g., somebody has rewound history and wants to expunge a
> >sensitive object).
> > 
> >I'm happy to share the "keep everything" patch if you're interested.
> 
> We have the same kind of patch actually (for the same reason), but
> back on the shell implementation of repack. It'd be great if you could
> share your modern version.

Here is a cleaned-up version of what we run at GitHub (so this is a
concept that has been exercised for a few years in production, but I had
to forward port the patches a bit; I _probably_ didn't introduce any
bugs. :) ).

The heavy lifting is done by the existing --keep-unreachable option to
pack-objects, which Junio added a long time ago[1] in support of a safer
"gc --auto". But it doesn't look like we ever documented or exercised
it, and "gc --auto" ended up using the loosen-unreachable strategy
instead. In fact, the rest of that series seems to have been dropped; I
couldn't find any discussion on the list explaining it, or why this one
patch was kept (so I don't think anybody upstream has ever used this
code, but as I said, we have been doing so for a few years, so I feel
confident in it).

  [1/3]: repack: document --unpack-unreachable option
  [2/3]: repack: add --keep-unreachable option
  [3/3]: repack: extend --keep-unreachable to loose objects

-Peff

[1] http://article.gmane.org/gmane.comp.version-control.git/58413
--
To unsubscribe from this list: send the line "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: Repacking a repository uses up all available disk space

2016-06-12 Thread Nasser Grainawi
On Jun 12, 2016, at 4:13 PM, Jeff King  wrote:
> 
>At GitHub we actually have a patch to `repack` that keeps all
>objects, reachable or not, in the pack, and use it for all of our
>automated maintenance. Since we don't drop objects at all, we can't
>ever have such a race. Aside from some pathological cases, it wastes
>much less space than you'd expect. We turn the flag off for special
>cases (e.g., somebody has rewound history and wants to expunge a
>sensitive object).
> 
>I'm happy to share the "keep everything" patch if you're interested.

We have the same kind of patch actually (for the same reason), but back on the 
shell implementation of repack. It'd be great if you could share your modern 
version.

Nasser

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, 
a Linux Foundation Collaborative Project

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


Re: [GIT PULL] l10n updates for 2.9.0 rc0

2016-06-12 Thread Junio C Hamano
Jiang Xin  writes:

> Please pull the following git l10n updates.
>
> The following changes since commit 3a0f269e7c82aa3a87323cb7ae04ac5f129f036b:
>
>   Git 2.9-rc0 (2016-05-23 15:02:48 -0700)
>
> are available in the git repository at:
>
>   git://github.com/git-l10n/git-po tags/l10n-2.9.0-rc0
>
> for you to fetch changes up to ad583ebe0813c5d6a8e7c263d72d934770083d83:
>
>   l10n: ko.po: Update Korean translation (2016-06-12 01:25:58 +0900)

Thanks, will do.

>
> 
> l10n-2.9.0-rc0
>
> 
> Alexander Shopov (1):
>   l10n: Updated Bulgarian translation of git (2597t,0f,0u)
>
> Antonin (1):
>   l10n: fr.po Fixed grammar mistake
>
> Changwoo Ryu (1):
>   l10n: ko.po: Update Korean translation
>
> Dimitriy Ryazantcev (1):
>   l10n: ru.po: update Russian translation
>
> Jean-Noel Avila (1):
>   l10n: fr.po v2.9.0rnd1
>
> Jiang Xin (5):
>   l10n: git.pot: v2.9.0 round 1 (104 new, 37 removed)
>   Merge branch 'fix_fr' of git://github.com/jnavila/git
>   Merge branch 'v2.9.0_rnd1_fr' of git://github.com/jnavila/git
>   l10n: zh_CN: for git v2.9.0 l10n round 1
>   Merge branch 'russian-l10n' of https://github.com/DJm00n/git-po-ru
>
> Peter Krefting (1):
>   l10n: sv.po: Update Swedish translation (2597t0f0u)
>
> Ralf Thielow (1):
>   l10n: de.po: translate 104 new messages
>
> Ray Chen (1):
>   l10n: zh_CN: review for git v2.9.0 l10n round 1
>
> Trần Ngọc Quân (1):
>   l10n: Updated Vietnamese translation (2597t)
>
> Vasco Almeida (3):
>   l10n: pt_PT: merge git.pot file
>   l10n: pt_PT: update according to git-gui glossary
>   l10n: pt_PT: update Portuguese translation
>
>  po/bg.po| 4689 
> +--
>  po/de.po| 3310 +++--
>  po/fr.po| 3252 +++--
>  po/git.pot  | 3078 ++-
>  po/ko.po| 3192 ++--
>  po/pt_PT.po | 3893 +++--
>  po/ru.po| 3171 ++--
>  po/sv.po| 3269 +++--
>  po/vi.po| 3274 +++--
>  po/zh_CN.po | 3375 ++
>  10 files changed, 19378 insertions(+), 15125 deletions(-)
>
> --
> Jiang Xin
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Repacking a repository uses up all available disk space

2016-06-12 Thread Duy Nguyen
On Mon, Jun 13, 2016 at 5:13 AM, Jeff King  wrote:
> On Sun, Jun 12, 2016 at 05:54:36PM -0400, Konstantin Ryabitsev wrote:
>
>> >   git gc --prune=now
>>
>> You are correct, this solves the problem, however I'm curious. The usual
>> maintenance for these repositories is a regular run of:
>>
>> - git fsck --full
>> - git repack -Adl -b --pack-kept-objects
>> - git pack-refs --all
>> - git prune
>>
>> The reason it's split into repack + prune instead of just gc is because
>> we use alternates to save on disk space and try not to prune repos that
>> are used as alternates by other repos in order to avoid potential
>> corruption.

Isn't this what extensions.preciousObjects is for? It looks like prune
just refuses to run in precious objects mode though, and repack is
skipped by gc, but if that repack command works, maybe we should do
something like that in git-gc?

BTW Jeff, I think we need more documentation for
extensions.preciousObjects. It's only documented in technical/ which
is practically invisible to all users. Maybe
include::repository-version.txt in config.txt, or somewhere close to
alternates?

> [2] It's unclear to me if you're passing any options to git-prune, but
> you may want to pass "--expire" with a short grace period. Without
> any options it prunes every unreachable thing, which can lead to
> races if the repository is actively being used.
>
> At GitHub we actually have a patch to `repack` that keeps all
> objects, reachable or not, in the pack, and use it for all of our
> automated maintenance. Since we don't drop objects at all, we can't
> ever have such a race. Aside from some pathological cases, it wastes
> much less space than you'd expect. We turn the flag off for special
> cases (e.g., somebody has rewound history and wants to expunge a
> sensitive object).
>
> I'm happy to share the "keep everything" patch if you're interested.

Ah ok, I guess this is why we just skip repack. I guess '-Adl -b
--pack-kept-objects' is not enough then.
-- 
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] parse-options-cb.c: use string_list_append_nodup in OPT_STRING_LIST()

2016-06-12 Thread Duy Nguyen
On Mon, Jun 13, 2016 at 5:03 AM, Jeff King  wrote:
> On Fri, Jun 10, 2016 at 06:57:26PM +0700, Nguyễn Thái Ngọc Duy wrote:
>
>> If the given string list has strdup_strings set (*), the string will be
>> duplicated again. Pointless and leak memory. Ignore that flag.
>>
>> (*) only interpret-trailers.c does it at the moment
>>
>> Signed-off-by: Nguyễn Thái Ngọc Duy 
>> ---
>>  parse-options-cb.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/parse-options-cb.c b/parse-options-cb.c
>> index 239898d..8a1b6e6 100644
>> --- a/parse-options-cb.c
>> +++ b/parse-options-cb.c
>> @@ -144,7 +144,7 @@ int parse_opt_string_list(const struct option *opt, 
>> const char *arg, int unset)
>>   if (!arg)
>>   return -1;
>>
>> - string_list_append(v, xstrdup(arg));
>> + string_list_append_nodup(v, xstrdup(arg));
>
> Hmm. So I agree this is an improvement, in the sense that we are
> double-allocating when v->strdup_strings is set.  But I think there's a
> deeper issue here. Why are we always allocating in the first place?
>
> If the memory we are getting in "arg" is not stable, then we _do_ need
> to make a copy of it. But in that case, we want "strdup_strings" to be
> set; without it any time we later run string_list_clear(), we leak the
> allocated memory, because the struct has no idea that it is the owner of
> the memory (and we do call string_list_clear() when we see "--no-foo").
>
> If the memory _is_ stable, then we are fine to add a direct reference to
> it, and can lose the extra xstrdup() here. Only the caller knows for
> sure, so we should be respecting their value of strdup_strings (so lose
> the xstrdup, but keep calling string_list_append()).
>
> In practice, I suspect the memory _is_ stable, because we are generally
> parsing command-line arguments. But it does not hurt to stay on the
> conservative side, and always make a copy (in case we are parsing
> something besides the global argv array) . Apparently I am the original
> author of this code, in c8ba163 (parse-options: add OPT_STRING_LIST
> helper, 2011-06-09), but there's no mention of this point there, in the
> list archives, or in my brain.
>
> So if we are doing the conservative thing, then I think the resulting
> code should either look like:
>
>   if (!v->strdup_strings)
> die("BUG: OPT_STRING_LIST should always use strdup_strings");
>   string_list_append(v, arg);

I agree with the analysis. But this die() would hit all callers
(except interpret-trailers) because they all initialize with _NODUP
and setting strdup_strings may require auditing all access to the
string list in question, e.g. to change string_list_append(v,
xstrdup(xxx)) to string_list_append(xxx). it may cause side effects if
we are not careful.

So far all callers are in builtin/, I think it will not take much time
to verify that they all call parse_options() with global argv, then we
can just lose extra xstrdup() and stick to string_list_append().
OPTION_STRING already assumes that argument strings are stable because
they are passed back as-is. Can we go with an easier route, adding a
comment on top of parse_options() stating that argv[] pointers may be
passed back as-is and it's up to the caller to xstrdup() appropriately
before argv[] memory is freed?

>
> or:
>
>   /* silently enable for convenience */
>   v->strdup_strings = 1;
>   string_list_append(v, arg);
>
> Of the two, I like the top one as it is less magical, but it would
> require adjusting the initialization of the string-list for most of the
> callers.
>
> -Peff



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


Re: Repacking a repository uses up all available disk space

2016-06-12 Thread Jeff King
On Sun, Jun 12, 2016 at 05:54:36PM -0400, Konstantin Ryabitsev wrote:

> >   git gc --prune=now
> 
> You are correct, this solves the problem, however I'm curious. The usual
> maintenance for these repositories is a regular run of:
> 
> - git fsck --full
> - git repack -Adl -b --pack-kept-objects
> - git pack-refs --all
> - git prune
> 
> The reason it's split into repack + prune instead of just gc is because
> we use alternates to save on disk space and try not to prune repos that
> are used as alternates by other repos in order to avoid potential
> corruption.
> 
> Am I not doing something that needs to be doing in order to avoid the
> same problem?

Your approach makes sense; we do the same thing at GitHub for the same
reasons[1]. The main thing you are missing that gc will do is that it
knows the prune-time it is going to feed to git-prune[2], and passes
that along to repack. That's what enables the "don't bother ejecting
these, because I'm about to delete them" optimization.

That option is not documented, because it was always assumed to be an
internal thing to git-gc, but it is:

  git repack ... --unpack-unreachable=5.minutes.ago

or whatever.

-Peff

[1] We don't run the fsck at the front, though, because it's really
expensive.  I'm not sure it buys you much, either. The repack
will do a full walk of the graph, so it gets you a connectivity
check, as well as a full content check of the commits and trees. The
blobs are copied as-is from the old pack, but there is a checksum on
the pack data (to catch any bit flips by the disk storage). So the
only thing the fsck is getting you is that it fully reconstructs the
deltas for each blob and checks their sha1. That's more robust than
a checksum, but it's a lot more expensive.

[2] It's unclear to me if you're passing any options to git-prune, but
you may want to pass "--expire" with a short grace period. Without
any options it prunes every unreachable thing, which can lead to
races if the repository is actively being used.

At GitHub we actually have a patch to `repack` that keeps all
objects, reachable or not, in the pack, and use it for all of our
automated maintenance. Since we don't drop objects at all, we can't
ever have such a race. Aside from some pathological cases, it wastes
much less space than you'd expect. We turn the flag off for special
cases (e.g., somebody has rewound history and wants to expunge a
sensitive object).

I'm happy to share the "keep everything" patch if you're interested.
--
To unsubscribe from this list: send the line "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] parse-options-cb.c: use string_list_append_nodup in OPT_STRING_LIST()

2016-06-12 Thread Jeff King
On Fri, Jun 10, 2016 at 06:57:26PM +0700, Nguyễn Thái Ngọc Duy wrote:

> If the given string list has strdup_strings set (*), the string will be
> duplicated again. Pointless and leak memory. Ignore that flag.
> 
> (*) only interpret-trailers.c does it at the moment
> 
> Signed-off-by: Nguyễn Thái Ngọc Duy 
> ---
>  parse-options-cb.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/parse-options-cb.c b/parse-options-cb.c
> index 239898d..8a1b6e6 100644
> --- a/parse-options-cb.c
> +++ b/parse-options-cb.c
> @@ -144,7 +144,7 @@ int parse_opt_string_list(const struct option *opt, const 
> char *arg, int unset)
>   if (!arg)
>   return -1;
>  
> - string_list_append(v, xstrdup(arg));
> + string_list_append_nodup(v, xstrdup(arg));

Hmm. So I agree this is an improvement, in the sense that we are
double-allocating when v->strdup_strings is set.  But I think there's a
deeper issue here. Why are we always allocating in the first place?

If the memory we are getting in "arg" is not stable, then we _do_ need
to make a copy of it. But in that case, we want "strdup_strings" to be
set; without it any time we later run string_list_clear(), we leak the
allocated memory, because the struct has no idea that it is the owner of
the memory (and we do call string_list_clear() when we see "--no-foo").

If the memory _is_ stable, then we are fine to add a direct reference to
it, and can lose the extra xstrdup() here. Only the caller knows for
sure, so we should be respecting their value of strdup_strings (so lose
the xstrdup, but keep calling string_list_append()).

In practice, I suspect the memory _is_ stable, because we are generally
parsing command-line arguments. But it does not hurt to stay on the
conservative side, and always make a copy (in case we are parsing
something besides the global argv array) . Apparently I am the original
author of this code, in c8ba163 (parse-options: add OPT_STRING_LIST
helper, 2011-06-09), but there's no mention of this point there, in the
list archives, or in my brain.

So if we are doing the conservative thing, then I think the resulting
code should either look like:

  if (!v->strdup_strings)
die("BUG: OPT_STRING_LIST should always use strdup_strings");
  string_list_append(v, arg);

or:

  /* silently enable for convenience */
  v->strdup_strings = 1;
  string_list_append(v, arg);

Of the two, I like the top one as it is less magical, but it would
require adjusting the initialization of the string-list for most of the
callers.

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


Re: Repacking a repository uses up all available disk space

2016-06-12 Thread Konstantin Ryabitsev
On Sun, Jun 12, 2016 at 05:38:04PM -0400, Jeff King wrote:
> > - When attempting to repack, creates millions of files and eventually
> >   eats up all available disk space
> 
> That means these objects fall into the unreachable category. Git will
> prune unreachable loose objects after a grace period based on the
> filesystem mtime of the objects; the default is 2 weeks.
> 
> For unreachable packed objects, their mtime is jumbled in with the rest
> of the objects in the packfile.  So Git's strategy is to "eject" such
> objects from the packfiles into individual loose objects, and let them
> "age out" of the grace period individually.
> 
> Generally this works just fine, but there are corner cases where you
> might have a very large number of such objects, and the loose storage is
> much more expensive than the packed (e.g., because each object is stored
> individually, not as a delta).
> 
> It sounds like this is the case you're running into.
> 
> The solution is to lower the grace period time, with something like:
> 
>   git gc --prune=5.minutes.ago
> 
> or even:
> 
>   git gc --prune=now

You are correct, this solves the problem, however I'm curious. The usual
maintenance for these repositories is a regular run of:

- git fsck --full
- git repack -Adl -b --pack-kept-objects
- git pack-refs --all
- git prune

The reason it's split into repack + prune instead of just gc is because
we use alternates to save on disk space and try not to prune repos that
are used as alternates by other repos in order to avoid potential
corruption.

Am I not doing something that needs to be doing in order to avoid the
same problem?

Thanks for your help.

Regards,
-- 
Konstantin Ryabitsev
Linux Foundation Collab Projects
Montréal, Québec


signature.asc
Description: PGP signature


Re: Repacking a repository uses up all available disk space

2016-06-12 Thread Jeff King
On Sun, Jun 12, 2016 at 05:25:14PM -0400, Konstantin Ryabitsev wrote:

> Hello:
> 
> I have a problematic repository that:
> 
> - Takes up 9GB on disk
> - Passes 'git fsck --full' with no errors
> - When cloned with --mirror, takes up 38M on the target system

Cloning will only copy the objects that are reachable from the refs. So
presumably the other 8.9GB is either reachable from reflogs, or not
reachable at all (due to rewinding history or deleting branches).

> - When attempting to repack, creates millions of files and eventually
>   eats up all available disk space

That means these objects fall into the unreachable category. Git will
prune unreachable loose objects after a grace period based on the
filesystem mtime of the objects; the default is 2 weeks.

For unreachable packed objects, their mtime is jumbled in with the rest
of the objects in the packfile.  So Git's strategy is to "eject" such
objects from the packfiles into individual loose objects, and let them
"age out" of the grace period individually.

Generally this works just fine, but there are corner cases where you
might have a very large number of such objects, and the loose storage is
much more expensive than the packed (e.g., because each object is stored
individually, not as a delta).

It sounds like this is the case you're running into.

The solution is to lower the grace period time, with something like:

  git gc --prune=5.minutes.ago

or even:

  git gc --prune=now

That will prune the unreachable objects immediately (and the packfile
ejector is smart enough to skip ejecting any file that would just get
deleted immediately anyway).

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


Repacking a repository uses up all available disk space

2016-06-12 Thread Konstantin Ryabitsev
Hello:

I have a problematic repository that:

- Takes up 9GB on disk
- Passes 'git fsck --full' with no errors
- When cloned with --mirror, takes up 38M on the target system
- When attempting to repack, creates millions of files and eventually
  eats up all available disk space

Repacking the result of 'git clone --mirror' shows no problem, so it's
got to be something really weird with that particular instance of the
repository.

If anyone is interested in poking at this particular problem to figure
out what causes the repack process to eat up all available disk space,
you can find the tarball of the problematic repository here:

http://mricon.com/misc/src.git.tar.xz (warning: 6.6GB)

You can clone the non-problematic version of this repository from
git://codeaurora.org/quic/chrome4sdp/breakpad/breakpad/src.git

Best,
-- 
Konstantin Ryabitsev
Linux Foundation Collab Projects
Montréal, Québec


signature.asc
Description: PGP signature


[PATCH] Document the 'svn propset' command.

2016-06-12 Thread Alfred Perlstein
Junio + all,

A week ago I was requested to provide documentation for the
'svn propset' command.  I have attached a diff off of the
'maint' branch for this, however it seems to apply cleanly
to 'master' as well.

Thank you for your patience.

This is also available on my github here:
https://github.com/splbio/git/tree/document_propset


---
 Documentation/git-svn.txt | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index fb23a98..e104824 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -459,6 +459,20 @@ Any other arguments are passed directly to 'git log'
Gets the Subversion property given as the first argument, for a
file.  A specific revision can be specified with -r/--revision.
 
+'propset'::
+   Sets the Subversion property given as the first argument, to the
+   value given as the second argument for the file given as the
+   third argument.
++
+Example:
++
+
+git svn propset svn:keywords "FreeBSD=%H" devel/py-tipper/Makefile
+
++
+This will set the property 'svn:keywords' to 'FreeBSD=%H' for the file
+'devel/py-tipper/Makefile'.
+
 'show-externals'::
Shows the Subversion externals.  Use -r/--revision to specify a
specific revision.
-- 
2.7.1

--
To unsubscribe from this list: send the line "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: lib-httpd/apache.conf and mod_unixd.so

2016-06-12 Thread Duy Nguyen
On Sun, Jun 12, 2016 at 8:00 PM, Jeff King  wrote:
> On Sun, Jun 12, 2016 at 05:48:42PM +0700, Duy Nguyen wrote:
>
>> A quick search shows that loading mod_unixd.so will do (and did make
>> httpd run for me). Problem is, can I just update apache.conf to load
>> it when apache version >= 2.4? I don't know if doing that would cause
>> failure for other people because mod_unixd has existed since 2.2 and
>> people have run httpd tests fine so far...
>
> Are you running a version that has 5922322 (t/lib-httpd: load mod_unixd,
> 2015-05-11)?

Nope. This is nd/shallow-deepen which has a really old base. Good to
know it's already fixed.
-- 
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


[no subject]

2016-06-12 Thread Financial Service
Greetings,  Have you been looking for finance options for your new home 
purchase, construction, refinance, medical cash, family cash, personal or 
business purpose. Welcome to the future! Finance made easy with us. Contact us 
as we offer our finance service at a low and affordable interest rate for long 
and short cash term,reply to this Email for more Info
--
To unsubscribe from this list: send the line "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: lib-httpd/apache.conf and mod_unixd.so

2016-06-12 Thread Jeff King
On Sun, Jun 12, 2016 at 05:48:42PM +0700, Duy Nguyen wrote:

> A quick search shows that loading mod_unixd.so will do (and did make
> httpd run for me). Problem is, can I just update apache.conf to load
> it when apache version >= 2.4? I don't know if doing that would cause
> failure for other people because mod_unixd has existed since 2.2 and
> people have run httpd tests fine so far...

Are you running a version that has 5922322 (t/lib-httpd: load mod_unixd,
2015-05-11)?

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


Re: [PATCH] lib-httpd.sh: print error.log on error

2016-06-12 Thread Jeff King
On Sun, Jun 12, 2016 at 05:41:54PM +0700, Nguyễn Thái Ngọc Duy wrote:

> Failure to bring up httpd for testing is not considered an error, so the
> trash directory, which contains this error.log file, is removed and we
> don't know what made httpd fail to start. Improve the situation a bit.
> 
> Signed-off-by: Nguyễn Thái Ngọc Duy 
> ---
>  t/lib-httpd.sh | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
> index f9f3e5f..5b8de38 100644
> --- a/t/lib-httpd.sh
> +++ b/t/lib-httpd.sh
> @@ -180,6 +180,7 @@ start_httpd() {
>   if test $? -ne 0
>   then
>   trap 'die' EXIT
> + cat "$HTTPD_ROOT_PATH"/error.log 2>/dev/null
>   test_skip_or_die $GIT_TEST_HTTPD "web server setup failed"
>   fi

I like the idea of giving more data on error, but I think this will
break the TAP output and confuse anything parsing the output of the
tests, like prove (I think arbitrary output should have "#" prepended).

Also (or alternatively), it should probably only happen when we are in
verbose mode (it's not taken care of for us as usual because tests call
start_httpd outside of a test_expect_ block). I think this eliminates
the need to deal with the TAP thing (because our usual "-v" output is
not TAP-compliant).

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


[PATCH v2 27/27] fetch, upload-pack: --deepen=N extends shallow boundary by N commits

2016-06-12 Thread Nguyễn Thái Ngọc Duy
In git-fetch, --depth argument is always relative with the latest
remote refs. This makes it a bit difficult to cover this use case,
where the user wants to make the shallow history, say 3 levels
deeper. It would work if remote refs have not moved yet, but nobody
can guarantee that, especially when that use case is performed a
couple months after the last clone or "git fetch --depth". Also,
modifying shallow boundary using --depth does not work well with
clones created by --since or --not.

This patch fixes that. A new argument --deepen= will add  more (*)
parent commits to the current history regardless of where remote refs
are.

Have/Want negotiation is still respected. So if remote refs move, the
server will send two chunks: one between "have" and "want" and another
to extend shallow history. In theory, the client could send no "want"s
in order to get the second chunk only. But the protocol does not allow
that. Either you send no want lines, which means ls-remote; or you
have to send at least one want line that carries deep-relative to the
server..

The main work was done by Dongcan Jiang. I fixed it up here and there.
And of course all the bugs belong to me.

(*) We could even support --deepen= where  is negative. In that
case we can cut some history from the shallow clone. This operation
(and --depth=) does not require interaction with remote
side (and more complicated to implement as a result).

Helped-by: Duy Nguyen 
Helped-by: Eric Sunshine 
Helped-by: Junio C Hamano 
Signed-off-by: Dongcan Jiang 
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Documentation/fetch-options.txt   |  5 +
 Documentation/git-fetch-pack.txt  |  5 +
 Documentation/gitremote-helpers.txt   |  4 
 Documentation/technical/protocol-capabilities.txt |  7 ++
 builtin/fetch-pack.c  |  4 
 builtin/fetch.c   | 14 +++-
 fetch-pack.c  |  3 +++
 fetch-pack.h  |  1 +
 remote-curl.c | 14 +++-
 t/t5500-fetch-pack.sh | 23 
 t/t5539-fetch-http-shallow.sh | 26 +++
 transport-helper.c|  1 +
 transport.c   |  4 
 transport.h   |  4 
 upload-pack.c | 23 
 15 files changed, 132 insertions(+), 6 deletions(-)

diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 7aa1285..3b91f15 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -14,6 +14,11 @@
linkgit:git-clone[1]), deepen or shorten the history to the specified
number of commits. Tags for the deepened commits are not fetched.
 
+--deepen=::
+   Similar to --depth, except it specifies the number of commits
+   from the current shallow boundary instead of from the tip of
+   each remote branch history.
+
 --shallow-since=::
Deepen or shorten the history of a shallow repository to
include all reachable commits after .
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
index 4d15b04..c20958f 100644
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -96,6 +96,11 @@ be in a separate packet, and the list must end with a flush 
packet.
exclude commits reachable from a specified remote branch or tag.
This option can be specified multiple times.
 
+--deepen-relative::
+   Argument --depth specifies the number of commits from the
+   current shallow boundary instead of from the tip of each
+   remote branch history.
+
 --no-progress::
Do not show the progress.
 
diff --git a/Documentation/gitremote-helpers.txt 
b/Documentation/gitremote-helpers.txt
index 75bb638..6fca268 100644
--- a/Documentation/gitremote-helpers.txt
+++ b/Documentation/gitremote-helpers.txt
@@ -422,6 +422,10 @@ set by Git if the remote helper has the 'option' 
capability.
Deepens the history of a shallow repository excluding ref.
Multiple options add up.
 
+'option deepen-relative {'true'|'false'}::
+   Deepens the history of a shallow repository relative to
+   current boundary. Only valid when used with "option depth".
+
 'option followtags' {'true'|'false'}::
If enabled the helper should automatically fetch annotated
tag objects if the object the tag points at was transferred
diff --git a/Documentation/technical/protocol-capabilities.txt 
b/Documentation/technical/protocol-capabilities.txt
index 0e6b57d..4fd6dcc 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -197,6 +197,13 @@ specific revision, instead of depth. Internally it's 

[PATCH v2 26/27] upload-pack: add get_reachable_list()

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 object.h  |  2 +-
 upload-pack.c | 52 +---
 2 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/object.h b/object.h
index f8b6442..614a006 100644
--- a/object.h
+++ b/object.h
@@ -31,7 +31,7 @@ struct object_array {
  * revision.h:  0-1026
  * fetch-pack.c:0---4
  * walker.c:0-2
- * upload-pack.c:   1119
+ * upload-pack.c:   4   1119
  * builtin/blame.c:   12-13
  * bisect.c:   16
  * bundle.c:   16
diff --git a/upload-pack.c b/upload-pack.c
index adb8e33..3227df8 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -456,7 +456,8 @@ static int is_our_ref(struct object *o)
  * on successful case, it's up to the caller to close cmd->out
  */
 static int do_reachable_revlist(struct child_process *cmd,
-   struct object_array *src)
+   struct object_array *src,
+   struct object_array *reachable)
 {
static const char *argv[] = {
"rev-list", "--stdin", NULL,
@@ -487,6 +488,8 @@ static int do_reachable_revlist(struct child_process *cmd,
o = get_indexed_object(--i);
if (!o)
continue;
+   if (reachable && o->type == OBJ_COMMIT)
+   o->flags &= ~TMP_MARK;
if (!is_our_ref(o))
continue;
memcpy(namebuf + 1, oid_to_hex(&o->oid), GIT_SHA1_HEXSZ);
@@ -496,8 +499,13 @@ static int do_reachable_revlist(struct child_process *cmd,
namebuf[40] = '\n';
for (i = 0; i < src->nr; i++) {
o = src->objects[i].item;
-   if (is_our_ref(o))
+   if (is_our_ref(o)) {
+   if (reachable)
+   add_object_array(o, NULL, reachable);
continue;
+   }
+   if (reachable && o->type == OBJ_COMMIT)
+   o->flags |= TMP_MARK;
memcpy(namebuf, oid_to_hex(&o->oid), GIT_SHA1_HEXSZ);
if (write_in_full(cmd->in, namebuf, 41) < 0)
goto error;
@@ -518,13 +526,51 @@ error:
return -1;
 }
 
+static int get_reachable_list(struct object_array *src,
+ struct object_array *reachable)
+{
+   struct child_process cmd = CHILD_PROCESS_INIT;
+   int i;
+   struct object *o;
+   char namebuf[42]; /* ^ + SHA-1 + LF */
+
+   if (do_reachable_revlist(&cmd, src, reachable) < 0)
+   return -1;
+
+   while ((i = read_in_full(cmd.out, namebuf, 41)) == 41) {
+   struct object_id sha1;
+
+   if (namebuf[40] != '\n' || get_oid_hex(namebuf, &sha1))
+   break;
+
+   o = lookup_object(sha1.hash);
+   if (o && o->type == OBJ_COMMIT) {
+   o->flags &= ~TMP_MARK;
+   }
+   }
+   for (i = get_max_object_index(); 0 < i; i--) {
+   o = get_indexed_object(i - 1);
+   if (o && o->type == OBJ_COMMIT &&
+   (o->flags & TMP_MARK)) {
+   add_object_array(o, NULL, reachable);
+   o->flags &= ~TMP_MARK;
+   }
+   }
+   close(cmd.out);
+
+   if (finish_command(&cmd))
+   return -1;
+
+   return 0;
+}
+
 static int has_unreachable(struct object_array *src)
 {
struct child_process cmd = CHILD_PROCESS_INIT;
char buf[1];
int i;
 
-   if (do_reachable_revlist(&cmd, src) < 0)
+   if (do_reachable_revlist(&cmd, src, NULL) < 0)
return 1;
 
/*
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 25/27] upload-pack: split check_unreachable() in two, prep for get_reachable_list()

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 upload-pack.c | 56 ++--
 1 file changed, 38 insertions(+), 18 deletions(-)

diff --git a/upload-pack.c b/upload-pack.c
index acc6d97..adb8e33 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -452,21 +452,24 @@ static int is_our_ref(struct object *o)
return o->flags & ((allow_hidden_ref ? HIDDEN_REF : 0) | OUR_REF);
 }
 
-static int has_unreachable(struct object_array *src)
+/*
+ * on successful case, it's up to the caller to close cmd->out
+ */
+static int do_reachable_revlist(struct child_process *cmd,
+   struct object_array *src)
 {
static const char *argv[] = {
"rev-list", "--stdin", NULL,
};
-   static struct child_process cmd = CHILD_PROCESS_INIT;
struct object *o;
char namebuf[42]; /* ^ + SHA-1 + LF */
int i;
 
-   cmd.argv = argv;
-   cmd.git_cmd = 1;
-   cmd.no_stderr = 1;
-   cmd.in = -1;
-   cmd.out = -1;
+   cmd->argv = argv;
+   cmd->git_cmd = 1;
+   cmd->no_stderr = 1;
+   cmd->in = -1;
+   cmd->out = -1;
 
/*
 * If the next rev-list --stdin encounters an unknown commit,
@@ -475,7 +478,7 @@ static int has_unreachable(struct object_array *src)
 */
sigchain_push(SIGPIPE, SIG_IGN);
 
-   if (start_command(&cmd))
+   if (start_command(cmd))
goto error;
 
namebuf[0] = '^';
@@ -487,7 +490,7 @@ static int has_unreachable(struct object_array *src)
if (!is_our_ref(o))
continue;
memcpy(namebuf + 1, oid_to_hex(&o->oid), GIT_SHA1_HEXSZ);
-   if (write_in_full(cmd.in, namebuf, 42) < 0)
+   if (write_in_full(cmd->in, namebuf, 42) < 0)
goto error;
}
namebuf[40] = '\n';
@@ -496,17 +499,39 @@ static int has_unreachable(struct object_array *src)
if (is_our_ref(o))
continue;
memcpy(namebuf, oid_to_hex(&o->oid), GIT_SHA1_HEXSZ);
-   if (write_in_full(cmd.in, namebuf, 41) < 0)
+   if (write_in_full(cmd->in, namebuf, 41) < 0)
goto error;
}
-   close(cmd.in);
-   cmd.in = -1;
+   close(cmd->in);
+   cmd->in = -1;
+   sigchain_pop(SIGPIPE);
+
+   return 0;
+
+error:
+   sigchain_pop(SIGPIPE);
+
+   if (cmd->in >= 0)
+   close(cmd->in);
+   if (cmd->out >= 0)
+   close(cmd->out);
+   return -1;
+}
+
+static int has_unreachable(struct object_array *src)
+{
+   struct child_process cmd = CHILD_PROCESS_INIT;
+   char buf[1];
+   int i;
+
+   if (do_reachable_revlist(&cmd, src) < 0)
+   return 1;
 
/*
 * The commits out of the rev-list are not ancestors of
 * our ref.
 */
-   i = read_in_full(cmd.out, namebuf, 1);
+   i = read_in_full(cmd.out, buf, 1);
if (i)
goto error;
close(cmd.out);
@@ -520,16 +545,11 @@ static int has_unreachable(struct object_array *src)
if (finish_command(&cmd))
goto error;
 
-   sigchain_pop(SIGPIPE);
-
/* All the non-tip ones are ancestors of what we advertised */
return 0;
 
 error:
sigchain_pop(SIGPIPE);
-
-   if (cmd.in >= 0)
-   close(cmd.in);
if (cmd.out >= 0)
close(cmd.out);
return 1;
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 24/27] t5500, t5539: tests for shallow depth excluding a ref

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 t/t5500-fetch-pack.sh | 21 +
 t/t5539-fetch-http-shallow.sh | 22 ++
 2 files changed, 43 insertions(+)

diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 26f050d..145b370 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -661,4 +661,25 @@ test_expect_success 'fetch shallow since ...' '
test_cmp expected actual
 '
 
+test_expect_success 'shallow clone exclude tag two' '
+   test_create_repo shallow-exclude &&
+   (
+   cd shallow-exclude &&
+   test_commit one &&
+   test_commit two &&
+   test_commit three &&
+   git clone --shallow-exclude two "file://$(pwd)/." ../shallow12 &&
+   git -C ../shallow12 log --pretty=tformat:%s HEAD >actual &&
+   echo three >expected &&
+   test_cmp expected actual
+   )
+'
+
+test_expect_success 'fetch exclude tag one' '
+   git -C shallow12 fetch --shallow-exclude one origin &&
+   git -C shallow12 log --pretty=tformat:%s origin/master >actual &&
+   test_write_lines three two >expected &&
+   test_cmp expected actual
+'
+
 test_done
diff --git a/t/t5539-fetch-http-shallow.sh b/t/t5539-fetch-http-shallow.sh
index 704753c..8e38c1b 100755
--- a/t/t5539-fetch-http-shallow.sh
+++ b/t/t5539-fetch-http-shallow.sh
@@ -98,5 +98,27 @@ test_expect_success 'fetch shallow since ...' '
test_cmp expected actual
 '
 
+test_expect_success 'shallow clone exclude tag two' '
+   test_create_repo shallow-exclude &&
+   (
+   cd shallow-exclude &&
+   test_commit one &&
+   test_commit two &&
+   test_commit three &&
+   mv .git "$HTTPD_DOCUMENT_ROOT_PATH/shallow-exclude.git" &&
+   git clone --shallow-exclude two $HTTPD_URL/smart/shallow-exclude.git 
../shallow12 &&
+   git -C ../shallow12 log --pretty=tformat:%s HEAD >actual &&
+   echo three >expected &&
+   test_cmp expected actual
+   )
+'
+
+test_expect_success 'fetch exclude tag one' '
+   git -C shallow12 fetch --shallow-exclude one origin &&
+   git -C shallow12 log --pretty=tformat:%s origin/master >actual &&
+   test_write_lines three two >expected &&
+   test_cmp expected actual
+'
+
 stop_httpd
 test_done
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 21/27] upload-pack: support define shallow boundary by excluding revisions

2016-06-12 Thread Nguyễn Thái Ngọc Duy
This should allow the user to say "create a shallow clone of this branch
after version ".

Short refs are accepted and expanded at the server side with expand_ref()
because we cannot expand (unknown) refs from the client side.

Like deepen-since, deepen-not cannot be used with deepen. But deepen-not
can be mixed with deepen-since. The result is exactly how you do the
command "git rev-list --since=... --not ref".

Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 Documentation/technical/pack-protocol.txt |  3 ++-
 Documentation/technical/protocol-capabilities.txt |  9 +
 upload-pack.c | 23 +--
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/Documentation/technical/pack-protocol.txt 
b/Documentation/technical/pack-protocol.txt
index 9251df1..dee33a6 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -220,7 +220,8 @@ out of what the server said it could do with the first 
'want' line.
   shallow-line  =  PKT-LINE("shallow" SP obj-id)
 
   depth-request =  PKT-LINE("deepen" SP depth) /
-  PKT-LINE("deepen-since" SP timestamp)
+  PKT-LINE("deepen-since" SP timestamp) /
+  PKT-LINE("deepen-not" SP ref)
 
   first-want=  PKT-LINE("want" SP obj-id SP capability-list)
   additional-want   =  PKT-LINE("want" SP obj-id)
diff --git a/Documentation/technical/protocol-capabilities.txt 
b/Documentation/technical/protocol-capabilities.txt
index f08cc4e..0e6b57d 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -188,6 +188,15 @@ specific time, instead of depth. Internally it's 
equivalent of doing
 "rev-list --max-age=" on the server side. "deepen-since"
 cannot be used with "deepen".
 
+deepen-not
+--
+
+This capability adds "deepen-not" command to fetch-pack/upload-pack
+protocol so the client can request shallow clones that are cut at a
+specific revision, instead of depth. Internally it's equivalent of
+doing "rev-list --not " on the server side. "deepen-not"
+cannot be used with "deepen", but can be used with "deepen-since".
+
 no-progress
 ---
 
diff --git a/upload-pack.c b/upload-pack.c
index 5269461..acc6d97 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -645,6 +645,7 @@ static void deepen_by_rev_list(int ac, const char **av,
 static void receive_needs(void)
 {
struct object_array shallows = OBJECT_ARRAY_INIT;
+   struct string_list deepen_not = STRING_LIST_INIT_DUP;
int depth = 0;
int has_non_tip = 0;
unsigned long deepen_since = 0;
@@ -695,6 +696,16 @@ static void receive_needs(void)
deepen_rev_list = 1;
continue;
}
+   if (skip_prefix(line, "deepen-not ", &arg)) {
+   char *ref = NULL;
+   unsigned char sha1[20];
+   if (expand_ref(arg, strlen(arg), sha1, &ref) != 1)
+   die("git upload-pack: ambiguous deepen-not: 
%s", line);
+   string_list_append(&deepen_not, ref);
+   free(ref);
+   deepen_rev_list = 1;
+   continue;
+   }
if (!skip_prefix(line, "want ", &arg) ||
get_sha1_hex(arg, sha1_buf))
die("git upload-pack: protocol error, "
@@ -749,7 +760,7 @@ static void receive_needs(void)
if (depth == 0 && !deepen_rev_list && shallows.nr == 0)
return;
if (depth > 0 && deepen_rev_list)
-   die("git upload-pack: deepen and deepen-since cannot be used 
together");
+   die("git upload-pack: deepen and deepen-since (or deepen-not) 
cannot be used together");
if (depth > 0)
deepen(depth, &shallows);
else if (deepen_rev_list) {
@@ -759,6 +770,14 @@ static void receive_needs(void)
argv_array_push(&av, "rev-list");
if (deepen_since)
argv_array_pushf(&av, "--max-age=%lu", deepen_since);
+   if (deepen_not.nr) {
+   argv_array_push(&av, "--not");
+   for (i = 0; i < deepen_not.nr; i++) {
+   struct string_list_item *s = deepen_not.items + 
i;
+   argv_array_push(&av, s->string);
+   }
+   argv_array_push(&av, "--not");
+   }
for (i = 0; i < want_obj.nr; i++) {
struct object *o = want_obj.objects[i].item;
argv_array_push(&av, oid_to_hex(&o->oid));
@@ -814,7 +833,7 @@ static int send_ref(const char *refname, const struct 
object_id *oid,
int flag, void *cb_data)
 {
s

[PATCH v2 23/27] clone: define shallow clone boundary with --shallow-exclude

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 Documentation/git-clone.txt |  5 +
 builtin/clone.c | 10 +-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index a410409..5049663 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -196,6 +196,11 @@ objects from the source repository into a pack in the 
cloned repository.
 --shallow-since=::
Create a shallow clone with a history after the specified time.
 
+--shallow-exclude=::
+   Create a shallow clone with a history, excluding commits
+   reachable from a specified remote branch or tag.  This option
+   can be specified multiple times.
+
 --[no-]single-branch::
Clone only the history leading to the tip of a single branch,
either specified by the `--branch` option or the primary
diff --git a/builtin/clone.c b/builtin/clone.c
index dc2ef4f..3849231 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -44,6 +44,7 @@ static int deepen;
 static char *option_template, *option_depth, *option_since;
 static char *option_origin = NULL;
 static char *option_branch = NULL;
+static struct string_list option_not = STRING_LIST_INIT_NODUP;
 static const char *real_git_dir;
 static char *option_upload_pack = "git-upload-pack";
 static int option_verbosity;
@@ -89,6 +90,8 @@ static struct option builtin_clone_options[] = {
N_("create a shallow clone of that depth")),
OPT_STRING(0, "shallow-since", &option_since, N_("time"),
N_("create a shallow clone since a specific time")),
+   OPT_STRING_LIST(0, "shallow-exclude", &option_not, N_("revision"),
+   N_("deepen history of shallow clone by excluding rev")),
OPT_BOOL(0, "single-branch", &option_single_branch,
N_("clone only one branch, HEAD or --branch")),
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
@@ -852,7 +855,7 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
usage_msg_opt(_("You must specify a repository to clone."),
builtin_clone_usage, builtin_clone_options);
 
-   if (option_depth || option_since)
+   if (option_depth || option_since || option_not.nr)
deepen = 1;
if (option_single_branch == -1)
option_single_branch = deepen ? 1 : 0;
@@ -983,6 +986,8 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
warning(_("--depth is ignored in local clones; use 
file:// instead."));
if (option_since)
warning(_("--shallow-since is ignored in local clones; 
use file:// instead."));
+   if (option_not.nr)
+   warning(_("--shallow-exclude is ignored in local 
clones; use file:// instead."));
if (!access(mkpath("%s/shallow", path), F_OK)) {
if (option_local > 0)
warning(_("source repository is shallow, 
ignoring --local"));
@@ -1004,6 +1009,9 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
if (option_since)
transport_set_option(transport, TRANS_OPT_DEEPEN_SINCE,
 option_since);
+   if (option_not.nr)
+   transport_set_option(transport, TRANS_OPT_DEEPEN_NOT,
+(const char *)&option_not);
if (option_single_branch)
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");
 
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 22/27] fetch: define shallow boundary with --shallow-exclude

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 Documentation/fetch-options.txt |  5 +
 Documentation/git-fetch-pack.txt|  5 +
 Documentation/gitremote-helpers.txt |  4 
 builtin/fetch-pack.c|  7 +++
 builtin/fetch.c | 13 ++---
 fetch-pack.c| 15 ++-
 fetch-pack.h|  1 +
 remote-curl.c   |  9 +
 transport-helper.c  | 24 
 transport.c |  4 
 transport.h |  6 ++
 11 files changed, 89 insertions(+), 4 deletions(-)

diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 8738d3d..7aa1285 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -18,6 +18,11 @@
Deepen or shorten the history of a shallow repository to
include all reachable commits after .
 
+--shallow-exclude=::
+   Deepen or shorten the history of a shallow repository to
+   exclude commits reachable from a specified remote branch or tag.
+   This option can be specified multiple times.
+
 --unshallow::
If the source repository is complete, convert a shallow
repository to a complete one, removing all the limitations
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
index 99e6257..4d15b04 100644
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -91,6 +91,11 @@ be in a separate packet, and the list must end with a flush 
packet.
Deepen or shorten the history of a shallow'repository to
include all reachable commits after .
 
+--shallow-exclude=::
+   Deepen or shorten the history of a shallow repository to
+   exclude commits reachable from a specified remote branch or tag.
+   This option can be specified multiple times.
+
 --no-progress::
Do not show the progress.
 
diff --git a/Documentation/gitremote-helpers.txt 
b/Documentation/gitremote-helpers.txt
index 9971d9a..75bb638 100644
--- a/Documentation/gitremote-helpers.txt
+++ b/Documentation/gitremote-helpers.txt
@@ -418,6 +418,10 @@ set by Git if the remote helper has the 'option' 
capability.
 'option deepen-since ::
Deepens the history of a shallow repository based on time.
 
+'option deepen-not ::
+   Deepens the history of a shallow repository excluding ref.
+   Multiple options add up.
+
 'option followtags' {'true'|'false'}::
If enabled the helper should automatically fetch annotated
tag objects if the object the tag points at was transferred
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 0402e27..07570be 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -50,6 +50,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char 
*prefix)
struct child_process *conn;
struct fetch_pack_args args;
struct sha1_array shallow = SHA1_ARRAY_INIT;
+   struct string_list deepen_not = STRING_LIST_INIT_DUP;
 
packet_trace_identity("fetch-pack");
 
@@ -108,6 +109,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char 
*prefix)
args.deepen_since = xstrdup(arg);
continue;
}
+   if (skip_prefix(arg, "--shallow-exclude=", &arg)) {
+   string_list_append(&deepen_not, arg);
+   continue;
+   }
if (!strcmp("--no-progress", arg)) {
args.no_progress = 1;
continue;
@@ -135,6 +140,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char 
*prefix)
}
usage(fetch_pack_usage);
}
+   if (deepen_not.nr)
+   args.deepen_not = &deepen_not;
 
if (i < argc)
dest = argv[i++];
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 283aa95..147504d 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -41,6 +41,7 @@ static int max_children = 1;
 static const char *depth;
 static const char *deepen_since;
 static const char *upload_pack;
+static struct string_list deepen_not = STRING_LIST_INIT_NODUP;
 static struct strbuf default_rla = STRBUF_INIT;
 static struct transport *gtransport;
 static struct transport *gsecondary;
@@ -118,6 +119,8 @@ static struct option builtin_fetch_options[] = {
   N_("deepen history of shallow clone")),
OPT_STRING(0, "shallow-since", &deepen_since, N_("time"),
   N_("deepen history of shallow repository based on time")),
+   OPT_STRING_LIST(0, "shallow-exclude", &deepen_not, N_("revision"),
+   N_("deepen history of shallow clone by excluding rev")),
{ OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
   N_("convert to a complete repository"),
   PARSE_

[PATCH v2 20/27] refs: add expand_ref()

2016-06-12 Thread Nguyễn Thái Ngọc Duy
This is basically dwim_ref() without @{} support. To be used on the
server side where we want to expand abbreviated to full ref names and
nothing else. The first user is "git clone/fetch --shallow-exclude".

Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 refs.c | 8 +++-
 refs.h | 1 +
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/refs.c b/refs.c
index e2d34b2..842e4d8 100644
--- a/refs.c
+++ b/refs.c
@@ -392,6 +392,13 @@ static char *substitute_branch_name(const char **string, 
int *len)
 int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
 {
char *last_branch = substitute_branch_name(&str, &len);
+   int   refs_found  = expand_ref(str, len, sha1, ref);
+   free(last_branch);
+   return refs_found;
+}
+
+int expand_ref(const char *str, int len, unsigned char *sha1, char **ref)
+{
const char **p, *r;
int refs_found = 0;
 
@@ -417,7 +424,6 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, 
char **ref)
warning("ignoring broken ref %s.", fullref);
}
}
-   free(last_branch);
return refs_found;
 }
 
diff --git a/refs.h b/refs.h
index 3c3da29..31a2fa6 100644
--- a/refs.h
+++ b/refs.h
@@ -90,6 +90,7 @@ extern int resolve_gitlink_ref(const char *path, const char 
*refname, unsigned c
  */
 extern int refname_match(const char *abbrev_name, const char *full_name);
 
+extern int expand_ref(const char *str, int len, unsigned char *sha1, char 
**ref);
 extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
 extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
 
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 18/27] clone: define shallow clone boundary based on time with --shallow-since

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 Documentation/git-clone.txt |  3 +++
 builtin/clone.c | 16 +---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index b7c467a..a410409 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -193,6 +193,9 @@ objects from the source repository into a pack in the 
cloned repository.
`--no-single-branch` is given to fetch the histories near the
tips of all branches.
 
+--shallow-since=::
+   Create a shallow clone with a history after the specified time.
+
 --[no-]single-branch::
Clone only the history leading to the tip of a single branch,
either specified by the `--branch` option or the primary
diff --git a/builtin/clone.c b/builtin/clone.c
index bcba080..dc2ef4f 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -40,7 +40,8 @@ static const char * const builtin_clone_usage[] = {
 
 static int option_no_checkout, option_bare, option_mirror, 
option_single_branch = -1;
 static int option_local = -1, option_no_hardlinks, option_shared, 
option_recursive;
-static char *option_template, *option_depth;
+static int deepen;
+static char *option_template, *option_depth, *option_since;
 static char *option_origin = NULL;
 static char *option_branch = NULL;
 static const char *real_git_dir;
@@ -86,6 +87,8 @@ static struct option builtin_clone_options[] = {
   N_("path to git-upload-pack on the remote")),
OPT_STRING(0, "depth", &option_depth, N_("depth"),
N_("create a shallow clone of that depth")),
+   OPT_STRING(0, "shallow-since", &option_since, N_("time"),
+   N_("create a shallow clone since a specific time")),
OPT_BOOL(0, "single-branch", &option_single_branch,
N_("clone only one branch, HEAD or --branch")),
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
@@ -849,8 +852,10 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
usage_msg_opt(_("You must specify a repository to clone."),
builtin_clone_usage, builtin_clone_options);
 
+   if (option_depth || option_since)
+   deepen = 1;
if (option_single_branch == -1)
-   option_single_branch = option_depth ? 1 : 0;
+   option_single_branch = deepen ? 1 : 0;
 
if (option_mirror)
option_bare = 1;
@@ -976,6 +981,8 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
if (is_local) {
if (option_depth)
warning(_("--depth is ignored in local clones; use 
file:// instead."));
+   if (option_since)
+   warning(_("--shallow-since is ignored in local clones; 
use file:// instead."));
if (!access(mkpath("%s/shallow", path), F_OK)) {
if (option_local > 0)
warning(_("source repository is shallow, 
ignoring --local"));
@@ -994,6 +1001,9 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
if (option_depth)
transport_set_option(transport, TRANS_OPT_DEPTH,
 option_depth);
+   if (option_since)
+   transport_set_option(transport, TRANS_OPT_DEEPEN_SINCE,
+option_since);
if (option_single_branch)
transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");
 
@@ -1001,7 +1011,7 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
transport_set_option(transport, TRANS_OPT_UPLOADPACK,
 option_upload_pack);
 
-   if (transport->smart_options && !option_depth)
+   if (transport->smart_options && !deepen)
transport->smart_options->check_self_contained_and_connected = 
1;
 
refs = transport_get_remote_refs(transport);
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 19/27] t5500, t5539: tests for shallow depth since a specific date

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 t/t5500-fetch-pack.sh | 24 
 t/t5539-fetch-http-shallow.sh | 25 +
 2 files changed, 49 insertions(+)

diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index e5f83bf..26f050d 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -637,4 +637,28 @@ test_expect_success MINGW 'fetch-pack --diag-url c:repo' '
check_prot_path c:repo file c:repo
 '
 
+test_expect_success 'clone shallow since ...' '
+   test_create_repo shallow-since &&
+   (
+   cd shallow-since &&
+   GIT_COMMITTER_DATE="1 +0700" git commit --allow-empty -m one &&
+   GIT_COMMITTER_DATE="2 +0700" git commit --allow-empty -m two &&
+   GIT_COMMITTER_DATE="3 +0700" git commit --allow-empty -m three 
&&
+   git clone --shallow-since "3 +0700" "file://$(pwd)/." 
../shallow11 &&
+   git -C ../shallow11 log --pretty=tformat:%s HEAD >actual &&
+   echo three >expected &&
+   test_cmp expected actual
+   )
+'
+
+test_expect_success 'fetch shallow since ...' '
+   git -C shallow11 fetch --shallow-since "2 +0700" origin &&
+   git -C shallow11 log --pretty=tformat:%s origin/master >actual &&
+   cat >expected <<-\EOF &&
+   three
+   two
+   EOF
+   test_cmp expected actual
+'
+
 test_done
diff --git a/t/t5539-fetch-http-shallow.sh b/t/t5539-fetch-http-shallow.sh
index 37a4335..704753c 100755
--- a/t/t5539-fetch-http-shallow.sh
+++ b/t/t5539-fetch-http-shallow.sh
@@ -73,5 +73,30 @@ test_expect_success 'no shallow lines after receiving ACK 
ready' '
)
 '
 
+test_expect_success 'clone shallow since ...' '
+   test_create_repo shallow-since &&
+   (
+   cd shallow-since &&
+   GIT_COMMITTER_DATE="1 +0700" git commit --allow-empty -m one &&
+   GIT_COMMITTER_DATE="2 +0700" git commit --allow-empty -m two &&
+   GIT_COMMITTER_DATE="3 +0700" git commit --allow-empty -m three 
&&
+   mv .git "$HTTPD_DOCUMENT_ROOT_PATH/shallow-since.git" &&
+   git clone --shallow-since "3 +0700" 
$HTTPD_URL/smart/shallow-since.git ../shallow11 &&
+   git -C ../shallow11 log --pretty=tformat:%s HEAD >actual &&
+   echo three >expected &&
+   test_cmp expected actual
+   )
+'
+
+test_expect_success 'fetch shallow since ...' '
+   git -C shallow11 fetch --shallow-since "2 +0700" origin &&
+   git -C shallow11 log --pretty=tformat:%s origin/master >actual &&
+   cat >expected <<-\EOF &&
+   three
+   two
+   EOF
+   test_cmp expected actual
+'
+
 stop_httpd
 test_done
-- 
2.8.2.524.g6ff3d78

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


[PATCH v2 10/27] upload-pack: move rev-list code out of check_non_tip()

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 upload-pack.c | 36 +++-
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/upload-pack.c b/upload-pack.c
index 7ce97ec..93c0522 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -451,7 +451,7 @@ static int is_our_ref(struct object *o)
return o->flags & ((allow_hidden_ref ? HIDDEN_REF : 0) | OUR_REF);
 }
 
-static void check_non_tip(void)
+static int has_unreachable(struct object_array *src)
 {
static const char *argv[] = {
"rev-list", "--stdin", NULL,
@@ -461,14 +461,6 @@ static void check_non_tip(void)
char namebuf[42]; /* ^ + SHA-1 + LF */
int i;
 
-   /*
-* In the normal in-process case without
-* uploadpack.allowReachableSHA1InWant,
-* non-tip requests can never happen.
-*/
-   if (!stateless_rpc && !(allow_unadvertised_object_request & 
ALLOW_REACHABLE_SHA1))
-   goto error;
-
cmd.argv = argv;
cmd.git_cmd = 1;
cmd.no_stderr = 1;
@@ -498,8 +490,8 @@ static void check_non_tip(void)
goto error;
}
namebuf[40] = '\n';
-   for (i = 0; i < want_obj.nr; i++) {
-   o = want_obj.objects[i].item;
+   for (i = 0; i < src->nr; i++) {
+   o = src->objects[i].item;
if (is_our_ref(o))
continue;
memcpy(namebuf, oid_to_hex(&o->oid), GIT_SHA1_HEXSZ);
@@ -530,7 +522,7 @@ static void check_non_tip(void)
sigchain_pop(SIGPIPE);
 
/* All the non-tip ones are ancestors of what we advertised */
-   return;
+   return 0;
 
 error:
sigchain_pop(SIGPIPE);
@@ -539,10 +531,28 @@ error:
close(cmd.in);
if (cmd.out >= 0)
close(cmd.out);
+   return 1;
+}
 
+static void check_non_tip(void)
+{
+   int i;
+
+   /*
+* In the normal in-process case without
+* uploadpack.allowReachableSHA1InWant,
+* non-tip requests can never happen.
+*/
+   if (!stateless_rpc && !(allow_unadvertised_object_request & 
ALLOW_REACHABLE_SHA1))
+   goto error;
+   if (!has_unreachable(&want_obj))
+   /* All the non-tip ones are ancestors of what we advertised */
+   return;
+
+error:
/* Pick one of them (we know there at least is one) */
for (i = 0; i < want_obj.nr; i++) {
-   o = want_obj.objects[i].item;
+   struct object *o = want_obj.objects[i].item;
if (!is_our_ref(o))
die("git upload-pack: not our ref %s",
oid_to_hex(&o->oid));
-- 
2.8.2.524.g6ff3d78

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


[PATCH v2 05/27] upload-pack: remove unused variable "backup"

2016-06-12 Thread Nguyễn Thái Ngọc Duy
After the last patch, "result" and "backup" are the same. "result" used
to move, but the movement is now contained in send_shallow(). Delete
this redundant variable.

Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 upload-pack.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/upload-pack.c b/upload-pack.c
index 0eb9a0b..ee5d20b 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -554,7 +554,7 @@ static void send_shallow(struct commit_list *result)
 
 static void deepen(int depth, const struct object_array *shallows)
 {
-   struct commit_list *result = NULL, *backup = NULL;
+   struct commit_list *result = NULL;
int i;
if (depth == INFINITE_DEPTH && !is_repository_shallow())
for (i = 0; i < shallows->nr; i++) {
@@ -562,11 +562,10 @@ static void deepen(int depth, const struct object_array 
*shallows)
object->flags |= NOT_SHALLOW;
}
else
-   backup = result =
-   get_shallow_commits(&want_obj, depth,
-   SHALLOW, NOT_SHALLOW);
+   result = get_shallow_commits(&want_obj, depth,
+SHALLOW, NOT_SHALLOW);
send_shallow(result);
-   free_commit_list(backup);
+   free_commit_list(result);
for (i = 0; i < shallows->nr; i++) {
struct object *object = shallows->objects[i].item;
if (object->flags & NOT_SHALLOW) {
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 09/27] upload-pack: make check_non_tip() clean things up on error

2016-06-12 Thread Nguyễn Thái Ngọc Duy
On error check_non_tip() will die and not closing file descriptors is no
big deal. The next patch will split the majority of this function out
for reuse in other cases, where die() may not be the only outcome. Same
story for popping SIGPIPE out of the signal chain. So let's make sure we
clean things up properly first.

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 upload-pack.c | 23 ---
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/upload-pack.c b/upload-pack.c
index 8f4d7f4..7ce97ec 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -475,16 +475,16 @@ static void check_non_tip(void)
cmd.in = -1;
cmd.out = -1;
 
-   if (start_command(&cmd))
-   goto error;
-
/*
-* If rev-list --stdin encounters an unknown commit, it
-* terminates, which will cause SIGPIPE in the write loop
+* If the next rev-list --stdin encounters an unknown commit,
+* it terminates, which will cause SIGPIPE in the write loop
 * below.
 */
sigchain_push(SIGPIPE, SIG_IGN);
 
+   if (start_command(&cmd))
+   goto error;
+
namebuf[0] = '^';
namebuf[41] = '\n';
for (i = get_max_object_index(); 0 < i; ) {
@@ -507,8 +507,7 @@ static void check_non_tip(void)
goto error;
}
close(cmd.in);
-
-   sigchain_pop(SIGPIPE);
+   cmd.in = -1;
 
/*
 * The commits out of the rev-list are not ancestors of
@@ -518,6 +517,7 @@ static void check_non_tip(void)
if (i)
goto error;
close(cmd.out);
+   cmd.out = -1;
 
/*
 * rev-list may have died by encountering a bad commit
@@ -527,10 +527,19 @@ static void check_non_tip(void)
if (finish_command(&cmd))
goto error;
 
+   sigchain_pop(SIGPIPE);
+
/* All the non-tip ones are ancestors of what we advertised */
return;
 
 error:
+   sigchain_pop(SIGPIPE);
+
+   if (cmd.in >= 0)
+   close(cmd.in);
+   if (cmd.out >= 0)
+   close(cmd.out);
+
/* Pick one of them (we know there at least is one) */
for (i = 0; i < want_obj.nr; i++) {
o = want_obj.objects[i].item;
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 17/27] fetch: define shallow boundary with --shallow-since

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 Documentation/fetch-options.txt |  4 
 Documentation/git-fetch-pack.txt|  4 
 Documentation/gitremote-helpers.txt |  3 +++
 builtin/fetch-pack.c|  4 
 builtin/fetch.c | 29 +++--
 fetch-pack.c| 12 +++-
 fetch-pack.h|  1 +
 remote-curl.c   | 11 +--
 transport.c |  4 
 transport.h |  4 
 10 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 952dfdf..8738d3d 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -14,6 +14,10 @@
linkgit:git-clone[1]), deepen or shorten the history to the specified
number of commits. Tags for the deepened commits are not fetched.
 
+--shallow-since=::
+   Deepen or shorten the history of a shallow repository to
+   include all reachable commits after .
+
 --unshallow::
If the source repository is complete, convert a shallow
repository to a complete one, removing all the limitations
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
index 8680f45..99e6257 100644
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -87,6 +87,10 @@ be in a separate packet, and the list must end with a flush 
packet.
'git-upload-pack' treats the special depth 2147483647 as
infinite even if there is an ancestor-chain that long.
 
+--shallow-since=::
+   Deepen or shorten the history of a shallow'repository to
+   include all reachable commits after .
+
 --no-progress::
Do not show the progress.
 
diff --git a/Documentation/gitremote-helpers.txt 
b/Documentation/gitremote-helpers.txt
index 78e0b27..9971d9a 100644
--- a/Documentation/gitremote-helpers.txt
+++ b/Documentation/gitremote-helpers.txt
@@ -415,6 +415,9 @@ set by Git if the remote helper has the 'option' capability.
 'option depth' ::
Deepens the history of a shallow repository.
 
+'option deepen-since ::
+   Deepens the history of a shallow repository based on time.
+
 'option followtags' {'true'|'false'}::
If enabled the helper should automatically fetch annotated
tag objects if the object the tag points at was transferred
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 8332d3d..0402e27 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -104,6 +104,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char 
*prefix)
args.depth = strtol(arg, NULL, 0);
continue;
}
+   if (skip_prefix(arg, "--shallow-since=", &arg)) {
+   args.deepen_since = xstrdup(arg);
+   continue;
+   }
if (!strcmp("--no-progress", arg)) {
args.no_progress = 1;
continue;
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 8e74213..283aa95 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -36,9 +36,10 @@ static int prune = -1; /* unspecified */
 
 static int all, append, dry_run, force, keep, multiple, update_head_ok, 
verbosity;
 static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
-static int tags = TAGS_DEFAULT, unshallow, update_shallow;
+static int tags = TAGS_DEFAULT, unshallow, update_shallow, deepen;
 static int max_children = 1;
 static const char *depth;
+static const char *deepen_since;
 static const char *upload_pack;
 static struct strbuf default_rla = STRBUF_INIT;
 static struct transport *gtransport;
@@ -115,6 +116,8 @@ static struct option builtin_fetch_options[] = {
OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
OPT_STRING(0, "depth", &depth, N_("depth"),
   N_("deepen history of shallow clone")),
+   OPT_STRING(0, "shallow-since", &deepen_since, N_("time"),
+  N_("deepen history of shallow repository based on time")),
{ OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
   N_("convert to a complete repository"),
   PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 },
@@ -754,7 +757,7 @@ static int quickfetch(struct ref *ref_map)
 * really need to perform.  Claiming failure now will ensure
 * we perform the network exchange to deepen our history.
 */
-   if (depth)
+   if (deepen)
return -1;
return check_everything_connected(iterate_ref_map, 1, &rm);
 }
@@ -859,7 +862,7 @@ static void set_option(struct transport *transport, const 
char *name, const char
name, transport->url);
 }
 
-static struct transport *prepare_transport(struct remote *remote)
+static struct transport *

[PATCH v2 13/27] fetch-pack.c: mark strings for translating

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 fetch-pack.c | 75 ++--
 1 file changed, 37 insertions(+), 38 deletions(-)

diff --git a/fetch-pack.c b/fetch-pack.c
index 4020744..08caf1d 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -208,7 +208,7 @@ static void consume_shallow_list(struct fetch_pack_args 
*args, int fd)
continue;
if (starts_with(line, "unshallow "))
continue;
-   die("git fetch-pack: expected shallow list");
+   die(_("git fetch-pack: expected shallow list"));
}
}
 }
@@ -220,7 +220,7 @@ static enum ack_type get_ack(int fd, unsigned char 
*result_sha1)
const char *arg;
 
if (!len)
-   die("git fetch-pack: expected ACK/NAK, got EOF");
+   die(_("git fetch-pack: expected ACK/NAK, got EOF"));
if (!strcmp(line, "NAK"))
return NAK;
if (skip_prefix(line, "ACK ", &arg)) {
@@ -238,7 +238,7 @@ static enum ack_type get_ack(int fd, unsigned char 
*result_sha1)
return ACK;
}
}
-   die("git fetch_pack: expected ACK/NAK, got '%s'", line);
+   die(_("git fetch_pack: expected ACK/NAK, got '%s'"), line);
 }
 
 static void send_request(struct fetch_pack_args *args,
@@ -285,7 +285,7 @@ static int find_common(struct fetch_pack_args *args,
size_t state_len = 0;
 
if (args->stateless_rpc && multi_ack == 1)
-   die("--stateless-rpc requires multi_ack_detailed");
+   die(_("--stateless-rpc requires multi_ack_detailed"));
if (marked)
for_each_ref(clear_marks, NULL);
marked = 1;
@@ -357,23 +357,23 @@ static int find_common(struct fetch_pack_args *args,
while ((line = packet_read_line(fd[0], NULL))) {
if (skip_prefix(line, "shallow ", &arg)) {
if (get_sha1_hex(arg, sha1))
-   die("invalid shallow line: %s", line);
+   die(_("invalid shallow line: %s"), 
line);
register_shallow(sha1);
continue;
}
if (skip_prefix(line, "unshallow ", &arg)) {
if (get_sha1_hex(arg, sha1))
-   die("invalid unshallow line: %s", line);
+   die(_("invalid unshallow line: %s"), 
line);
if (!lookup_object(sha1))
-   die("object not found: %s", line);
+   die(_("object not found: %s"), line);
/* make sure that it is parsed as shallow */
if (!parse_object(sha1))
-   die("error in object: %s", line);
+   die(_("error in object: %s"), line);
if (unregister_shallow(sha1))
-   die("no shallow found: %s", line);
+   die(_("no shallow found: %s"), line);
continue;
}
-   die("expected shallow/unshallow, got %s", line);
+   die(_("expected shallow/unshallow, got %s"), line);
}
} else if (!args->stateless_rpc)
send_request(args, fd[1], &req_buf);
@@ -412,8 +412,8 @@ static int find_common(struct fetch_pack_args *args,
do {
ack = get_ack(fd[0], result_sha1);
if (ack)
-   print_verbose(args, "got ack %d %s", 
ack,
- sha1_to_hex(result_sha1));
+   print_verbose(args, _("got %s %d %s"), 
"ack",
+ ack, 
sha1_to_hex(result_sha1));
switch (ack) {
case ACK:
flushes = 0;
@@ -426,7 +426,7 @@ static int find_common(struct fetch_pack_args *args,
struct commit *commit =
lookup_commit(result_sha1);
if (!commit)
-   die("invalid commit %s", 
sha1_to_hex(result_sha1));
+   die(_("invalid commit %s"), 
sha1_to_hex(result_sha1));
if (args->stateless_rpc
 && ack == ACK_co

[PATCH v2 15/27] shallow.c: implement a generic shallow boundary finder based on rev-list

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Instead of a custom commit walker like get_shallow_commits(), this new
function uses rev-list to mark NOT_SHALLOW to all reachable commits,
except borders. The definition of reachable is to be defined by the
protocol later. This makes it more flexible to define shallow boundary.

The way we find border is paint all reachable commits NOT_SHALLOW.  Any
of them that "touches" commits without NOT_SHALLOW flag are considered
shallow (e.g. zero parents via grafting mechanism). Shallow commits and
their true parents are all marked SHALLOW. Then NOT_SHALLOW is removed
from shallow commits at the end.

There is an interesting observation. With a generic walker, we can
produce all kinds of shallow cutting. In the following graph, every
commit but "x" is reachable. "b" is a parent of "a".

   x -- a -- o
  //
x -- c -- b -- o

After this function is run, "a" and "c" are both considered shallow
commits. After grafting occurs at the client side, what we see is

a -- o
/
 c -- b -- o

Notice that because of grafting, "a" has zero parents, so "b" is no
longer a parent of "a".

This is unfortunate and may be solved in two ways. The first is change
the way shallow grafting works and keep "a -- b" connection if "b"
exists and always ends at shallow commits (iow, no loose ends). This is
hard to detect, or at least not cheap to do.

The second way is mark one "x" as shallow commit instead of "a" and
produce this graph at client side:

   x -- a -- o
   //
 c -- b -- o

More commits, but simpler grafting rules.

Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 commit.h  |  2 ++
 shallow.c | 78 +++
 2 files changed, 80 insertions(+)

diff --git a/commit.h b/commit.h
index 5d58be0..b717be1 100644
--- a/commit.h
+++ b/commit.h
@@ -258,6 +258,8 @@ extern int for_each_commit_graft(each_commit_graft_fn, void 
*);
 extern int is_repository_shallow(void);
 extern struct commit_list *get_shallow_commits(struct object_array *heads,
int depth, int shallow_flag, int not_shallow_flag);
+extern struct commit_list *get_shallow_commits_by_rev_list(
+   int ac, const char **av, int shallow_flag, int 
not_shallow_flag);
 extern void set_alternate_shallow_file(const char *path, int override);
 extern int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
 const struct sha1_array *extra);
diff --git a/shallow.c b/shallow.c
index 60f1505..40c2485 100644
--- a/shallow.c
+++ b/shallow.c
@@ -10,6 +10,8 @@
 #include "diff.h"
 #include "revision.h"
 #include "commit-slab.h"
+#include "revision.h"
+#include "list-objects.h"
 
 static int is_shallow = -1;
 static struct stat_validity shallow_stat;
@@ -137,6 +139,82 @@ struct commit_list *get_shallow_commits(struct 
object_array *heads, int depth,
return result;
 }
 
+static void show_commit(struct commit *commit, void *data)
+{
+   commit_list_insert(commit, data);
+}
+
+/*
+ * Given rev-list arguments, run rev-list. All reachable commits
+ * except border ones are marked with not_shallow_flag. Border commits
+ * are marked with shallow_flag. The list of border/shallow commits
+ * are also returned.
+ */
+struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av,
+   int shallow_flag,
+   int not_shallow_flag)
+{
+   struct commit_list *result = NULL, *p;
+   struct commit_list *not_shallow_list = NULL;
+   struct rev_info revs;
+   int both_flags = shallow_flag | not_shallow_flag;
+
+   /*
+* SHALLOW (excluded) and NOT_SHALLOW (included) should not be
+* set at this point. But better be safe than sorry.
+*/
+   clear_object_flags(both_flags);
+
+   is_repository_shallow(); /* make sure shallows are read */
+
+   init_revisions(&revs, NULL);
+   save_commit_buffer = 0;
+   setup_revisions(ac, av, &revs, NULL);
+
+   if (prepare_revision_walk(&revs))
+   die("revision walk setup failed");
+   traverse_commit_list(&revs, show_commit, NULL, ¬_shallow_list);
+
+   /* Mark all reachable commits as NOT_SHALLOW */
+   for (p = not_shallow_list; p; p = p->next)
+   p->item->object.flags |= not_shallow_flag;
+
+   /*
+* mark border commits SHALLOW + NOT_SHALLOW.
+* We cannot clear NOT_SHALLOW right now. Imagine border
+* commit A is processed first, then commit B, whose parent is
+* A, later. If NOT_SHALLOW on A is cleared at step 1, B
+* itself is considered border at step 2, which is incorrect.
+*/
+   for (p = not_shallow_list; p; p = p->next) {
+   struct commit *c = p->item;
+   struct commit_list *parent;
+
+   if (parse_commit(c))
+ 

[PATCH v2 06/27] upload-pack: move "unshallow" sending code out of deepen()

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Also add some more comments in this code because it takes too long to
understand what it does (to me, who should be familiar enough to
understand this code well!)

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 upload-pack.c | 43 ++-
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/upload-pack.c b/upload-pack.c
index ee5d20b..73a8b28 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -552,20 +552,10 @@ static void send_shallow(struct commit_list *result)
}
 }
 
-static void deepen(int depth, const struct object_array *shallows)
+static void send_unshallow(const struct object_array *shallows)
 {
-   struct commit_list *result = NULL;
int i;
-   if (depth == INFINITE_DEPTH && !is_repository_shallow())
-   for (i = 0; i < shallows->nr; i++) {
-   struct object *object = shallows->objects[i].item;
-   object->flags |= NOT_SHALLOW;
-   }
-   else
-   result = get_shallow_commits(&want_obj, depth,
-SHALLOW, NOT_SHALLOW);
-   send_shallow(result);
-   free_commit_list(result);
+
for (i = 0; i < shallows->nr; i++) {
struct object *object = shallows->objects[i].item;
if (object->flags & NOT_SHALLOW) {
@@ -573,7 +563,13 @@ static void deepen(int depth, const struct object_array 
*shallows)
packet_write(1, "unshallow %s",
 oid_to_hex(&object->oid));
object->flags &= ~CLIENT_SHALLOW;
-   /* make sure the real parents are parsed */
+   /*
+* We want to _register_ "object" as shallow, but we
+* also need to traverse object's parents to deepen a
+* shallow clone. Unregister it for now so we can
+* parse and add the parents to the want list, then
+* re-register it.
+*/
unregister_shallow(object->oid.hash);
object->parsed = 0;
parse_commit_or_die((struct commit *)object);
@@ -588,6 +584,27 @@ static void deepen(int depth, const struct object_array 
*shallows)
/* make sure commit traversal conforms to client */
register_shallow(object->oid.hash);
}
+}
+
+static void deepen(int depth, const struct object_array *shallows)
+{
+   if (depth == INFINITE_DEPTH && !is_repository_shallow()) {
+   int i;
+
+   for (i = 0; i < shallows->nr; i++) {
+   struct object *object = shallows->objects[i].item;
+   object->flags |= NOT_SHALLOW;
+   }
+   } else {
+   struct commit_list *result;
+
+   result = get_shallow_commits(&want_obj, depth,
+SHALLOW, NOT_SHALLOW);
+   send_shallow(result);
+   free_commit_list(result);
+   }
+
+   send_unshallow(shallows);
packet_flush(1);
 }
 
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 16/27] upload-pack: add deepen-since to cut shallow repos based on time

2016-06-12 Thread Nguyễn Thái Ngọc Duy
This should allow the user to say "create a shallow clone containing the
work from last year" (once the client side is fixed up, of course).

In theory deepen-since and deepen (aka --depth) can be used together to
draw the shallow boundary (whether it's intersection or union is up to
discussion, but if rev-list is used, it's likely intersection). However,
because deepen goes with a custom commit walker, we can't mix the two
yet.

Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 Documentation/technical/pack-protocol.txt |  3 +-
 Documentation/technical/protocol-capabilities.txt |  9 +
 upload-pack.c | 45 ++-
 3 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/Documentation/technical/pack-protocol.txt 
b/Documentation/technical/pack-protocol.txt
index c6977bb..9251df1 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -219,7 +219,8 @@ out of what the server said it could do with the first 
'want' line.
 
   shallow-line  =  PKT-LINE("shallow" SP obj-id)
 
-  depth-request =  PKT-LINE("deepen" SP depth)
+  depth-request =  PKT-LINE("deepen" SP depth) /
+  PKT-LINE("deepen-since" SP timestamp)
 
   first-want=  PKT-LINE("want" SP obj-id SP capability-list)
   additional-want   =  PKT-LINE("want" SP obj-id)
diff --git a/Documentation/technical/protocol-capabilities.txt 
b/Documentation/technical/protocol-capabilities.txt
index eaab6b4..f08cc4e 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -179,6 +179,15 @@ This capability adds "deepen", "shallow" and "unshallow" 
commands to
 the  fetch-pack/upload-pack protocol so clients can request shallow
 clones.
 
+deepen-since
+
+
+This capability adds "deepen-since" command to fetch-pack/upload-pack
+protocol so the client can request shallow clones that are cut at a
+specific time, instead of depth. Internally it's equivalent of doing
+"rev-list --max-age=" on the server side. "deepen-since"
+cannot be used with "deepen".
+
 no-progress
 ---
 
diff --git a/upload-pack.c b/upload-pack.c
index 93c0522..5269461 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -14,6 +14,7 @@
 #include "sigchain.h"
 #include "version.h"
 #include "string-list.h"
+#include "argv-array.h"
 
 static const char upload_pack_usage[] = "git upload-pack [--strict] 
[--timeout=] ";
 
@@ -629,11 +630,25 @@ static void deepen(int depth, const struct object_array 
*shallows)
packet_flush(1);
 }
 
+static void deepen_by_rev_list(int ac, const char **av,
+  struct object_array *shallows)
+{
+   struct commit_list *result;
+
+   result = get_shallow_commits_by_rev_list(ac, av, SHALLOW, NOT_SHALLOW);
+   send_shallow(result);
+   free_commit_list(result);
+   send_unshallow(shallows);
+   packet_flush(1);
+}
+
 static void receive_needs(void)
 {
struct object_array shallows = OBJECT_ARRAY_INIT;
int depth = 0;
int has_non_tip = 0;
+   unsigned long deepen_since = 0;
+   int deepen_rev_list = 0;
 
shallow_nr = 0;
for (;;) {
@@ -670,6 +685,16 @@ static void receive_needs(void)
die("Invalid deepen: %s", line);
continue;
}
+   if (skip_prefix(line, "deepen-since ", &arg)) {
+   char *end = NULL;
+   deepen_since = strtoul(arg, &end, 0);
+   if (!end || *end || !deepen_since ||
+   /* revisions.c's max_age -1 is special */
+   deepen_since == -1)
+   die("Invalid deepen-since: %s", line);
+   deepen_rev_list = 1;
+   continue;
+   }
if (!skip_prefix(line, "want ", &arg) ||
get_sha1_hex(arg, sha1_buf))
die("git upload-pack: protocol error, "
@@ -721,10 +746,26 @@ static void receive_needs(void)
if (!use_sideband && daemon_mode)
no_progress = 1;
 
-   if (depth == 0 && shallows.nr == 0)
+   if (depth == 0 && !deepen_rev_list && shallows.nr == 0)
return;
+   if (depth > 0 && deepen_rev_list)
+   die("git upload-pack: deepen and deepen-since cannot be used 
together");
if (depth > 0)
deepen(depth, &shallows);
+   else if (deepen_rev_list) {
+   struct argv_array av = ARGV_ARRAY_INIT;
+   int i;
+
+   argv_array_push(&av, "rev-list");
+   if (deepen_since)
+   argv_array_pushf(&av, "--max-age=%lu", deepen_since);
+   for (i = 0; i < want_obj.nr; i++) {
+   struct object *o = want_obj.objects[i].item;
+

[PATCH v2 07/27] upload-pack: use skip_prefix() instead of starts_with()

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 upload-pack.c | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/upload-pack.c b/upload-pack.c
index 73a8b28..fa7ce09 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -276,7 +276,7 @@ static void create_pack_file(void)
die("git upload-pack: %s", abort_msg);
 }
 
-static int got_sha1(char *hex, unsigned char *sha1)
+static int got_sha1(const char *hex, unsigned char *sha1)
 {
struct object *o;
int we_knew_they_have = 0;
@@ -382,6 +382,8 @@ static int get_common_commits(void)
 
for (;;) {
char *line = packet_read_line(0, NULL);
+   const char *arg;
+
reset_timeout();
 
if (!line) {
@@ -403,8 +405,8 @@ static int get_common_commits(void)
got_other = 0;
continue;
}
-   if (starts_with(line, "have ")) {
-   switch (got_sha1(line+5, sha1)) {
+   if (skip_prefix(line, "have ", &arg)) {
+   switch (got_sha1(arg, sha1)) {
case -1: /* they have what we do not */
got_other = 1;
if (multi_ack && ok_to_give_up()) {
@@ -620,14 +622,16 @@ static void receive_needs(void)
const char *features;
unsigned char sha1_buf[20];
char *line = packet_read_line(0, NULL);
+   const char *arg;
+
reset_timeout();
if (!line)
break;
 
-   if (starts_with(line, "shallow ")) {
+   if (skip_prefix(line, "shallow ", &arg)) {
unsigned char sha1[20];
struct object *object;
-   if (get_sha1_hex(line + 8, sha1))
+   if (get_sha1_hex(arg, sha1))
die("invalid shallow line: %s", line);
object = parse_object(sha1);
if (!object)
@@ -640,19 +644,19 @@ static void receive_needs(void)
}
continue;
}
-   if (starts_with(line, "deepen ")) {
+   if (skip_prefix(line, "deepen ", &arg)) {
char *end;
-   depth = strtol(line + 7, &end, 0);
-   if (end == line + 7 || depth <= 0)
+   depth = strtol(arg, &end, 0);
+   if (end == arg || depth <= 0)
die("Invalid deepen: %s", line);
continue;
}
-   if (!starts_with(line, "want ") ||
-   get_sha1_hex(line+5, sha1_buf))
+   if (!skip_prefix(line, "want ", &arg) ||
+   get_sha1_hex(arg, sha1_buf))
die("git upload-pack: protocol error, "
"expected to get sha, not '%s'", line);
 
-   features = line + 45;
+   features = arg + 40;
 
if (parse_feature_request(features, "multi_ack_detailed"))
multi_ack = 2;
@@ -859,7 +863,7 @@ int main(int argc, char **argv)
check_replace_refs = 0;
 
for (i = 1; i < argc; i++) {
-   char *arg = argv[i];
+   const char *arg = argv[i];
 
if (arg[0] != '-')
break;
@@ -875,8 +879,8 @@ int main(int argc, char **argv)
strict = 1;
continue;
}
-   if (starts_with(arg, "--timeout=")) {
-   timeout = atoi(arg+10);
+   if (skip_prefix(arg, "--timeout=", &arg)) {
+   timeout = atoi(arg);
daemon_mode = 1;
continue;
}
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 12/27] fetch-pack: use a common function for verbose printing

2016-06-12 Thread Nguyễn Thái Ngọc Duy
This reduces the number of "if (verbose)" which makes it a bit easier
to read imo. It also makes it easier to redirect all these printouts,
to a file for example.

Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 fetch-pack.c | 88 +---
 1 file changed, 42 insertions(+), 46 deletions(-)

diff --git a/fetch-pack.c b/fetch-pack.c
index 01e34b6..4020744 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -50,6 +50,21 @@ static int non_common_revs, multi_ack, use_sideband;
 #define ALLOW_REACHABLE_SHA1   02
 static unsigned int allow_unadvertised_object_request;
 
+__attribute__((format (printf, 2, 3)))
+static inline void print_verbose(const struct fetch_pack_args *args,
+const char *fmt, ...)
+{
+   va_list params;
+
+   if (!args->verbose)
+   return;
+
+   va_start(params, fmt);
+   vfprintf(stderr, fmt, params);
+   va_end(params);
+   fputc('\n', stderr);
+}
+
 static void rev_list_push(struct commit *commit, int mark)
 {
if (!(commit->object.flags & mark)) {
@@ -375,8 +390,7 @@ static int find_common(struct fetch_pack_args *args,
retval = -1;
while ((sha1 = get_rev())) {
packet_buf_write(&req_buf, "have %s\n", sha1_to_hex(sha1));
-   if (args->verbose)
-   fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
+   print_verbose(args, "have %s", sha1_to_hex(sha1));
in_vain++;
if (flush_at <= ++count) {
int ack;
@@ -397,9 +411,9 @@ static int find_common(struct fetch_pack_args *args,
consume_shallow_list(args, fd[0]);
do {
ack = get_ack(fd[0], result_sha1);
-   if (args->verbose && ack)
-   fprintf(stderr, "got ack %d %s\n", ack,
-   
sha1_to_hex(result_sha1));
+   if (ack)
+   print_verbose(args, "got ack %d %s", 
ack,
+ sha1_to_hex(result_sha1));
switch (ack) {
case ACK:
flushes = 0;
@@ -438,8 +452,7 @@ static int find_common(struct fetch_pack_args *args,
} while (ack);
flushes--;
if (got_continue && MAX_IN_VAIN < in_vain) {
-   if (args->verbose)
-   fprintf(stderr, "giving up\n");
+   print_verbose(args, "giving up");
break; /* give up */
}
}
@@ -449,8 +462,7 @@ done:
packet_buf_write(&req_buf, "done\n");
send_request(args, fd[1], &req_buf);
}
-   if (args->verbose)
-   fprintf(stderr, "done\n");
+   print_verbose(args, "done");
if (retval != 0) {
multi_ack = 0;
flushes++;
@@ -462,9 +474,8 @@ done:
while (flushes || multi_ack) {
int ack = get_ack(fd[0], result_sha1);
if (ack) {
-   if (args->verbose)
-   fprintf(stderr, "got ack (%d) %s\n", ack,
-   sha1_to_hex(result_sha1));
+   print_verbose(args, "got ack (%d) %s", ack,
+ sha1_to_hex(result_sha1));
if (ack == ACK)
return 0;
multi_ack = 1;
@@ -509,9 +520,8 @@ static void mark_recent_complete_commits(struct 
fetch_pack_args *args,
 unsigned long cutoff)
 {
while (complete && cutoff <= complete->item->date) {
-   if (args->verbose)
-   fprintf(stderr, "Marking %s as complete\n",
-   oid_to_hex(&complete->item->object.oid));
+   print_verbose(args, "Marking %s as complete",
+ oid_to_hex(&complete->item->object.oid));
pop_most_recent_commit(&complete, COMPLETE);
}
 }
@@ -652,18 +662,12 @@ static int everything_local(struct fetch_pack_args *args,
o = lookup_object(remote);
if (!o || !(o->flags & COMPLETE)) {
retval = 0;
-   if (!args->verbose)
-   continue;
-   fprintf(stderr,
-   "want %s (%s)\n", sha1_to_hex(remote),
-   ref->name);
+   print_verbose(args, "want %s (%s)", sha1_to_hex(remote),
+  

[PATCH v2 11/27] fetch-pack: use skip_prefix() instead of starts_with()

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 builtin/fetch-pack.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 9b2a514..8332d3d 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -59,12 +59,12 @@ int cmd_fetch_pack(int argc, const char **argv, const char 
*prefix)
for (i = 1; i < argc && *argv[i] == '-'; i++) {
const char *arg = argv[i];
 
-   if (starts_with(arg, "--upload-pack=")) {
-   args.uploadpack = arg + 14;
+   if (skip_prefix(arg, "--upload-pack=", &arg)) {
+   args.uploadpack = arg;
continue;
}
-   if (starts_with(arg, "--exec=")) {
-   args.uploadpack = arg + 7;
+   if (skip_prefix(arg, "--exec=", &arg)) {
+   args.uploadpack = arg;
continue;
}
if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
@@ -100,8 +100,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char 
*prefix)
args.verbose = 1;
continue;
}
-   if (starts_with(arg, "--depth=")) {
-   args.depth = strtol(arg + 8, NULL, 0);
+   if (skip_prefix(arg, "--depth=", &arg)) {
+   args.depth = strtol(arg, NULL, 0);
continue;
}
if (!strcmp("--no-progress", arg)) {
-- 
2.8.2.524.g6ff3d78

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


[PATCH v2 08/27] upload-pack: tighten number parsing at "deepen" lines

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 upload-pack.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/upload-pack.c b/upload-pack.c
index fa7ce09..8f4d7f4 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -645,9 +645,9 @@ static void receive_needs(void)
continue;
}
if (skip_prefix(line, "deepen ", &arg)) {
-   char *end;
+   char *end = NULL;
depth = strtol(arg, &end, 0);
-   if (end == arg || depth <= 0)
+   if (!end || *end || depth <= 0)
die("Invalid deepen: %s", line);
continue;
}
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 14/27] fetch-pack: use a separate flag for fetch in deepening mode

2016-06-12 Thread Nguyễn Thái Ngọc Duy
The shallow repo could be deepened or shortened when then user gives
--depth. But in future that won't be the only way to deepen/shorten a
repo. Stop relying on args->depth in this mode. Future deepening
methods can simply set this flag on instead of updating all these if
expressions.

The new name "deepen" was chosen after the command to define shallow
boundary in pack protocol. New commands also follow this tradition.

Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 fetch-pack.c | 14 --
 fetch-pack.h |  1 +
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/fetch-pack.c b/fetch-pack.c
index 08caf1d..a14d24a 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -197,7 +197,7 @@ enum ack_type {
 
 static void consume_shallow_list(struct fetch_pack_args *args, int fd)
 {
-   if (args->stateless_rpc && args->depth > 0) {
+   if (args->stateless_rpc && args->deepen) {
/* If we sent a depth we will get back "duplicate"
 * shallow and unshallow commands every time there
 * is a block of have lines exchanged.
@@ -348,7 +348,7 @@ static int find_common(struct fetch_pack_args *args,
packet_buf_flush(&req_buf);
state_len = req_buf.len;
 
-   if (args->depth > 0) {
+   if (args->deepen) {
char *line;
const char *arg;
unsigned char sha1[20];
@@ -557,7 +557,7 @@ static void filter_refs(struct fetch_pack_args *args,
}
 
if (!keep && args->fetch_all &&
-   (!args->depth || !starts_with(ref->name, "refs/tags/")))
+   (!args->deepen || !starts_with(ref->name, "refs/tags/")))
keep = 1;
 
if (keep) {
@@ -627,7 +627,7 @@ static int everything_local(struct fetch_pack_args *args,
}
}
 
-   if (!args->depth) {
+   if (!args->deepen) {
for_each_ref(mark_complete_oid, NULL);
for_each_alternate_ref(mark_alternate_complete, NULL);
commit_list_sort_by_date(&complete);
@@ -812,6 +812,8 @@ static struct ref *do_fetch_pack(struct fetch_pack_args 
*args,
 
if ((args->depth > 0 || is_repository_shallow()) && 
!server_supports("shallow"))
die(_("Server does not support shallow clients"));
+   if (args->depth > 0)
+   args->deepen = 1;
if (server_supports("multi_ack_detailed")) {
print_verbose(args, _("Server supports multi_ack_detailed"));
multi_ack = 2;
@@ -872,7 +874,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args 
*args,
 
if (args->stateless_rpc)
packet_flush(fd[1]);
-   if (args->depth > 0)
+   if (args->deepen)
setup_alternate_shallow(&shallow_lock, &alternate_shallow_file,
NULL);
else if (si->nr_ours || si->nr_theirs)
@@ -939,7 +941,7 @@ static void update_shallow(struct fetch_pack_args *args,
int *status;
int i;
 
-   if (args->depth > 0 && alternate_shallow_file) {
+   if (args->deepen && alternate_shallow_file) {
if (*alternate_shallow_file == '\0') { /* --unshallow */
unlink_or_warn(git_path_shallow());
rollback_lock_file(&shallow_lock);
diff --git a/fetch-pack.h b/fetch-pack.h
index bb7fd76..4d0adb0 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -25,6 +25,7 @@ struct fetch_pack_args {
unsigned self_contained_and_connected:1;
unsigned cloning:1;
unsigned update_shallow:1;
+   unsigned deepen:1;
 };
 
 /*
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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 04/27] upload-pack: move "shallow" sending code out of deepen()

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 upload-pack.c | 25 +++--
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/upload-pack.c b/upload-pack.c
index 97ed620..0eb9a0b 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -538,6 +538,20 @@ error:
}
 }
 
+static void send_shallow(struct commit_list *result)
+{
+   while (result) {
+   struct object *object = &result->item->object;
+   if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
+   packet_write(1, "shallow %s",
+oid_to_hex(&object->oid));
+   register_shallow(object->oid.hash);
+   shallow_nr++;
+   }
+   result = result->next;
+   }
+}
+
 static void deepen(int depth, const struct object_array *shallows)
 {
struct commit_list *result = NULL, *backup = NULL;
@@ -551,16 +565,7 @@ static void deepen(int depth, const struct object_array 
*shallows)
backup = result =
get_shallow_commits(&want_obj, depth,
SHALLOW, NOT_SHALLOW);
-   while (result) {
-   struct object *object = &result->item->object;
-   if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
-   packet_write(1, "shallow %s",
-oid_to_hex(&object->oid));
-   register_shallow(object->oid.hash);
-   shallow_nr++;
-   }
-   result = result->next;
-   }
+   send_shallow(result);
free_commit_list(backup);
for (i = 0; i < shallows->nr; i++) {
struct object *object = shallows->objects[i].item;
-- 
2.8.2.524.g6ff3d78

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


[PATCH v2 02/27] transport-helper.c: refactor set_helper_option()

2016-06-12 Thread Nguyễn Thái Ngọc Duy
For now we can handle two types, string and boolean, in
set_helper_option(). Later on we'll add string_list support, which does
not fit well. The new function strbuf_set_helper_option() can be reused
for a separate function that handles string-list.

Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 transport-helper.c | 37 +++--
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/transport-helper.c b/transport-helper.c
index a6bff8b..27a34e9 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -260,6 +260,28 @@ static const char *boolean_options[] = {
TRANS_OPT_FOLLOWTAGS,
};
 
+static int strbuf_set_helper_option(struct helper_data *data,
+   struct strbuf *buf)
+{
+   int ret;
+
+   sendline(data, buf);
+   if (recvline(data, buf))
+   exit(128);
+
+   if (!strcmp(buf->buf, "ok"))
+   ret = 0;
+   else if (starts_with(buf->buf, "error"))
+   ret = -1;
+   else if (!strcmp(buf->buf, "unsupported"))
+   ret = 1;
+   else {
+   warning("%s unexpectedly said: '%s'", data->name, buf->buf);
+   ret = 1;
+   }
+   return ret;
+}
+
 static int set_helper_option(struct transport *transport,
  const char *name, const char *value)
 {
@@ -291,20 +313,7 @@ static int set_helper_option(struct transport *transport,
quote_c_style(value, &buf, NULL, 0);
strbuf_addch(&buf, '\n');
 
-   sendline(data, &buf);
-   if (recvline(data, &buf))
-   exit(128);
-
-   if (!strcmp(buf.buf, "ok"))
-   ret = 0;
-   else if (starts_with(buf.buf, "error")) {
-   ret = -1;
-   } else if (!strcmp(buf.buf, "unsupported"))
-   ret = 1;
-   else {
-   warning("%s unexpectedly said: '%s'", data->name, buf.buf);
-   ret = 1;
-   }
+   ret = strbuf_set_helper_option(data, &buf);
strbuf_release(&buf);
return ret;
 }
-- 
2.8.2.524.g6ff3d78

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


[PATCH v2 01/27] remote-curl.c: convert fetch_git() to use argv_array

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 remote-curl.c | 46 ++
 1 file changed, 18 insertions(+), 28 deletions(-)

diff --git a/remote-curl.c b/remote-curl.c
index c704857..fd030c1 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -725,38 +725,28 @@ static int fetch_git(struct discovery *heads,
 {
struct rpc_state rpc;
struct strbuf preamble = STRBUF_INIT;
-   char *depth_arg = NULL;
-   int argc = 0, i, err;
-   const char *argv[17];
-
-   argv[argc++] = "fetch-pack";
-   argv[argc++] = "--stateless-rpc";
-   argv[argc++] = "--stdin";
-   argv[argc++] = "--lock-pack";
+   int i, err;
+   struct argv_array args = ARGV_ARRAY_INIT;
+
+   argv_array_pushl(&args, "fetch-pack", "--stateless-rpc",
+"--stdin", "--lock-pack", NULL);
if (options.followtags)
-   argv[argc++] = "--include-tag";
+   argv_array_push(&args, "--include-tag");
if (options.thin)
-   argv[argc++] = "--thin";
-   if (options.verbosity >= 3) {
-   argv[argc++] = "-v";
-   argv[argc++] = "-v";
-   }
+   argv_array_push(&args, "--thin");
+   if (options.verbosity >= 3)
+   argv_array_pushl(&args, "-v", "-v", NULL);
if (options.check_self_contained_and_connected)
-   argv[argc++] = "--check-self-contained-and-connected";
+   argv_array_push(&args, "--check-self-contained-and-connected");
if (options.cloning)
-   argv[argc++] = "--cloning";
+   argv_array_push(&args, "--cloning");
if (options.update_shallow)
-   argv[argc++] = "--update-shallow";
+   argv_array_push(&args, "--update-shallow");
if (!options.progress)
-   argv[argc++] = "--no-progress";
-   if (options.depth) {
-   struct strbuf buf = STRBUF_INIT;
-   strbuf_addf(&buf, "--depth=%lu", options.depth);
-   depth_arg = strbuf_detach(&buf, NULL);
-   argv[argc++] = depth_arg;
-   }
-   argv[argc++] = url.buf;
-   argv[argc++] = NULL;
+   argv_array_push(&args, "--no-progress");
+   if (options.depth)
+   argv_array_pushf(&args, "--depth=%lu", options.depth);
+   argv_array_push(&args, url.buf);
 
for (i = 0; i < nr_heads; i++) {
struct ref *ref = to_fetch[i];
@@ -769,7 +759,7 @@ static int fetch_git(struct discovery *heads,
 
memset(&rpc, 0, sizeof(rpc));
rpc.service_name = "git-upload-pack",
-   rpc.argv = argv;
+   rpc.argv = args.argv;
rpc.stdin_preamble = &preamble;
rpc.gzip_request = 1;
 
@@ -778,7 +768,7 @@ static int fetch_git(struct discovery *heads,
write_or_die(1, rpc.result.buf, rpc.result.len);
strbuf_release(&rpc.result);
strbuf_release(&preamble);
-   free(depth_arg);
+   argv_array_clear(&args);
return err;
 }
 
-- 
2.8.2.524.g6ff3d78

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


[PATCH v2 03/27] upload-pack: move shallow deepen code out of receive_needs()

2016-06-12 Thread Nguyễn Thái Ngọc Duy
This is a prep step for further refactoring. Besides reindentation and
s/shallows\./shallows->/g, no other changes are expected.

Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 upload-pack.c | 99 +++
 1 file changed, 52 insertions(+), 47 deletions(-)

diff --git a/upload-pack.c b/upload-pack.c
index b3f6653..97ed620 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -538,6 +538,55 @@ error:
}
 }
 
+static void deepen(int depth, const struct object_array *shallows)
+{
+   struct commit_list *result = NULL, *backup = NULL;
+   int i;
+   if (depth == INFINITE_DEPTH && !is_repository_shallow())
+   for (i = 0; i < shallows->nr; i++) {
+   struct object *object = shallows->objects[i].item;
+   object->flags |= NOT_SHALLOW;
+   }
+   else
+   backup = result =
+   get_shallow_commits(&want_obj, depth,
+   SHALLOW, NOT_SHALLOW);
+   while (result) {
+   struct object *object = &result->item->object;
+   if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
+   packet_write(1, "shallow %s",
+oid_to_hex(&object->oid));
+   register_shallow(object->oid.hash);
+   shallow_nr++;
+   }
+   result = result->next;
+   }
+   free_commit_list(backup);
+   for (i = 0; i < shallows->nr; i++) {
+   struct object *object = shallows->objects[i].item;
+   if (object->flags & NOT_SHALLOW) {
+   struct commit_list *parents;
+   packet_write(1, "unshallow %s",
+oid_to_hex(&object->oid));
+   object->flags &= ~CLIENT_SHALLOW;
+   /* make sure the real parents are parsed */
+   unregister_shallow(object->oid.hash);
+   object->parsed = 0;
+   parse_commit_or_die((struct commit *)object);
+   parents = ((struct commit *)object)->parents;
+   while (parents) {
+   add_object_array(&parents->item->object,
+NULL, &want_obj);
+   parents = parents->next;
+   }
+   add_object_array(object, NULL, &extra_edge_obj);
+   }
+   /* make sure commit traversal conforms to client */
+   register_shallow(object->oid.hash);
+   }
+   packet_flush(1);
+}
+
 static void receive_needs(void)
 {
struct object_array shallows = OBJECT_ARRAY_INIT;
@@ -630,53 +679,9 @@ static void receive_needs(void)
 
if (depth == 0 && shallows.nr == 0)
return;
-   if (depth > 0) {
-   struct commit_list *result = NULL, *backup = NULL;
-   int i;
-   if (depth == INFINITE_DEPTH && !is_repository_shallow())
-   for (i = 0; i < shallows.nr; i++) {
-   struct object *object = 
shallows.objects[i].item;
-   object->flags |= NOT_SHALLOW;
-   }
-   else
-   backup = result =
-   get_shallow_commits(&want_obj, depth,
-   SHALLOW, NOT_SHALLOW);
-   while (result) {
-   struct object *object = &result->item->object;
-   if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
-   packet_write(1, "shallow %s",
-   oid_to_hex(&object->oid));
-   register_shallow(object->oid.hash);
-   shallow_nr++;
-   }
-   result = result->next;
-   }
-   free_commit_list(backup);
-   for (i = 0; i < shallows.nr; i++) {
-   struct object *object = shallows.objects[i].item;
-   if (object->flags & NOT_SHALLOW) {
-   struct commit_list *parents;
-   packet_write(1, "unshallow %s",
-   oid_to_hex(&object->oid));
-   object->flags &= ~CLIENT_SHALLOW;
-   /* make sure the real parents are parsed */
-   unregister_shallow(object->oid.hash);
-   object->parsed = 0;
-   parse_commit_or_die((struct commit *)object);
-   parents = ((struct commit *)object)->parents;
-  

[PATCH v2 00/27] nd/shallow-deepen updates

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Second update to address Junio comments. Interdiff

diff --git a/upload-pack.c b/upload-pack.c
index ef693bd..e40d15a 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -453,6 +453,9 @@ static int is_our_ref(struct object *o)
return o->flags & ((allow_hidden_ref ? HIDDEN_REF : 0) | OUR_REF);
 }
 
+/*
+ * on successful case, it's up to the caller to close cmd->out
+ */
 static int do_reachable_revlist(struct child_process *cmd,
struct object_array *src,
struct object_array *reachable)
@@ -470,16 +473,16 @@ static int do_reachable_revlist(struct child_process *cmd,
cmd->in = -1;
cmd->out = -1;
 
-   if (start_command(cmd))
-   goto error;
-
/*
-* If rev-list --stdin encounters an unknown commit, it
-* terminates, which will cause SIGPIPE in the write loop
+* If the next rev-list --stdin encounters an unknown commit,
+* it terminates, which will cause SIGPIPE in the write loop
 * below.
 */
sigchain_push(SIGPIPE, SIG_IGN);
 
+   if (start_command(cmd))
+   goto error;
+
namebuf[0] = '^';
namebuf[41] = '\n';
for (i = get_max_object_index(); 0 < i; ) {
@@ -491,10 +494,8 @@ static int do_reachable_revlist(struct child_process *cmd,
if (!is_our_ref(o))
continue;
memcpy(namebuf + 1, oid_to_hex(&o->oid), GIT_SHA1_HEXSZ);
-   if (write_in_full(cmd->in, namebuf, 42) < 0) {
-   sigchain_pop(SIGPIPE);
+   if (write_in_full(cmd->in, namebuf, 42) < 0)
goto error;
-   }
}
namebuf[40] = '\n';
for (i = 0; i < src->nr; i++) {
@@ -507,18 +508,18 @@ static int do_reachable_revlist(struct child_process *cmd,
if (reachable && o->type == OBJ_COMMIT)
o->flags |= TMP_MARK;
memcpy(namebuf, oid_to_hex(&o->oid), GIT_SHA1_HEXSZ);
-   if (write_in_full(cmd->in, namebuf, 41) < 0) {
-   sigchain_pop(SIGPIPE);
+   if (write_in_full(cmd->in, namebuf, 41) < 0)
goto error;
-   }
}
close(cmd->in);
cmd->in = -1;
-
sigchain_pop(SIGPIPE);
+
return 0;
 
 error:
+   sigchain_pop(SIGPIPE);
+
if (cmd->in >= 0)
close(cmd->in);
if (cmd->out >= 0)
@@ -530,11 +531,11 @@ static int get_reachable_list(struct object_array *src,
  struct object_array *reachable)
 {
struct child_process cmd = CHILD_PROCESS_INIT;
-   int i, ret = do_reachable_revlist(&cmd, src, reachable);
+   int i;
struct object *o;
char namebuf[42]; /* ^ + SHA-1 + LF */
 
-   if (ret < 0)
+   if (do_reachable_revlist(&cmd, src, reachable) < 0)
return -1;
 
while ((i = read_in_full(cmd.out, namebuf, 41)) == 41) {
@@ -564,14 +565,14 @@ static int get_reachable_list(struct object_array *src,
return 0;
 }
 
-static int check_unreachable(struct object_array *src)
+static int has_unreachable(struct object_array *src)
 {
struct child_process cmd = CHILD_PROCESS_INIT;
char buf[1];
int i;
 
if (do_reachable_revlist(&cmd, src, NULL) < 0)
-   return 0;
+   return 1;
 
/*
 * The commits out of the rev-list are not ancestors of
@@ -592,14 +593,13 @@ static int check_unreachable(struct object_array *src)
goto error;
 
/* All the non-tip ones are ancestors of what we advertised */
-   return 1;
+   return 0;
 
 error:
-   if (cmd.in >= 0)
-   close(cmd.in);
+   sigchain_pop(SIGPIPE);
if (cmd.out >= 0)
close(cmd.out);
-   return 0;
+   return 1;
 }
 
 static void check_non_tip(void)
@@ -613,7 +613,7 @@ static void check_non_tip(void)
 */
if (!stateless_rpc && !(allow_unadvertised_object_request & 
ALLOW_REACHABLE_SHA1))
goto error;
-   if (check_unreachable(&want_obj))
+   if (!has_unreachable(&want_obj))
/* All the non-tip ones are ancestors of what we advertised */
return;
 
@@ -678,25 +678,33 @@ static void send_unshallow(const struct object_array 
*shallows)
 static void deepen(int depth, int deepen_relative,
   struct object_array *shallows)
 {
-   struct commit_list *result = NULL;
-   int i;
-   if (depth == INFINITE_DEPTH && !is_repository_shallow())
+   if (depth == INFINITE_DEPTH && !is_repository_shallow()) {
+   int i;
+
for (i = 0; i < shallows->nr; i++) {
struct object *object = shallows->objects[i].item;
object->flags |= NOT_SHALLOW;
}
-   else if (deepen_relative) {
+   }

lib-httpd/apache.conf and mod_unixd.so

2016-06-12 Thread Duy Nguyen
I need help from apache experts. On my system (gentoo 64bit,
apache-2.4.20), running an httpd test gives me

-- 8< --
Initialized empty Git repository in /home/pclouds/w/git/temp/t/trash
directory.t5539-fetch-http-shallow/.git/
checking prerequisite: NOT_ROOT

mkdir -p "$TRASH_DIRECTORY/prereq-test-dir" &&
(
cd "$TRASH_DIRECTORY/prereq-test-dir" &&
uid=$(id -u) &&
test "$uid" != 0

)
prerequisite NOT_ROOT ok
[Sun Jun 12 10:42:19.958873 2016] [core:crit] [pid 31585] AH00136:
Server MUST relinquish startup privileges before accepting
connections.  Please ensure mod_unixd or other system security module
is loaded.
AH00016: Configuration Failed
1..0 # SKIP web server setup failed
-- 8< --

A quick search shows that loading mod_unixd.so will do (and did make
httpd run for me). Problem is, can I just update apache.conf to load
it when apache version >= 2.4? I don't know if doing that would cause
failure for other people because mod_unixd has existed since 2.2 and
people have run httpd tests fine so far...
-- 
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/4] dir: introduce file_size() to check the size of file

2016-06-12 Thread Torsten Bögershausen
>> So what I understand, you want something like this:
>>
>> +ssize_t file_size_not_zero(const char *filename)
>> +{
>> +   struct stat st;
>> +   if (stat(filename, &st) < 0)
>> +   return -1;
>> +   return !!st.st_size);
>> +}
> 
> For the purpose of bisect_reset(), Yes. BTW a similar function exist
> in builtin/am.c with the name is_empty_file(). But as Christian points
> out file_size() could help to refactor other parts of code.
> 

Please allow one or more late comments:
If is_empty_file() does what you need, then it can be moved into wrapper.c
and simply be re-used in your code.

If you want to introduce a new function, that can be used for other refactoring,
then the whole thing would ideally go into a single commit,
or into a single series.
That may probably be out of the scope for your current efforts ?

What really makes me concern is the mixture of signed - and unsigned:
ssize_t file_size(const char *filename)
+{
+   struct stat st;
+   if (stat(filename, &st) < 0)
+   return -1;
+   return xsize_t(st.st_size);
+}

To my understanding a file size is either 0, or a positive integer.
Returning -1 is of course impossible with a positive integer.

So either the function is changed like this:

int file_size(const char *filename, size_t *len)
+{
+   struct stat st;
+   if (stat(filename, &st) < 0)
+   return -1;
+   *len = xsize_t(st.st_size);
+   return 0;
+}

Or, if that works for you:

size_t file_size(const char *filename)
+{
+   struct stat st;
+   if (stat(filename, &st) < 0)
+   return 0;
+   return xsize_t(st.st_size);
+}

Or, more git-ish:

size_t file_size(const char *filename)
+{
+   struct stat st;
+   if (stat(filename, &st))
+   return 0;
+   return xsize_t(st.st_size);
+}

(And then builtin/am.c  can be changed to use the new function.

 
--
To unsubscribe from this list: send the line "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] lib-httpd.sh: print error.log on error

2016-06-12 Thread Nguyễn Thái Ngọc Duy
Failure to bring up httpd for testing is not considered an error, so the
trash directory, which contains this error.log file, is removed and we
don't know what made httpd fail to start. Improve the situation a bit.

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 t/lib-httpd.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index f9f3e5f..5b8de38 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -180,6 +180,7 @@ start_httpd() {
if test $? -ne 0
then
trap 'die' EXIT
+   cat "$HTTPD_ROOT_PATH"/error.log 2>/dev/null
test_skip_or_die $GIT_TEST_HTTPD "web server setup failed"
fi
 }
-- 
2.8.2.524.g6ff3d78

--
To unsubscribe from this list: send the line "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: feature request: git svn dommit --preserve-timestamps

2016-06-12 Thread Peter Münster
On Sat, Jun 11 2016, Eric Wong wrote:

> I'm sorry for your situation and hoping you migrate off SVN
> entirely, soon :)

I've done so, but my customer won't. He wants the code in his svn-repo.


> Maybe you could look at how the _use_log_author and
> _add_author_from options work.  I've forgotten their existence
> until now and I've never used them myself; but apparently
> they're still there.

That would mean adding "Date: ..." to the log message.
Of course, I could do that. But then my customer would get confused
about these extra lines in the svn log.


It seems really to complicated, I think I'll just make a script, that
saves all important information (date, message, etc.) at every
git-commit to some kind of personal log-file, that I can use when I need
to search the history by date.

Nevertheless thanks for your efforts.
Kind regards,
-- 
   Peter
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html