Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

worktree: mimic 'git worktree add' behavior.#5319

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
ethomson merged 2 commits intolibgit2:mainfromherrerog:worktree
Mar 5, 2024

Conversation

herrerog
Copy link
Contributor

When adding a worktree usinggit worktree add <path>, if a reference
namedrefs/heads/$(basename <path>) already exist, it is checkouted in
the worktree.
Mimic this behavior in libgit2.

Copy link
Contributor

@tiennoutiennou left a comment

Choose a reason for hiding this comment

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

Hmm, isn't this supposed to be passed asgit_worktree_add_options'sref field ? As far as I can see this changes the behavior, as the old code would havenever reused a reference, instead returning an error. Now you cannever now if this actually happened, and you can end-up reusing by accident another unrelated reference.

if ((err = git_commit_lookup(&commit, repo, &head->target.oid)) < 0)
goto out;
if ((err = git_branch_create(&ref, repo, name, commit, false)) < 0)
git_buf ref_buf = GIT_BUF_INIT;
Copy link
Contributor

Choose a reason for hiding this comment

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

This must begit_buf_disposed of — CI reports a leak.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I fixed that, thanks.

@herrerog
Copy link
ContributorAuthor

Hmm, isn't this supposed to be passed asgit_worktree_add_options'sref field ? As far as I can see this changes the behavior, as the old code would havenever reused a reference, instead returning an error. Now you cannever now if this actually happened, and you can end-up reusing by accident another unrelated reference.

ref field looks a bit different to me, it's when you want to checkoutref in the worktree.
libgit2 will checkout thisref only if it already exists and is not already checked out.

When user doesn't passref field, current version ofgit_worktree_add creates a new branch with thename of the worktree in the main working tree and checkout HEAD in the new worktree.

The only thing this commit is changing is whenref field is not passed as an option and branchrefs/heads/<name> already exists in the main working tree.
It would have error out previously. But with this commit, it will now checkout the commit pointed byrefs/heads/<name> in the new worktree without any error.

It's the same behavior when you do the following:
git worktree add ../libgit2-wt
Git create the new worktree in ../libgit2-wt and create a branchlibgit2-wt in the main repositoriy.
rm -Rf ../libgit2-wt
git worktree prune
Here we deleted thelibgit2-wt and pruned it but Git kept thelibgit2-wt branch in the main repository.

git worktree add ../libgit2-wt
Adding the worktree again works whereaslibgit2-wt already exists.

This currently doesn't work with libgit2 and that's what I'm trying to fix.

Please let me know if I'm missing something.
Thanks for the review.

@herrerog
Copy link
ContributorAuthor

I have added a testtest_worktree_worktree__add_remove_add which add a worktree, delete it and add it back. This may help understanding what I'm trying to achieve.

goto out;
if ((err = git_branch_create(&ref, repo, name, commit, false)) < 0)
goto out;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Hm. I feel like you've got a point with thegit_branch_is_checked_out call, we're not doing that e.g. ifwtopts.ref is set. Let me propose the following flow:

if (wtopts.ref) {    git_reference_dup(&ref, wtopts.ref);} else if (git_branch_lookup(&ref, name) == 0) {    /* Use the ref */} else {    git_branche_create(&ref);}if (git_branch_is_checked_out(ref)) {    error out;}

I think we ought to give the user a option to turn off re-use of branches, though. So maybe we should add a flag togit_worktree_add_options?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I think we are already checking ifwopts.refs is checkouted at the beginning of thegit_worktree_add function with below code:

if (wtopts.ref) {if (!git_reference_is_branch(wtopts.ref)) {git_error_set(GIT_ERROR_WORKTREE, "reference is not a branch");err = -1;goto out;}if (git_branch_is_checked_out(wtopts.ref)) {git_error_set(GIT_ERROR_WORKTREE, "reference is already checked out");err = -1;goto out;}}

So that should be fine.
Should we add aforce option as ingit worktree command ?

Copy link
Member

Choose a reason for hiding this comment

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

Ah, fair enough. Didn't read into the code and only saw this single instance ofif (wtopts.ref) in the diff. I'd prefer to have that check whether it's checked out in a single location as proposed by me to make it easier to extend, bu that's definitely not something you'll have to fix.

I'd like to not call thisforce, as this is a frequently overloaded name and doesn't really tell what's being forced. Something like "allow_reusing_refs" or "allow_existing_branch" would be better? I'm open for better proposals though!

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

After thinking a bit more about it, theforce flag would make sense only if the branch passed aswtopts.ref or inferred fromname of the worktree is already checked out.
This pull request currently aborts if the branch is already checked out.
If the branch is not checked out, it will simply reuse it. So I guess that's fine from an user point of view.
Let me know what you think.

Copy link
Member

Choose a reason for hiding this comment

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

This pull request currently aborts if the branch is already checked out.

Let's keep it this way for now. Can still add it later if requested.

pks-t
pks-t previously approved these changesJan 24, 2020
Copy link
Member

@pks-tpks-t left a comment

Choose a reason for hiding this comment

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

Sorry for taking so long to review this and thanks for your changes!

goto out;
if ((err = git_branch_create(&ref, repo, name, commit, false)) < 0)
goto out;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

This pull request currently aborts if the branch is already checked out.

Let's keep it this way for now. Can still add it later if requested.

@pks-t
Copy link
Member

Rebased branch to re-trigger CI.

@pks-t
Copy link
Member

I've added another commit that hides this new feature behind an option to address@tiennou's remark.

@herrerog
Copy link
ContributorAuthor

I've added another commit that hides this new feature behind an option to address@tiennou's remark.

Thanks, this looks good to me.

@pks-t
Copy link
Member

/rebuild

@libgit2-azure-pipelines

Sorry@pks-t, an error occurred while trying to requeue the build.

herrerogand others added2 commitsJanuary 31, 2020 15:25
When adding a worktree using 'git worktree add <path>', if a referencenamed 'refs/heads/$(basename <path>)' already exist, it is checkouted inthe worktree.Mimic this behavior in libgit2.Signed-off-by: Gregory Herrero <gregory.herrero@oracle.com>
In this commit's parent, we have introduced logic that willautomatically re-use of existing branches if the new worktree namematches the branch name. While this is a handy feature, it changesbehaviour in a backwards-incompatible way and might thus surprise users.Furthermore, it's impossible to tell whether we have created theworktree with a new or an existing reference.To fix this, introduce a new option `checkout_existing` that togglesthis behaviour. Only if the flag is set will we now allow re-use ofexisting branches, while it's set to "off" by default.
Base automatically changed frommaster tomainJanuary 7, 2021 10:09
@ethomsonethomson merged commitea5028a intolibgit2:mainMar 5, 2024
@ethomson
Copy link
Member

I manually merged this and fixed up the conflicts. Thanks!

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@tiennoutiennoutiennou left review comments

@pks-tpks-tpks-t left review comments

Assignees
No one assigned
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

4 participants
@herrerog@pks-t@ethomson@tiennou

[8]ページ先頭

©2009-2025 Movatter.jp