Quantcast

is this behaviour expected for "git clone --single-branch"?

classic Classic list List threaded Threaded
39 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

is this behaviour expected for "git clone --single-branch"?

Ralf Thielow-2
Hi,

I know people which have a separate directory for every
branch. In this case it doesn't make sense to download
the whole repo with all branches. So I guess the
"--single-branch" option is the solution in that case!?!
But I'm wondering about it's behaviour.

# first clone the branch of the repo
$git clone --single-branch --branch master myrepo ./master
$cd master

# now calling "git branch -a" to see what I have
$git branch -a
*master
remotes/origin/HEAD -> origin/master
remotes/origin/master

# fine, now pulling from origin
$git pull
From myrepo
* [new branch]  foo  -> origin/foo
* [new branch] bar -> origin/bar
...

Hm?

# looking again to my branches
$git branch -a
*master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/bar
remotes/origin/foo
...

After cloning (or fetching), I now have all branches which is not
what I want, because I'm only interested in the one I've cloned.
I think it's not very useful for the use-case of having one directory
for one branch.

$git version
git version 1.7.12.395.g6b149ce

Thanks
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: is this behaviour expected for "git clone --single-branch"?

Junio C Hamano
Ralf Thielow <[hidden email]> writes:

> # looking again to my branches

Don't look at your branches, but look at how the refspecs are
configured by "git clone" in .git/config; I suspect we just write
the default 'refs/heads/*:refs/remotes/origin/*' pattern.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: is this behaviour expected for "git clone --single-branch"?

Ralf Thielow-2
On Thu, Sep 13, 2012 at 8:45 PM, Junio C Hamano <[hidden email]> wrote:
> Ralf Thielow <[hidden email]> writes:
>
>> # looking again to my branches
>
> Don't look at your branches, but look at how the refspecs are
> configured by "git clone" in .git/config; I suspect we just write
> the default 'refs/heads/*:refs/remotes/origin/*' pattern.

Indeed.

$ cat .git/config
[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH] clone: fix refspec on "--single-branch" option

Ralf Thielow-2
After using "git clone" with the "--single-branch"
option, the configured refspec for this repo was
"+refs/heads/*:refs/remotes/origin/*".
After fetching changes from this repo again, it'll
receive all refs instead of the single ref which
was used in "--single-branch". Fixing the refspec
that it just contains the ref of the branch which
was cloned.

Signed-off-by: Ralf Thielow <[hidden email]>
---
 builtin/clone.c | 5 ++++-
 1 Datei geändert, 4 Zeilen hinzugefügt(+), 1 Zeile entfernt(-)

diff --git a/builtin/clone.c b/builtin/clone.c
index 5e8f3ba..3e74d55 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -754,7 +754,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
  strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin);
  }
 
- strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
+ if (option_single_branch)
+ strbuf_addf(&value, "+%s%s:%s%s", src_ref_prefix, option_branch, branch_top.buf, option_branch);
+ else
+ strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
 
  if (option_mirror || !option_bare) {
  /* Configure the remote */
--
1.7.12.395.g6b149ce.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] clone: fix refspec on "--single-branch" option

Junio C Hamano
Ralf Thielow <[hidden email]> writes:

> After using "git clone" with the "--single-branch"
> option, the configured refspec for this repo was
> "+refs/heads/*:refs/remotes/origin/*".
> After fetching changes from this repo again, it'll
> receive all refs instead of the single ref which
> was used in "--single-branch". Fixing the refspec
> that it just contains the ref of the branch which
> was cloned.
>
> Signed-off-by: Ralf Thielow <[hidden email]>
> ---
>  builtin/clone.c | 5 ++++-
>  1 Datei geändert, 4 Zeilen hinzugefügt(+), 1 Zeile entfernt(-)
>
> diff --git a/builtin/clone.c b/builtin/clone.c
> index 5e8f3ba..3e74d55 100644
> --- a/builtin/clone.c
> +++ b/builtin/clone.c
> @@ -754,7 +754,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
>   strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin);
>   }
>  
> - strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
> + if (option_single_branch)
> + strbuf_addf(&value, "+%s%s:%s%s", src_ref_prefix, option_branch, branch_top.buf, option_branch);
> + else
> + strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);

Who guarantees at this point in the codepath that option_branch is
set when option_single_branch is non-zero?  Until we talk with the
remote, "clone --single-branch" without an explicit "--branch" will
not learn which branch at the remote we are going to fetch (it will
be their HEAD).

