Re: [PATCHv6] clone --single: limit the fetch refspec to fetched branch

2012-09-19 Thread Ralf Thielow
On Wed, Sep 19, 2012 at 9:36 AM, Nguyen Thai Ngoc Duy  wrote:
> On Wed, Sep 19, 2012 at 2:14 AM, Ralf Thielow  wrote:
>> +test_expect_success '--single-branch with explicit --branch tag' '
>> +   (
>> +   cd dir_tag && git fetch &&
>> +   git for-each-ref refs/tags >../actual
>> +   ) &&
>> +   git for-each-ref refs/tags >expect &&
>> +   test_cmp expect actual
>> +'
>
> We should have added the tag right after cloning, not until the first
> git-fetch. Not that I object how you do it in this patch. Just a note
> to myself that if I'm going to do that, I'll need to update this test
> to update the change tag before fetching and verify the tag is updated
> after git-fetch.
> --
> Duy

Right. I'll create two tests to replace this one. The first test
verifys that the tag
has been added after cloning. And in the second test, the tag gets updated in
the cloned repository and we verify that the next fetch updates the tag, which
catches my "delivery" tag example.
--
To unsubscribe from this list: send the line "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: [PATCHv6] clone --single: limit the fetch refspec to fetched branch

2012-09-19 Thread Nguyen Thai Ngoc Duy
On Wed, Sep 19, 2012 at 2:14 AM, Ralf Thielow  wrote:
> +test_expect_success '--single-branch with explicit --branch tag' '
> +   (
> +   cd dir_tag && git fetch &&
> +   git for-each-ref refs/tags >../actual
> +   ) &&
> +   git for-each-ref refs/tags >expect &&
> +   test_cmp expect actual
> +'

We should have added the tag right after cloning, not until the first
git-fetch. Not that I object how you do it in this patch. Just a note
to myself that if I'm going to do that, I'll need to update this test
to update the change tag before fetching and verify the tag is updated
after git-fetch.
-- 
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: [PATCHv6] clone --single: limit the fetch refspec to fetched branch

2012-09-18 Thread Junio C Hamano
Ralf Thielow  writes:

> + ...
> + # explicit --single with tag
> + git clone --single-branch --branch two . dir_tag &&
> +
> + # advance both "master" and "side" branches
> + git checkout side &&
> + echo five >file &&
> + git commit -a -m five &&
> + git checkout master &&
> + echo six >file &&
> + git commit -a -m six

Don't we also want to cover your "delivery" tag scenario by updating
the tag "two" before letting the clones fetch in the following test?

> + ...
> +test_expect_success '--single-branch with explicit --branch tag' '
> + (
> + cd dir_tag && git fetch &&
> + git for-each-ref refs/tags >../actual
> + ) &&
> + git for-each-ref refs/tags >expect &&
> + test_cmp expect actual
> +'
--
To unsubscribe from this list: send the line "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: [PATCHv6] clone --single: limit the fetch refspec to fetched branch

2012-09-18 Thread Junio C Hamano
Ralf Thielow  writes:

> After running "git clone --single", the resulting repository has the
> usual default "+refs/heads/*:refs/remotes/origin/*" wildcard fetch
> refspec installed, which means that a subsequent "git fetch" will
> end up grabbing all the other branches.
>
> Update the fetch refspec to cover only the singly cloned ref instead
> to correct this.
>
> That means:
> If "--single" is used without "--branch" or "--mirror", the
> fetch refspec covers the branch on which remote's HEAD points to.
> If "--single" is used with "--branch", it'll cover only the branch
> specified in the "--branch" option.
> If "--single" is combined with "--mirror", then it'll cover all
> refs of the cloned repository.
> If "--single" is used with "--branch" that specifies a tag, then
> it'll cover only the ref for this tag.
>
> Signed-off-by: Ralf Thielow 
> ---
>
> changes in v6
> - remove initial created tests (they tested in a too deep level)
> - add tests for "--mirror" option
> - add tests for the case of cloning a tag
> - update commit message
>
> I've tried to update "Documentation/git-clone.txt", but I don't
> know in which way this patch changes already described behaviour.
> The resulting refspec seems only be covered in the last part of
> the "--single-branch" section by describing "--no-single-branch",
> but this hasn't changed. Or did I miss something?

I do not think we are changing anything.  The whole "--single-branch"
was an half-baked afterthought hack that nobody anticipated the user
to later issue "git fetch" in the resulting repository, and everybody
involved in the series (the maintainer included) were just happy to
see the resulting code only transferred objects needed for the branch
without wasting bandwidth for objects needed for other branches, and
stopped thinking beyond that X-<.

If anything, we need to _add_ the description of what happens when
further fetches are done.  The second and the third paragraph in
the DESCRIPTION section talks only about the normal case, so at
least at the end of the second paragraph we should say "But if you
use --single-branch, all of this is different".  And what happens
when you do use --single-branch should be described in the part that
describes that option, e.g.

 Documentation/git-clone.txt | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git c/Documentation/git-clone.txt w/Documentation/git-clone.txt
index c1ddd4c..f59bc49 100644
--- c/Documentation/git-clone.txt
+++ w/Documentation/git-clone.txt
@@ -29,7 +29,8 @@ currently active branch.
 After the clone, a plain `git fetch` without arguments will update
 all the remote-tracking branches, and a `git pull` without
 arguments will in addition merge the remote master branch into the
