Patchwork [bitbake-devel] fetch2/git: Add workaround for clone using alternates problem

login
register
mail settings
Submitter Richard Purdie
Date Jan. 31, 2012, 2:18 p.m.
Message ID <1328019536.13744.28.camel@ted>
Download mbox | patch
Permalink /patch/20429/
State Accepted
Commit d978e7b35550e3785c7c567ffe4c40a3c3947450
Headers show

Comments

Richard Purdie - Jan. 31, 2012, 2:18 p.m.
To quote my report of this to the git mailing list:
"""
    
    I have a problem with git clone commands using alternates failing by
    mixing up different repositories. I have a situation where I could end
    up with both:
    
    /srv/mirrors/repo
    /srv/mirrors/repo.git
    
    as bare clones.
    
    I then try cloning "repo" with alternates with the command:
    
    $ git clone -s -n /srv/mirrors/repo /tmp/foo
    Cloning into /tmp/foo...
    done.
    
    $ cat /tmp/foo/.git/objects/info/alternates
    /srv/mirrors/repo.git/objects
    
    Note how I'm now referencing repo.git, not repo. This doesn't work as
    expected giving some very bizarre results when actually using the
    repository.
    
    I appreciate this is a rather bizarre corner case but its one that is
    breaking the build system I work with. Ideally people would use a
    consistent URL for the same repository but we have an example where they
    haven't and this really shouldn't break like this.
    
    Looking at the code, the cause seems to be
    
    clone.c:get_repo_path():
            static char *suffix[] = { "/.git", ".git", "" };
    
    since its looking in order for:
     repo/.git (fails)
     repo.git (suceeds, incorrect)
     repo (never looked at)
    
    I'm not sure what would break if that order were to change, swapping the
    last two options.
    
    I can "force" the issue by running:
    
    git clone -s -n /srv/mirrors/repo/ /tmp/foo
    
    but this results in the slightly odd looking:
    
    $ cat /tmp/foo/.git/objects/info/alternates
    
    /srv/mirrors/repo//objects
    
    which does at least work.
"""
    
This patch adds the trailing slash to ensure the correct repository is
referenced at the expense of some ugliness in the alternates file.
    
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Bruce Ashfield - Jan. 31, 2012, 2:29 p.m.
On 12-01-31 09:18 AM, Richard Purdie wrote:
> To quote my report of this to the git mailing list:
> """
>
>      I have a problem with git clone commands using alternates failing by
>      mixing up different repositories. I have a situation where I could end
>      up with both:
>
>      /srv/mirrors/repo
>      /srv/mirrors/repo.git
>
>      as bare clones.
>
>      I then try cloning "repo" with alternates with the command:
>
>      $ git clone -s -n /srv/mirrors/repo /tmp/foo
>      Cloning into /tmp/foo...
>      done.
>
>      $ cat /tmp/foo/.git/objects/info/alternates
>      /srv/mirrors/repo.git/objects
>
>      Note how I'm now referencing repo.git, not repo. This doesn't work as
>      expected giving some very bizarre results when actually using the
>      repository.
>
>      I appreciate this is a rather bizarre corner case but its one that is
>      breaking the build system I work with. Ideally people would use a
>      consistent URL for the same repository but we have an example where they
>      haven't and this really shouldn't break like this.
>
>      Looking at the code, the cause seems to be
>
>      clone.c:get_repo_path():
>              static char *suffix[] = { "/.git", ".git", "" };
>
>      since its looking in order for:
>       repo/.git (fails)
>       repo.git (suceeds, incorrect)
>       repo (never looked at)
>
>      I'm not sure what would break if that order were to change, swapping the
>      last two options.
>
>      I can "force" the issue by running:
>
>      git clone -s -n /srv/mirrors/repo/ /tmp/foo
>
>      but this results in the slightly odd looking:
>
>      $ cat /tmp/foo/.git/objects/info/alternates
>
>      /srv/mirrors/repo//objects
>
>      which does at least work.
> """
>
> This patch adds the trailing slash to ensure the correct repository is
> referenced at the expense of some ugliness in the alternates file.

For what it's worth, I've run into very similar issues in the past, and
the solution was the same .. Ensure that the trailing / was present, it
is meaningful to git in a few cases (in mine it was relative references
to alternate repositories).

In the relative reference case, we eventually did propose and got a variant
of our change to support it incorporated into git. But the work around
was still needed for a while, since waiting for it to propagate to
supported hosts and versions of git was a bit messy.

I couldn't find a good explanation of the ordering either, but I do know
that there are existing scripts and infrastructure that do depend on
having <foo>.git found before <foo>, so changing any ordering could
have some subtle impacts.

The summary of my rambling is that I couldn't come up with anything
better in my poking around before I've had much coffee today :)

Cheers,

Bruce



>
> Signed-off-by: Richard Purdie<richard.purdie@linuxfoundation.org>
>
> diff --git a/lib/bb/fetch2/git.py b/lib/bb/fetch2/git.py
> index d833714..fb0260a 100644
> --- a/lib/bb/fetch2/git.py
> +++ b/lib/bb/fetch2/git.py
> @@ -220,7 +220,7 @@ class Git(FetchMethod):
>           if os.path.exists(destdir):
>               bb.utils.prunedir(destdir)
>
> -        runfetchcmd("git clone -s -n %s %s" % (ud.clonedir, destdir), d)
> +        runfetchcmd("git clone -s -n %s/ %s" % (ud.clonedir, destdir), d)
>           if not ud.nocheckout:
>               os.chdir(destdir)
>               if subdir != "":
>

Patch

diff --git a/lib/bb/fetch2/git.py b/lib/bb/fetch2/git.py
index d833714..fb0260a 100644
--- a/lib/bb/fetch2/git.py
+++ b/lib/bb/fetch2/git.py
@@ -220,7 +220,7 @@  class Git(FetchMethod):
         if os.path.exists(destdir):
             bb.utils.prunedir(destdir)
 
-        runfetchcmd("git clone -s -n %s %s" % (ud.clonedir, destdir), d)
+        runfetchcmd("git clone -s -n %s/ %s" % (ud.clonedir, destdir), d)
         if not ud.nocheckout:
             os.chdir(destdir)
             if subdir != "":