Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shallow clones don't seem to work for local clones #6634

Open
ehuss opened this issue Sep 12, 2023 · 3 comments
Open

Shallow clones don't seem to work for local clones #6634

ehuss opened this issue Sep 12, 2023 · 3 comments

Comments

@ehuss
Copy link
Contributor

ehuss commented Sep 12, 2023

From what I can tell, shallow clones don't seem to work with local clones. Am I missing some option? I'm guessing they only work with the smart transport. I would expect it to work like the git CLI, which can support shallow clones when using file:// URLs.

git clone --depth=1 file:///path/to/test

Reproduction steps

#include <assert.h>
#include <git2/repository.h>
#include <git2/errors.h>
#include <git2/global.h>
#include <git2/signature.h>
#include <git2/index.h>
#include <git2/commit.h>
#include <git2/clone.h>
#include <git2/diff.h>
#include <stdio.h>
#include <unistd.h>

int main() {
  assert(git_libgit2_init() == 1);

  git_repository *repo;
  assert(git_repository_init(&repo, "repo", 0) == 0);

  FILE *fp;
  fp = fopen("repo/file", "w");
  fputs("this is a test\n", fp);
  fclose(fp);

  git_index *index;
  assert(git_repository_index(&index, repo) == 0);
  assert(git_index_add_bypath(index, "file") == 0);
  assert(git_index_write(index) == 0);

  git_oid tree_id;
  git_tree *tree;
  assert(git_index_write_tree(&tree_id, index) == 0);
  assert(git_tree_lookup(&tree, repo, &tree_id) == 0);
  git_signature *sig;
  assert(git_signature_default(&sig, repo) == 0);
  git_oid first_commit_id;
  assert(git_commit_create_v(&first_commit_id, repo, "HEAD", sig, sig, NULL, "first", tree, 0) == 0);

  truncate("repo/file", 0);
  assert(git_repository_index(&index, repo) == 0);
  assert(git_index_add_bypath(index, "file") == 0);
  assert(git_index_write(index) == 0);
  assert(git_tree_lookup(&tree, repo, &tree_id) == 0);
  git_oid second_commit_id;
  assert(git_commit_create_v(&second_commit_id, repo, "HEAD", sig, sig, NULL, "second", tree, 1, first_commit_id) == 0);

  git_repository *repo2;
  git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
  clone_opts.fetch_opts.depth = 1;
  // It doesn't seem to matter how `local` is set.
  clone_opts.local = GIT_CLONE_LOCAL_NO_LINKS;
  assert(git_clone(&repo2, "repo", "repo2", &clone_opts) == 0);

  assert(git_repository_is_shallow(repo2) == 1);

  return 0;
}

Expected behavior

Local repos can be shallow cloned.

Actual behavior

It seems to ignore the depth parameter.

Version of libgit2 (release number or SHA1)

4939fa7

Operating system(s) tested

macOS

@ethomson
Copy link
Member

Yes, there's a lot of disappointment all around in local remotes. git will either invoke git-upload-pack and git-receive-pack or do some hardlinking magic, depending on how you specify the local path. (file:///tmp/foo behaves differently than /tmp/foo).

We do neither of those things. We open up the remote as our own object database and sling files over. I think that this is in many ways a very clever solution, but as capabilities are added to the smart protocol, it would mean that they would need to be independently implemented in the local transport, which is a bummer.

I've coincidentally been playing around with refactoring the smart protocol handling a bit - and the local transport has been my test case for it - invoking git-upload-pack and using the smart protocol. That would get us parity between https/ssh and local. I can try to get it into a state where I can push it up this weekend.

@ethomson
Copy link
Member

In the meantime, should the depth parameter error on local transports? That seems more polite than ignoring it.

@ethomson
Copy link
Member

We now error on depth with local transports (with #6757). Actually making this work is something that I've started on, but is a (much) bigger dig.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants