-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
worktree: add ability to create worktree with pre-existing branch #4524
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -348,13 +348,30 @@ int git_worktree_add(git_worktree **out, git_repository *repo, | |
|| (err = write_wtfile(gitdir.ptr, "gitdir", &buf)) < 0) | ||
goto out; | ||
|
||
/* Create new branch */ | ||
if ((err = git_repository_head(&head, repo)) < 0) | ||
goto out; | ||
if ((err = git_commit_lookup(&commit, repo, &head->target.oid)) < 0) | ||
goto out; | ||
if ((err = git_branch_create(&ref, repo, name, commit, false)) < 0) | ||
goto out; | ||
/* Set up worktree reference */ | ||
if (wtopts.ref) { | ||
if (!git_reference_is_branch(wtopts.ref)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My first comments on libgit2 code, apologies if I've misunderstood anything. :) git worktree add allows using an existing branch name or commit, this code only supports branches? Should it add commit support now rather than adding that later? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Even if you misunderstand anything that is a worthwhile comment, as it hints at things that are hard to understand and could be improved. So don't worry about that ;) That being said, I didn't really want to allow using committish things here. The main problem is actually the interface. In case we allow either a hash or a reference, I'd have to make sure what it is the user passed to me by parsing it. Same for branches vs tags -- in case the user passed a tag to me, I need to make sure to not let HEAD point at the tag, but instead create a detached HEAD. So, if you ask me, it creates quite some complexity for rather minor usecases. At least I think these usecases are minor as long as I'm not convinced otherwise by a convincing scenario. Alternatively, I'd also be happy to implement that if somebody has an idea how the interface could look like such that it is trivial to implement and easy to use. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be honest I have never actually used a commit or tag. My personal usecase for worktrees is always checking out branches locally for PRs without disturbing my working copy. So this change helps me. But I wonder how quickly requests would follow for tags/commits, perhaps it is enough to get there in incremental steps. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I definitly see where you're coming from. I mean I would already include the ability to use arbitrary commits, but I'm simply undecided on how that interface should look like. So a long as nobody has any proposals I think I'll just stay with the current one for now and wait until people start complaining. |
||
giterr_set(GITERR_WORKTREE, "reference is not a branch"); | ||
err = -1; | ||
goto out; | ||
} | ||
|
||
if (git_branch_is_checked_out(wtopts.ref)) { | ||
giterr_set(GITERR_WORKTREE, "reference is already checked out"); | ||
err = -1; | ||
goto out; | ||
} | ||
|
||
if ((err = git_reference_dup(&ref, wtopts.ref)) < 0) | ||
goto out; | ||
} else { | ||
if ((err = git_repository_head(&head, repo)) < 0) | ||
goto out; | ||
if ((err = git_commit_lookup(&commit, repo, &head->target.oid)) < 0) | ||
goto out; | ||
if ((err = git_branch_create(&ref, repo, name, commit, false)) < 0) | ||
goto out; | ||
} | ||
|
||
/* Set worktree's HEAD */ | ||
if ((err = git_repository_create_head(gitdir.ptr, git_reference_name(ref))) < 0) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When/how does the version get bumped?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The option versions shall get bumped whenever the structure changes, but this will only happen as soon as we have our first stable (1.0) release.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a general question about changing this struct/the version and breaking changes, really for my own education.
In libgit2sharp the shape of the _options structs is effectively fixed, e.g. for git_blame_options
see https://github.com/libgit2/libgit2sharp/blob/3f9b415fa1edfc31ce1ec2b4b3d18441c34adfff/LibGit2Sharp/Core/GitBlame.cs#L44
vs in libgit2
libgit2/include/git2/blame.h
Line 70 in 89c332e
So the libgit2sharp code would need reworking if a new field was added to the struct in libgit2.
So my question is why is it ok to refactor the worktree options struct, without bumping the version, in libgit2 but not to add params to a method definition?
Why does adding a param to the method break the API but adding a field to the struct not break it?
Hope that makes sense. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're very much right in that both are breaking API changes. The way that we extend things now is (generally) through the options interface instead of params. In the future it will always be through the options interface plus incrementing the version number.
We haven't been very responsible here about stabilizing. We should do that soon.