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

Worktrees can be made from bare repositories #4630

Merged
merged 2 commits into from
May 7, 2018

Conversation

tiennou
Copy link
Contributor

@tiennou tiennou commented Apr 18, 2018

Supersedes #4628, fixes #4626.

It fixes the issue by globally disabling the check in ensure_not_bare when working against a "worktree repo". I haven't given any thought to what this actually can provoke.

My gut feeling says it's not clean enough, as I don't like :

  • all those remaining repo->is_bare tests which might now not work against a "worktree repo".
  • you can have bare repo (git_repository_is_bare = true) with a workdir, since the bare-ness of the parent repo percolates down to the worktree repoes.

Maybe renaming ensure_not_bare to ensure_has_workdir and using that everywhere ? I'm unsure about the 2nd point though. Opinions, as always, welcome.

repo = cl_git_sandbox_init("testrepo.git");

cl_assert_equal_i(1, git_repository_is_bare(repo));
cl_assert_equal_i(0, git_repository_is_worktree(repo));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am aware of that. Right now I feel that we have bigger concerns than testing a single bool OR-ing function vs. all its others users that can now work against those bare-worktrees. Especially since the semantics are unclear.

cl_git_pass(git_repository_open(&wtrepo, path.ptr));
cl_assert_equal_i(1, git_repository_is_bare(wtrepo));
cl_assert_equal_i(1, git_repository_is_worktree(wtrepo));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git_repository__ensure_not_bare should be tested again on repo to make sure that adding a worktree to a bare repository does not change the return value on the bare repository.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that because of the semantic change in git_repository_is_bare, git_repository__ensure_not_bare now has the same semantics by default. So apart from the special error handling, it's equivalent (and I think it's better to test the public low-level API part vs. a slightly higher-up private one).

@ethomson
Copy link
Member

you can have bare repo (git_repository_is_bare = true) with a workdir, since the bare-ness of the parent repo percolates down to the worktree repoes.

To clarify: you're saying that if I have a bare parent repository, the subsequent worktree repository also identifies itself as bare? I don't think that's what I would have expected... if you add a working directory to a bare repository, it reports itself (correctly) as non-bare. I would expect worktree repositories created from a bare parent to do the same.

@tiennou
Copy link
Contributor Author

tiennou commented Apr 19, 2018

The unexpectedness is shared then. Note that cd $worktree; git config --get core.bare returns "true", so git seems to consider the repository still bare. I expect our config code to do the same, but that is_bare function clearly does not.

I found one broken thing in git, adding a relative submodule to the worktree of a bare repository always "can't find directory $relative_path".

repo = cl_git_sandbox_init("testrepo.git");

cl_assert_equal_i(1, git_repository_is_bare(repo));
cl_assert_equal_i(0, git_repository_is_worktree(repo));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am aware of that. Right now I feel that we have bigger concerns than testing a single bool OR-ing function vs. all its others users that can now work against those bare-worktrees. Especially since the semantics are unclear.

@ethomson
Copy link
Member

The unexpectedness is shared then. Note that cd $worktree; git config --get core.bare returns "true", so git seems to consider the repository still bare. I expect our config code to do the same, but that is_bare function clearly does not.

git config --get core.bare is really only showing you the configuration option, which remains unchanged. If you query the repository configuration through libgit2, we should also report core.bare = true even when you've configured a working folder.

I think that git_repository_is_bare should report the conceptual / perceived bareness of a repository, not just be a direct proxy to the configuration. I don't think there's a parallel in git.git for this concept.

src/worktree.c Outdated
@@ -139,7 +139,7 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char
if ((wt->name = git__strdup(name)) == NULL
|| (wt->commondir_path = git_worktree__read_link(dir, "commondir")) == NULL
|| (wt->gitlink_path = git_worktree__read_link(dir, "gitdir")) == NULL
|| (wt->parent_path = git__strdup(parent)) == NULL) {
|| (parent && (wt->parent_path = git__strdup(parent)) == NULL)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also seems to fix #4625

@tiennou tiennou force-pushed the fix/worktree-from-bare branch 2 times, most recently from c1ae122 to f08f74d Compare April 20, 2018 08:39
@tiennou
Copy link
Contributor Author

tiennou commented Apr 20, 2018

Updated. A repo created from a worktree will not be reported as bare anymore, and the override is done in load_config_data to repo->bare directly, so all call-sites will see it. I'm still trying to pinpoint what I'm breaking by allowing those worktrees to not have a parent, so it's still WIP.

Copy link
Member

@pks-t pks-t left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR. This was an obvious oversight by myself, a working tree shouldn't be considered as bare. It might be that the Windows failures stem from your use of joinpath with relative directories and Unix path separators, even though I think it unlikely. I can't dive into that right now, but could do so later.

if (git_config_get_bool(&is_bare, config, "core.bare") < 0)
repo->is_bare = 0;
if (err != GIT_ENOTFOUND)
repo->is_bare = is_bare && !repo->is_worktree;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This definitely makes sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Note to myself) the commit message should be We were previously conflating any error into GIT_ENOTFOUND, which might or might not be correct. This fixes the code so a config error is bubbled up, as well as preserving the semantics in the face of worktree-repositories.

cl_git_pass(git_repository_open(&wtrepo, path.ptr));
cl_assert_equal_i(1, git_repository_is_bare(wtrepo));
cl_assert_equal_i(1, git_repository_is_worktree(wtrepo));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed

cl_assert_equal_i(1, git_repository_is_bare(repo));
cl_assert_equal_i(0, git_repository_is_worktree(repo));

cl_git_pass(git_buf_joinpath(&path, repo->gitdir, "../worktree-frombare"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to just use "./worktree-frombare" instead of assembling the path, as we always chdir into the test data directory.

git_repository *repo, *wtrepo;
git_buf path = GIT_BUF_INIT;

repo = cl_git_sandbox_init("testrepo.git");
Copy link
Contributor

@csware csware Apr 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use another bare repository here (e.g., short_tag.git). This fixes the test issue on win32. I suppose the reason is that testrepo is already set up by setup_fixture_worktree.

We were previously conflating any error into GIT_ENOTFOUND, which might
or might not be correct. This fixes the code so a config error is
bubbled up, as well as preserving the semantics in the face of
worktree-repositories
@pks-t
Copy link
Member

pks-t commented May 7, 2018

I've rebased this branch and just wanted to push it when I ran the tests for a second time, but this time they failed. The problem is that you're actually adding the worktree-frombare repo outside of our sandbox -- the path of git_worktree_add is relative to cwd, not relative to the repository we're creating the worktree from.

I've fixed the test issue and conflict and pushed both to your branch.

@pks-t pks-t merged commit 81ea995 into libgit2:master May 7, 2018
@pks-t
Copy link
Member

pks-t commented May 7, 2018

Thanks @tiennou!

@tiennou
Copy link
Contributor Author

tiennou commented Aug 10, 2018

I've just hit that case locally, and was mightily confused 😉. So I looked this PR up and got even more confused by the backport-0.27.2 addition 👆(with the deletion only registering after I banged my
head around longer). Was that the de-backporting intentional ? It's just that OCGit is currently tracking 0.27 and this one's now MIA 😕.

@pks-t
Copy link
Member

pks-t commented Aug 16, 2018

I honestly can't remember anymore. I'd be happy to include it in another bugfix release, though, so I'm tagging it for backport

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

Successfully merging this pull request may close these issues.

Adding files to worktree of bare repository fails
4 participants