I wonder if this should be more like this:

        if (option_single_branch) {
                if (option_branch)
                        Your patch "+refs/heads/foo:refs/remotes/origin/foo";
                else
                        "HEAD";
        } else {
        Original "+refs/heads/*:refs/remotes/origin/*";
        }

That is, "clone --single-branch" will continue fetching from and
integrating with their HEAD without storing any remote tracking
branch.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] clone: fix refspec on "--single-branch" option

Junio C Hamano
Junio C Hamano <[hidden email]> writes:

> Who guarantees at this point in the codepath that option_branch is
> set when option_single_branch is non-zero?  Until we talk with the
> remote, "clone --single-branch" without an explicit "--branch" will
> not learn which branch at the remote we are going to fetch (it will
> be their HEAD).
>
> I wonder if this should be more like this:
>
> if (option_single_branch) {
> if (option_branch)
> Your patch "+refs/heads/foo:refs/remotes/origin/foo";
> else
> "HEAD";
>         } else {
>         Original "+refs/heads/*:refs/remotes/origin/*";
> }
>
> That is, "clone --single-branch" will continue fetching from and
> integrating with their HEAD without storing any remote tracking
> branch.

Alternatively, if you can move the logic to set up this
configuration further down so that it happens after we talked to the
other side and figured out remote_head_points_at, you could instead
set it up to keep a single remote tracking branch.

Even if you did so, guess_remote_head() may not find any branch when
the other repository's HEAD is detached, so you would need to decide
what to do in such a case, and "fetch and integrate their HEAD
without using any remote tracking branch" may be a reasonable thing
to do in such a case.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] clone: fix refspec on "--single-branch" option

Duy Nguyen
On Fri, Sep 14, 2012 at 1:48 PM, Junio C Hamano <[hidden email]> wrote:

> Junio C Hamano <[hidden email]> writes:
>
>> Who guarantees at this point in the codepath that option_branch is
>> set when option_single_branch is non-zero?  Until we talk with the
>> remote, "clone --single-branch" without an explicit "--branch" will
>> not learn which branch at the remote we are going to fetch (it will
>> be their HEAD).
>>
>> I wonder if this should be more like this:
>>
>>       if (option_single_branch) {
>>               if (option_branch)
>>                       Your patch "+refs/heads/foo:refs/remotes/origin/foo";
>>               else
>>                       "HEAD";
>>         } else {
>>               Original "+refs/heads/*:refs/remotes/origin/*";
>>       }
>>
>> That is, "clone --single-branch" will continue fetching from and
>> integrating with their HEAD without storing any remote tracking
>> branch.
>
> Alternatively, if you can move the logic to set up this
> configuration further down so that it happens after we talked to the
> other side and figured out remote_head_points_at, you could instead
> set it up to keep a single remote tracking branch.

That sounds reasonable. I have a question though, what should a user
do when he/she want to fetch all branches again? Messing up with
refspec in config file is not something I would like to do.

Perhaps a heuristic in git-fetch to detect "single branch" situation
and ignore refspec? We could hint people that refspecs are not
followed when remote has more than one branch. They could either fetch
the another branch explicitly, which turns off the heuristic, or turn
off the advice.

> Even if you did so, guess_remote_head() may not find any branch when
> the other repository's HEAD is detached, so you would need to decide
> what to do in such a case, and "fetch and integrate their HEAD
> without using any remote tracking branch" may be a reasonable thing
> to do in such a case.
--
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] clone: fix refspec on "--single-branch" option

Ralf Thielow-2
On Fri, Sep 14, 2012 at 3:10 PM, Nguyen Thai Ngoc Duy <[hidden email]> wrote:

> On Fri, Sep 14, 2012 at 1:48 PM, Junio C Hamano <[hidden email]> wrote:
>> Junio C Hamano <[hidden email]> writes:
>>
>>> Who guarantees at this point in the codepath that option_branch is
>>> set when option_single_branch is non-zero?  Until we talk with the
>>> remote, "clone --single-branch" without an explicit "--branch" will
>>> not learn which branch at the remote we are going to fetch (it will
>>> be their HEAD).
>>>
>>> I wonder if this should be more like this:
>>>
>>>       if (option_single_branch) {
>>>               if (option_branch)
>>>                       Your patch "+refs/heads/foo:refs/remotes/origin/foo";
>>>               else
>>>                       "HEAD";
>>>         } else {
>>>               Original "+refs/heads/*:refs/remotes/origin/*";
>>>       }
>>>
>>> That is, "clone --single-branch" will continue fetching from and
>>> integrating with their HEAD without storing any remote tracking
>>> branch.
>>
>> Alternatively, if you can move the logic to set up this
>> configuration further down so that it happens after we talked to the
>> other side and figured out remote_head_points_at, you could instead
>> set it up to keep a single remote tracking branch.
>
> That sounds reasonable. I have a question though, what should a user
> do when he/she want to fetch all branches again? Messing up with
> refspec in config file is not something I would like to do.
>