-current master branch, if any.
+current master branch, if any (this is untrue when "--single-branch"
+is given; see below).
 
 This default configuration is achieved by creating references to
 the remote branch heads under `refs/remotes/origin` and
@@ -152,9 +153,11 @@ objects from the source repository into a pack in the 
cloned repository.
 -b ::
Instead of pointing the newly created HEAD to the branch pointed
to by the cloned repository's HEAD, point to `` branch
-   instead. `--branch` can also take tags and treat them like
-   detached HEAD. In a non-bare repository, this is the branch
+   instead. In a non-bare repository, this is the branch
that will be checked out.
++
+`--branch` can also take tags and detaches the HEAD
+at that commit in the resulting repository. 
 
 --upload-pack ::
 -u ::
@@ -193,6 +196,12 @@ objects from the source repository into a pack in the 
cloned repository.
clone with the `--depth` option, this is the default, unless
`--no-single-branch` is given to fetch the histories near the
tips of all branches.
++
+Further fetches into the resulting repository will only update the
+remote tracking branch for the branch this option was used for the
+initial cloning.  If the HEAD at the remote did not point at any
+branch when `--single-branch` clone was made, no remote tracking
+branch is created.
 
 --recursive::
 --recurse-submodules::
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv6] clone --single: limit the fetch refspec to fetched branch

2012-09-18 Thread Ralf Thielow
After running "git clone --single", the resulting repository has the
usual default "+refs/heads/*:refs/remotes/origin/*" wildcard fetch
refspec installed, which means that a subsequent "git fetch" will
end up grabbing all the other branches.

Update the fetch refspec to cover only the singly cloned ref instead
to correct this.

That means:
If "--single" is used without "--branch" or "--mirror", the
fetch refspec covers the branch on which remote's HEAD points to.
If "--single" is used with "--branch", it'll cover only the branch
specified in the "--branch" option.
If "--single" is combined with "--mirror", then it'll cover all
refs of the cloned repository.
If "--single" is used with "--branch" that specifies a tag, then
it'll cover only the ref for this tag.

Signed-off-by: Ralf Thielow 
---

changes in v6
- remove initial created tests (they tested in a too deep level)
- add tests for "--mirror" option
- add tests for the case of cloning a tag
- update commit message

I've tried to update "Documentation/git-clone.txt", but I don't
know in which way this patch changes already described behaviour.
The resulting refspec seems only be covered in the last part of
the "--single-branch" section by describing "--no-single-branch",
but this hasn't changed. Or did I miss something?

 builtin/clone.c  |  66 -
 t/t5709-clone-refspec.sh | 145 +++
 2 Dateien geändert, 197 Zeilen hinzugefügt(+), 14 Zeilen entfernt(-)
 create mode 100755 t/t5709-clone-refspec.sh

diff --git a/builtin/clone.c b/builtin/clone.c
index 5e8f3ba..431635c 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -610,6 +610,55 @@ static void write_config(struct string_list *config)
}
 }
 
+static void write_refspec_config(const char* src_ref_prefix,
+   const struct ref* our_head_points_at,
+   const struct ref* remote_head_points_at, struct strbuf* 
branch_top)
+{
+   struct strbuf key = STRBUF_INIT;
+   struct strbuf value = STRBUF_INIT;
+
+   if (option_mirror || !option_bare) {
+   if (option_single_branch && !option_mirror) {
+   if (option_branch) {
+   if (strstr(our_head_points_at->name, 
"refs/tags/"))
+   strbuf_addf(&value, "+%s:%s", 
our_head_points_at->name,
+   our_head_points_at->name);
+   else
+   strbuf_addf(&value, "+%s:%s%s", 
our_head_points_at->name,
+   branch_top->buf, option_branch);
+   } else if (remote_head_points_at) {
+   strbuf_addf(&value, "+%s:%s%s", 
remote_head_points_at->name,
+   branch_top->buf,
+   
skip_prefix(remote_head_points_at->name, "refs/heads/"));
+   }
+   /*
+* otherwise, the next "git fetch" will
+* simply fetch from HEAD without updating
+* any remote tracking branch, which is what
+* we want.
+*/
+   } else {
+   strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, 
branch_top->buf);
+   }
+   /* Configure the remote */
+   if (value.len) {
+   strbuf_reset(&key);
+   strbuf_addf(&key, "remote.%s.fetch", option_origin);
+   git_config_set_multivar(key.buf, value.buf, "^$", 0);
+   strbuf_reset(&key);
+
+   if (option_mirror) {
+   strbuf_addf(&key, "remote.%s.mirror", 
option_origin);
+   git_config_set(key.buf, "true");
+   strbuf_reset(&key);
+   }
+   }
+   }
+
+   strbuf_release(&key);
+   strbuf_release(&value);
+}
+
 int cmd_clone(int argc, const char **argv, const char *prefix)
 {
int is_bundle = 0, is_local;
@@ -755,20 +804,6 @@ int cmd_clone(int argc, const char **argv, const char 
*prefix)
}
 
strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
-
-   if (option_mirror || !option_bare) {
-   /* Configure the remote */
-   strbuf_addf(&key, "remote.%s.fetch", option_origin);
-   git_config_set_multivar(key.buf, value.buf, "^$", 0);
-   strbuf_reset(&key);
-
-   if (option_mirror) {
-   strbuf_addf(&key, "remote.%s.mirror", option_origin);
-   git_config_set(key.buf, "true");
-   strbuf_reset(&key);
-   }
-   }
-
strbuf_addf(&key, "remote.%s.url", option_origin);
git