$ git remote set-branches <remote> "*"

> Perhaps a heuristic in git-fetch to detect "single branch" situation
> and ignore refspec? We could hint people that refspecs are not
> followed when remote has more than one branch. They could either fetch
> the another branch explicitly, which turns off the heuristic, or turn
> off the advice.
>

Such an advice when using "--single-branch" is a good idea, i think.
Something like "The remote <remote> is configured to fetch only branch <branch>.
If you want to fetch all branches, use "git remote set-branches <remote> "*""
or something like that.

>> Even if you did so, guess_remote_head() may not find any branch when
>> the other repository's HEAD is detached, so you would need to decide
>> what to do in such a case, and "fetch and integrate their HEAD
>> without using any remote tracking branch" may be a reasonable thing
>> to do in such a case.
> --
> Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] clone: fix refspec on "--single-branch" option

Junio C Hamano
In reply to this post by Duy Nguyen
Nguyen Thai Ngoc Duy <[hidden email]> writes:

> On Fri, Sep 14, 2012 at 1:48 PM, Junio C Hamano <[hidden email]> wrote:
>
>> Alternatively, if you can move the logic to set up this
>> configuration further down so that it happens after we talked to the
>> other side and figured out remote_head_points_at, you could instead
>> set it up to keep a single remote tracking branch.
>
> That sounds reasonable. I have a question though, what should a user
> do when he/she want to fetch all branches again? Messing up with
> refspec in config file is not something I would like to do.

You first have to think ;-).

I would say there are two kinds of users.

 - To the simplistic ones who fear the power of configuration, we
   can simply tell "You don't. Use 'single' when you want to keep
   working with the single branch. If you want full, reclone, and
   migrate your work from the single one by fetching from it to the
   full clone before discarding the single one".

 - To the ones who wants to take the full advantage of flexibility
   of configuration, we can tell "remotes.$name.fetch configuration
   is your friend. Do whatever you want to do with it, but here are
   two hints".  The hints would cover the case to revert to the
   default refspec, and the case to add another specific branch.

These days, with "git config" and "git remote" wrappers, I do not
particularly see a need to fear the power of configuration, though.



--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCHv2] clone: fix refspec on "--single-branch" option

Ralf Thielow-2
In reply to this post by Junio C Hamano
After a repo was cloned with the "--single-branch"
option, the configured refspec looks like
"+refs/heads/*:refs/remotes/origin/*".
After fetching from this repo again, it'll receive
all refs instead of just the ref from the single
branch. Fixing this by configure exactly the ref
of the branch the user specified in the "git clone"
command.

Signed-off-by: Ralf Thielow <[hidden email]>
---

> Alternatively, if you can move the logic to set up this
> configuration further down so that it happens after we talked to the
> other side and figured out remote_head_points_at, you could instead
> set it up to keep a single remote tracking branch.
>
> Even if you did so, guess_remote_head() may not find any branch when
> the other repository's HEAD is detached, so you would need to decide
> what to do in such a case, and "fetch and integrate their HEAD
> without using any remote tracking branch" may be a reasonable thing
> to do in such a case.

This second version now covers also the "--single-branch"
option when it was called without "--branch". It also covers
the "detached HEAD" case.
I've tested all the use-cases that have been described above and it works
as expected with this patch. But there's just one thing. It fetches
also all the tags even if they're not on this branch. I'm still in the
"learning process", perhaps someone else can fix this problem or point
me to the reason.
I think it comes from "transport_fetch_refs(transport, mapped_refs);"
on line 813 which is called with a full "+refs/heads/*:refs/remotes/origin/*"
refspec. Thanks

 builtin/clone.c | 41 +++++++++++++++++++++++++++--------------
 1 Datei geändert, 27 Zeilen hinzugefügt(+), 14 Zeilen entfernt(-)

diff --git a/builtin/clone.c b/builtin/clone.c
index 5e8f3ba..3ddf5ab 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -755,20 +755,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_config_set(key.buf, repo);
  strbuf_reset(&key);
@@ -853,6 +839,33 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
       "refs/heads/master");
  }
 
+ if (option_mirror || !option_bare) {
+ strbuf_reset(&value);
+ if (option_single_branch) {
+ if (option_branch)
+ strbuf_addf(&value, "+%s%s:%s%s", src_ref_prefix, option_branch,
+ branch_top.buf, option_branch);
+ else if (remote_head_points_at)
+ strbuf_addf(&value, "+%s:%s%s", our_head_points_at->name,
+ branch_top.buf, prettify_refname(remote_head_points_at->name));
+ } 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);
+ }
+ }
+ }
+
  if (is_local)
  clone_local(path, git_dir);
  else if (refs && complete_refs_before_fetch)
--
1.7.12.395.g6b149ce.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH] clone: fix refspec on "--single-branch" option

Junio C Hamano
In reply to this post by Junio C Hamano
Junio C Hamano <[hidden email]> writes:

> Alternatively, if you can move the logic to set up this
> configuration further down so that it happens after we talked to the
> other side and figured out remote_head_points_at, you could instead
> set it up to keep a single remote tracking branch.
>
> Even if you did so, guess_remote_head() may not find any branch when
> the other repository's HEAD is detached, so you would need to decide
> what to do in such a case, and "fetch and integrate their HEAD
> without using any remote tracking branch" may be a reasonable thing
> to do in such a case.

Along the lines of this, perhaps.

 builtin/clone.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git i/builtin/clone.c w/builtin/clone.c
index 5e8f3ba..c9e099d 100644
--- i/builtin/clone.c
+++ w/builtin/clone.c
@@ -853,6 +853,22 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
       "refs/heads/master");
  }
 
+ if (option_single_branch) {
+ /* Fix up the refspec for fetch */
+ strbuf_reset(&value);
+ if (!remote_head_points_at)
+ strbuf_addf(&value, "HEAD");
+ else
+ strbuf_addf(&value, "%s:%s%s",
+    remote_head_points_at->name,
+    branch_top.buf,
+    skip_prefix(remote_head_points_at->name, "refs/heads/"));
+
+ strbuf_reset(&key);
+ strbuf_addf(&key, "remote.%s.fetch", option_origin);
+ git_config_set_multivar(key.buf, value.buf, NULL, 1);
+ }
+
  if (is_local)
  clone_local(path, git_dir);
  else if (refs && complete_refs_before_fetch)
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCHv2] clone: fix refspec on "--single-branch" option

Junio C Hamano
In reply to this post by Ralf Thielow-2
Ralf Thielow <[hidden email]> writes:

> + else if (remote_head_points_at)
> + strbuf_addf(&value, "+%s:%s%s", our_head_points_at->name,
> + branch_top.buf, prettify_refname(remote_head_points_at->name));

As refspec maps names that appear on the source side to names that
appear on the destination side, and for fetch, the "soruce side"
is the remote, using "our_head_points_at" on the source side makes
it look very fishy (even though it may be a name derived from
remote_head_points_at and has the correct and appropriate value).

"prettify" also is very questionable.  It is meant to strip commonly
known prefix to make it easier to read by humans, and we can change
its result based solely on aesthetics in the future.  It is not
suitable for coming up with a value for configuration in the longer
term.

Can we make the part you moved de-dented a bit, perhaps by making it
into a small helper function or something?  It is extremely hard to
read with overly looooooong lines.

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCHv3] clone: fix refspec on "--single-branch" option

Ralf Thielow-2
After a repo was cloned with the "--single-branch"
option, the configured refspec looks like
"+refs/heads/*:refs/remotes/origin/*".
After fetching from this repo again, it'll receive
all refs instead of just the ref from the single
branch. Fixing this by configure exactly the ref
of the branch the user specified in the "git clone"
command.

Signed-off-by: Ralf Thielow <[hidden email]>
---

> As refspec maps names that appear on the source side to names that
> appear on the destination side, and for fetch, the "soruce side"
> is the remote, using "our_head_points_at" on the source side makes
> it look very fishy (even though it may be a name derived from
> remote_head_points_at and has the correct and appropriate value).
>
> "prettify" also is very questionable.  It is meant to strip commonly
> known prefix to make it easier to read by humans, and we can change
> its result based solely on aesthetics in the future.  It is not
> suitable for coming up with a value for configuration in the longer
> term.
>

Thanks. I've fixed.

> Can we make the part you moved de-dented a bit, perhaps by making it
> into a small helper function or something?  It is extremely hard to
> read with overly looooooong lines.
>

Would be nice but the list of arguments will become too long.
I did a bit of reformating and think it now looks a bit nicer.

 builtin/clone.c | 43 +++++++++++++++++++++++++++++--------------
 1 Datei geändert, 29 Zeilen hinzugefügt(+), 14 Zeilen entfernt(-)

diff --git a/builtin/clone.c b/builtin/clone.c
index 5e8f3ba..06e3d3a 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -755,20 +755,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_config_set(key.buf, repo);
  strbuf_reset(&key);
@@ -853,6 +839,35 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
       "refs/heads/master");
  }
 
+ if (option_mirror || !option_bare) {
+ strbuf_reset(&value);
+ if (option_single_branch) {
+ if (option_branch)
+ strbuf_addf(&value, "+%s%s:%s%s",
+ src_ref_prefix, option_branch,
+ 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/"));
+ } 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);
+ }
+ }
+ }
+
  if (is_local)
  clone_local(path, git_dir);
  else if (refs && complete_refs_before_fetch)
--
1.7.12.396.g3cff853.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCHv3] clone: fix refspec on "--single-branch" option

Junio C Hamano
Ralf Thielow <[hidden email]> writes:

> + if (option_mirror || !option_bare) {
> + strbuf_reset(&value);
> + if (option_single_branch) {
> + if (option_branch)
> + strbuf_addf(&value, "+%s%s:%s%s",
> + src_ref_prefix, option_branch,
> + 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/"));

We have already set "remote.origin.url" to this repository, so the
next "git fetch" would simply fetch from "HEAD" per default.
Perhaps worth commenting that here?

Other than that, looks good.  Perhaps we would want a test or two,
too?

Thanks.

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Ralf Thielow-2
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.

Signed-off-by: Ralf Thielow <[hidden email]>
---

Changes to v3:
- use commit message from Junio's topic branch
- add comment for the 'detached HEAD' case (also from Junio's topic branch)
(thanks for that)
- add tests for the refspec installed by the clone command

 builtin/clone.c          | 49 ++++++++++++++++++++++++++++------------
 t/t5709-clone-refspec.sh | 59 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 Dateien geändert, 94 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..be4c62b 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -755,20 +755,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_config_set(key.buf, repo);
  strbuf_reset(&key);
@@ -853,6 +839,41 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
       "refs/heads/master");
  }
 
+ if (option_mirror || !option_bare) {
+ strbuf_reset(&value);
+ if (option_single_branch) {
+ if (option_branch)
+ strbuf_addf(&value, "+%s%s:%s%s",
+ src_ref_prefix, option_branch,
+ 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);
+ }
+ }
+ }
+
  if (is_local)
  clone_local(path, git_dir);
  else if (refs && complete_refs_before_fetch)
diff --git a/t/t5709-clone-refspec.sh b/t/t5709-clone-refspec.sh
new file mode 100755
index 0000000..f4c8e31
--- /dev/null
+++ b/t/t5709-clone-refspec.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+test_description='test refspec written by clone-command'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ echo one >file &&
+ git add file &&
+ git commit -m one &&
+ echo two >file &&
+ git commit -a -m two &&
+ git tag two &&
+ echo three >file &&
+ git commit -a -m three &&
+ git checkout -b foo &&
+ echo four >file &&
+ git commit -a -m four &&
+ git checkout master
+'
+
+test_expect_success 'refspec contains all branches by default' '
+ git clone "file://$PWD" dir_all &&
+ echo "+refs/heads/*:refs/remotes/origin/*" > expected &&
+ git --git-dir=dir_all/.git config --get remote.origin.fetch > actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'refspec contains only master with option --single-branch and remotes HEAD point to master' '
+ git clone --single-branch "file://$PWD" dir_master &&
+ echo "+refs/heads/master:refs/remotes/origin/master" > expected &&
+ git --git-dir=dir_master/.git config --get remote.origin.fetch > actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'refspec contains only foo with option --single-branch and remotes HEAD point to foo' '
+ git checkout foo &&
+ git clone --single-branch "file://$PWD" dir_foo &&
+ echo "+refs/heads/foo:refs/remotes/origin/foo" > expected &&
+ git --git-dir=dir_foo/.git config --get remote.origin.fetch > actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'refspec contains one branch after using option --single-branch with --branch' '
+ git checkout master &&
+ git clone --single-branch --branch foo "file://$PWD" dir_foo2 &&
+ echo "+refs/heads/foo:refs/remotes/origin/foo" > expected &&
+ git --git-dir=dir_foo2/.git config --get remote.origin.fetch > actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'no refspec is written if remotes HEAD is detached' '
+ git checkout two^ &&
+ git clone --single-branch "file://$PWD" dir_detached &&
+ rm expected && touch expected &&
+ git --git-dir=dir_detached/.git config --get remote.origin.fetch > actual
+ test_cmp expected actual
+'
+
+test_done
--
1.7.12.396.g6bea32d.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Junio C Hamano
Ralf Thielow <[hidden email]> writes:

> - add tests for the refspec installed by the clone command

Thanks.

> +test_expect_success 'refspec contains all branches by default' '
> + git clone "file://$PWD" dir_all &&

There have been numerous "on windows which should we use, $PWD or
$(pwd)?" gotchas.  In this particular case, wouldn't the tests work
equally well with "." to avoid the uneasiness factor?

> + echo "+refs/heads/*:refs/remotes/origin/*" > expected &&
> + git --git-dir=dir_all/.git config --get remote.origin.fetch > actual &&
> + test_cmp expected actual

I am a bit torn with this one.

We'd want to make sure a single clone from a repository with two
branches will not result in a repository where the next fetch will
not pull in the other branch, and the value of the
"remote.origin.fetch" is an implementation detail that happen to be
what affects the outcome.  The test is not checking the expected
outcome in a direct way (imagine how this test will break when we do
another change similar to the migration from .git/remotes/origin to
the remote.origin.fetch variables).

I'll let it pass for now, though.

> +test_expect_success 'no refspec is written if remotes HEAD is detached' '
> + git checkout two^ &&
> + git clone --single-branch "file://$PWD" dir_detached &&
> + rm expected && touch expected &&

If earlier tests failed, there may not be any expected file and the
"rm expected" will fail.  You can just say

        >expected &&

instead.  "touch" is a way to update the timestamp of the file; do
not use it when you want to make sure an empty file exists.

> + git --git-dir=dir_detached/.git config --get remote.origin.fetch > actual
> + test_cmp expected actual
> +'

I'd feel better if the test were like this instead:

        git checkout two^ &&
        git clone --single-branch . dir_detached &&
        (
                cd dir_detached &&
                git fetch &&
                git for-each-ref refs/remotes/origin >actual
        ) &&
        >expect &&
        test_cmp expect actual

That is what I would call "testing the desired results in the most
direct way".

Perhaps like this?

-- >8 -- t5709-clone-refspec.sh -- >8 --
#!/bin/sh

test_description='test refspec written by clone-command'
. ./test-lib.sh

test_expect_success 'setup' '
        # Make two branches, "master" and "side"
        echo one >file &&
        git add file &&
        git commit -m one &&
        echo two >file &&
        git commit -a -m two &&
        git tag two &&
        echo three >file &&
        git commit -a -m three &&
        git checkout -b side &&
        echo four >file &&
        git commit -a -m four &&
        git checkout master &&

        # default clone
        git clone . dir_all &&

        # default --single that follows HEAD=master
        git clone --single-branch . dir_master &&

        # default --single that follows HEAD=side
        git checkout side &&
        git clone --single-branch . dir_side &&

        # explicit --single that follows side
        git checkout master &&
        git clone --single-branch --branch side . dir_side2 &&

        # --single that does not know what branch to follow
        git checkout two^ &&
        git clone --single-branch . dir_detached &&

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

test_expect_success 'by default all branches will be kept updated' '
        (
                cd dir_all && git fetch &&
                git for-each-ref refs/remotes/origin |
                sed -e "/HEAD$/d" \
                    -e "s|/remotes/origin/|/heads/|" >../actual
        ) &&
        # follow both master and side
        git for-each-ref refs/heads >expect &&
        test_cmp expect actual
'

test_expect_success '--single-branch while HEAD pointing at master' '
        (
                cd dir_master && git fetch &&
                git for-each-ref refs/remotes/origin |
                sed -e "/HEAD$/d" \
                    -e "s|/remotes/origin/|/heads/|" >../actual
        ) &&
        # only follow master
        git for-each-ref refs/heads/master >expect &&
        test_cmp expect actual
'

test_expect_success '--single-branch while HEAD pointing at side' '
        (
                cd dir_side && git fetch &&
                git for-each-ref refs/remotes/origin |
                sed -e "/HEAD$/d" \
                    -e "s|/remotes/origin/|/heads/|" >../actual
        ) &&
        # only follow side
        git for-each-ref refs/heads/side >expect &&
        test_cmp expect actual
'

test_expect_success '--single-branch with explicit --branch side' '
        (
                cd dir_side2 && git fetch &&
                git for-each-ref refs/remotes/origin |
                sed -e "/HEAD$/d" \
                    -e "s|/remotes/origin/|/heads/|" >../actual
        ) &&
        # only follow side
        git for-each-ref refs/heads/side >expect &&
        test_cmp expect actual
'

test_expect_success '--single-branch with detached' '
        (
                cd dir_detached && git fetch &&
                git for-each-ref refs/remotes/origin |
                sed -e "/HEAD$/d" \
                    -e "s|/remotes/origin/|/heads/|" >../actual
        )
        # nothing
        >expect &&
        test_cmp expect actual
'

test_done
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Duy Nguyen
In reply to this post by Ralf Thielow-2
On Sun, Sep 16, 2012 at 3:13 PM, Ralf Thielow <[hidden email]> wrote:
> +       if (option_mirror || !option_bare) {
> +               strbuf_reset(&value);

I think we should use a new strbuf local variable here to avoid
resetting this. At least reviewers don't have to check if this
statememt causes any effect later on because "value"'s value is gone.

> +               if (option_single_branch) {
> +                       if (option_branch)
> +                               strbuf_addf(&value, "+%s%s:%s%s",
> +                                               src_ref_prefix, option_branch,
> +                                               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.
> +                        */

Maybe document updates too? Though if it's obvious that
--single-branch should prepare refspec so that only one branch is
fetched later on, then maybe not.

> +               } else {
> +                       strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
> +               }

--mirror --single-branch combination does not look right. The "heads/"
part is missing..

$ git branch
  master * wildmatch
$ LANG=C ./git clone --mirror --single-branch .git abc
Cloning into bare repository 'abc'...
done.
$ grep fetch abc/config
        fetch = +refs/heads/wildmatch:refs/wildmatch
$ rm -rf abc
$ LANG=C ./git clone --mirror --single-branch --branch=master .git abc
Cloning into bare repository 'abc'...
done.
$ grep fetch abc/config
        fetch = +refs/master:refs/master
--
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Duy Nguyen
On Mon, Sep 17, 2012 at 7:06 PM, Nguyen Thai Ngoc Duy <[hidden email]> wrote:
> --mirror --single-branch combination does not look right. The "heads/"
> part is missing..

It also does not look right for cloning a tag:

$ LANG=C ./git clone --single-branch --branch=v1.7.0 .git abc
Cloning into 'abc'...
done.
Note: checking out 'e923eaeb901ff056421b9007adcbbce271caa7b6'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

$ grep fetch abc/.git/config
        fetch = +refs/heads/v1.7.0:refs/remotes/origin/v1.7.0
--
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Ralf Thielow-2
In reply to this post by Duy Nguyen
On Mon, Sep 17, 2012 at 2:06 PM, Nguyen Thai Ngoc Duy <[hidden email]> wrote:
> On Sun, Sep 16, 2012 at 3:13 PM, Ralf Thielow <[hidden email]> wrote:
>> +       if (option_mirror || !option_bare) {
>> +               strbuf_reset(&value);
>
> I think we should use a new strbuf local variable here to avoid
> resetting this. At least reviewers don't have to check if this
> statememt causes any effect later on because "value"'s value is gone.
>

It seems that we don't need this reset here because it's already
done earlier in this function. The variable "key" is also used multiple
times so I wouldn't use a new variable.

>> +               if (option_single_branch) {
>> +                       if (option_branch)
>> +                               strbuf_addf(&value, "+%s%s:%s%s",
>> +                                               src_ref_prefix, option_branch,
>> +                                               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.
>> +                        */
>
> Maybe document updates too? Though if it's obvious that
> --single-branch should prepare refspec so that only one branch is
> fetched later on, then maybe not.
>

I think it's obvious.

>> +               } else {
>> +                       strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
>> +               }
>
> --mirror --single-branch combination does not look right. The "heads/"
> part is missing..
>
> $ git branch
>   master * wildmatch
> $ LANG=C ./git clone --mirror --single-branch .git abc
> Cloning into bare repository 'abc'...
> done.
> $ grep fetch abc/config
>         fetch = +refs/heads/wildmatch:refs/wildmatch
> $ rm -rf abc
> $ LANG=C ./git clone --mirror --single-branch --branch=master .git abc
> Cloning into bare repository 'abc'...
> done.
> $ grep fetch abc/config
>         fetch = +refs/master:refs/master
> --
> Duy

Thanks, I'll check this later and send a new version.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Ralf Thielow-2
In reply to this post by Duy Nguyen
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.

Signed-off-by: Ralf Thielow <[hidden email]>
---

changes in v5:
- extract a function to write refspec config
- handle --mirror option (test added)
- install correct refspec if the value of --branch is a tag (test added)
Thanks to Junio for:
- refactor tests
- add tests for created refs

I'm not happy about using "our_head_points_to" for the remote
part of the refspec. Junio already complaint about that. As far
as I can see it's the only way of getting the information that
it's a tag. Also the condition "is this a tag" might not be the
best way.

 builtin/clone.c          |  66 +++++++++++++++-----
 t/t5709-clone-refspec.sh | 156 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 208 insertions(+), 14 deletions(-)
 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_config_set(key.buf, repo);
  strbuf_reset(&key);
@@ -853,6 +888,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
       "refs/heads/master");
  }
 
+ write_refspec_config(src_ref_prefix, our_head_points_at,
+ remote_head_points_at, &branch_top);
+
  if (is_local)
  clone_local(path, git_dir);
  else if (refs && complete_refs_before_fetch)
diff --git a/t/t5709-clone-refspec.sh b/t/t5709-clone-refspec.sh
new file mode 100755
index 0000000..af45182
--- /dev/null
+++ b/t/t5709-clone-refspec.sh
@@ -0,0 +1,156 @@
+#!/bin/sh
+
+test_description='test refspec written by clone-command'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ # Make two branches, "master" and "side"
+ echo one >file &&
+ git add file &&
+ git commit -m one &&
+ echo two >file &&
+ git commit -a -m two &&
+ git tag two &&
+ echo three >file &&
+ git commit -a -m three &&
+ git checkout -b side &&
+ echo four >file &&
+ git commit -a -m four &&
+ git checkout master &&
+
+ # default clone
+ git clone . dir_all &&
+
+ # default --single that follows HEAD=master
+ git clone --single-branch . dir_master &&
+
+ # default --single that follows HEAD=side
+ git checkout side &&
+ git clone --single-branch . dir_side &&
+
+ # explicit --single that follows side
+ git checkout master &&
+ git clone --single-branch --branch side . dir_side2 &&
+
+ # default --single with --mirror
+ git clone --single-branch --mirror . dir_mirror &&
+
+ # --single that does not know what branch to follow
+ git checkout two^ &&
+ git clone --single-branch . dir_detached &&
+
+ # 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
+'
+
+test_expect_success 'refspec contains all branches by default' '
+ echo "+refs/heads/*:refs/remotes/origin/*" > expect &&
+ git --git-dir=dir_all/.git config --get remote.origin.fetch > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'refspec contains all refs with option --mirror' '
+ echo "+refs/*:refs/*" > expect &&
+ git --git-dir=dir_mirror config --get remote.origin.fetch > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'refspec contains tag ref' '
+ echo "+refs/tags/two:refs/tags/two" > expect &&
+ git --git-dir=dir_tag/.git config --get remote.origin.fetch > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'refspec contains only master with option --single-branch and remotes HEAD point to master' '
+ echo "+refs/heads/master:refs/remotes/origin/master" > expect &&
+ git --git-dir=dir_master/.git config --get remote.origin.fetch > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'refspec contains only foo with option --single-branch and remotes HEAD point to side' '
+ echo "+refs/heads/side:refs/remotes/origin/side" > expect &&
+ git --git-dir=dir_side/.git config --get remote.origin.fetch > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'refspec contains one branch after using option --single-branch with --branch' '
+ echo "+refs/heads/side:refs/remotes/origin/side" > expect &&
+ git --git-dir=dir_side2/.git config --get remote.origin.fetch > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'no refspec is written if remotes HEAD is detached' '
+ > expect &&
+ git --git-dir=dir_detached/.git config --get remote.origin.fetch > actual
+ test_cmp expect actual
+'
+
+test_expect_success 'by default all branches will be kept updated' '
+ (
+ cd dir_all && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+    -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # follow both master and side
+ git for-each-ref refs/heads >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch while HEAD pointing at master' '
+ (
+ cd dir_master && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+    -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # only follow master
+ git for-each-ref refs/heads/master >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch while HEAD pointing at side' '
+ (
+ cd dir_side && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+    -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # only follow side
+ git for-each-ref refs/heads/side >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with explicit --branch side' '
+ (
+ cd dir_side2 && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+    -e "s|/remotes/origin/|/heads/|" >../actual
+ ) &&
+ # only follow side
+ git for-each-ref refs/heads/side >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--single-branch with detached' '
+ (
+ cd dir_detached && git fetch &&
+ git for-each-ref refs/remotes/origin |
+ sed -e "/HEAD$/d" \
+    -e "s|/remotes/origin/|/heads/|" >../actual
+ )
+ # nothing
+ >expect &&
+ test_cmp expect actual
+'
+
+test_done
--
1.7.12.397.ge29f79e.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
12
Loading...