You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm currently in a situation where I expected magit-branch-spinoff to be exactly what I needed but it didn't do what I thought. I'm going to describe what I wish Magit did, framed as an enhancement to magit-branch-spinoff, but I'm not 100% confident that I understood the use of magit-branch-spinoff so if I misunderstood that command, please consider this as a feature request for some other branch command that does something similar.
Proposal
It would be great if magit-branch-spinoff would not just look at the tracked branch, but also check if there is a pushRemote for the current branch, and consider that as well.
Current behavior
The situation is something like this. I am working in a repo called my-cool-project. I was working in this repository a week ago and at that time I was working on a branch called feature-1. I had pushed that branch to origin/feature-1 and opened a pull request. (That pull request has not been active since then but I don't think that is important.) When I started work today, I created a few more commits before realizing that actually I wanted these commits to be on another feature branch, feature-2, based off of main, rather than on feature-1.
Schematically, I have something like:
[main] -> o -> o -> [origin/feature-1] -> o -> o -> o -> [feature-1, HEAD]
I'd like to create a new branch feature-2 where HEAD is and move feature-1 back to origin/feature-1:
[main] -> o -> o -> [origin/feature-1, feature-1] -> o -> o -> o -> [feature-2, HEAD].
Once I have that, I can eventually move the feature-2 commits over to main using a simple rebase. (If there's a command that would do that for me too, that would be great!)
I thought I could use magit-branch-spinoff to accomplish this. However, when I hit b s I got:
[main] -> o -> o -> [origin/feature-1] -> o -> o -> o -> [feature-1, feature-2, HEAD]
In other words, feature-1 didn't move at all. Essentially this command was the same as doing b c.
Further details
Looking at the code for magit--branch-spinoff, it seems that the way to determine where to move the current branch is by getting the tracked branch using magit-get-upstream-branch and then using git merge-base to find the common ancestor. This is consistent with the text in the Magit manual for the magit-branch-spinoff command: "That branch in turn is reset to the last commit it shares with its upstream." In my situation, (magit-get-upstream-branch "feature-1") returns nil. If I look at the branch using b C, it shows merge unset, remote unset, and pushRemote is origin. I guess that since merge is null, this branch doesn't really have an "upstream", but it definitely does have some unpushed commits, which Magit is smart enough to know about (I guess by comparing against the pushRemote version of the same ref).
Alternatives
Perhaps this shouldn't be part of magit-branch-spinoff. Given the text in the manual, perhaps it is essential to the nature of magit-branch-spinoff that it operate only against true upstreams (described in the manual as "the branch into which the commits on that local branch should eventually be merged"), then perhaps another branch command would be better (magit-branch-spinoff-feature?). In my mind, the term "spinoff" doesn't have any special attachment to upstream, so I feel like "spinoff" is the right place for this functionality, but I'm happy to be corrected :)
Another general command to move a branch while not losing the current commit. I could be wrong but I think spinoff is the only command that helpfully combines both of these operations. However, I feel that it's relatively common for me to realize that I've done something on a branch that should go somewhere else, and want to "undo" the changes to the branch, but can't directly do that (i.e. using reset) without losing the work that I've done in the wrong place. We could probably envision a variety of ways of providing functionality in this direction: "detach and reset branch"; "reset other branch"; "create branch and reset other branch"; "replay work as new branch".
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I'm currently in a situation where I expected
magit-branch-spinoff
to be exactly what I needed but it didn't do what I thought. I'm going to describe what I wish Magit did, framed as an enhancement tomagit-branch-spinoff
, but I'm not 100% confident that I understood the use ofmagit-branch-spinoff
so if I misunderstood that command, please consider this as a feature request for some other branch command that does something similar.Proposal
It would be great if
magit-branch-spinoff
would not just look at the tracked branch, but also check if there is apushRemote
for the current branch, and consider that as well.Current behavior
The situation is something like this. I am working in a repo called
my-cool-project
. I was working in this repository a week ago and at that time I was working on a branch calledfeature-1
. I had pushed that branch toorigin/feature-1
and opened a pull request. (That pull request has not been active since then but I don't think that is important.) When I started work today, I created a few more commits before realizing that actually I wanted these commits to be on another feature branch,feature-2
, based off of main, rather than onfeature-1
.Schematically, I have something like:
[main] -> o -> o -> [origin/feature-1] -> o -> o -> o -> [feature-1, HEAD]
I'd like to create a new branch
feature-2
whereHEAD
is and movefeature-1
back toorigin/feature-1
:[main] -> o -> o -> [origin/feature-1, feature-1] -> o -> o -> o -> [feature-2, HEAD]
.Once I have that, I can eventually move the
feature-2
commits over tomain
using a simple rebase. (If there's a command that would do that for me too, that would be great!)I thought I could use
magit-branch-spinoff
to accomplish this. However, when I hitb s
I got:[main] -> o -> o -> [origin/feature-1] -> o -> o -> o -> [feature-1, feature-2, HEAD]
In other words,
feature-1
didn't move at all. Essentially this command was the same as doingb c
.Further details
Looking at the code for
magit--branch-spinoff
, it seems that the way to determine where to move the current branch is by getting thetracked
branch usingmagit-get-upstream-branch
and then usinggit merge-base
to find the common ancestor. This is consistent with the text in the Magit manual for themagit-branch-spinoff
command: "That branch in turn is reset to the last commit it shares with its upstream." In my situation,(magit-get-upstream-branch "feature-1")
returnsnil
. If I look at the branch usingb C
, it showsmerge
unset,remote
unset, andpushRemote
isorigin
. I guess that sincemerge
is null, this branch doesn't really have an "upstream", but it definitely does have some unpushed commits, which Magit is smart enough to know about (I guess by comparing against thepushRemote
version of the same ref).Alternatives
Perhaps this shouldn't be part of
magit-branch-spinoff
. Given the text in the manual, perhaps it is essential to the nature ofmagit-branch-spinoff
that it operate only against true upstreams (described in the manual as "the branch into which the commits on that local branch should eventually be merged"), then perhaps another branch command would be better (magit-branch-spinoff-feature
?). In my mind, the term "spinoff" doesn't have any special attachment to upstream, so I feel like "spinoff" is the right place for this functionality, but I'm happy to be corrected :)Another general command to move a branch while not losing the current commit. I could be wrong but I think
spinoff
is the only command that helpfully combines both of these operations. However, I feel that it's relatively common for me to realize that I've done something on a branch that should go somewhere else, and want to "undo" the changes to the branch, but can't directly do that (i.e. using reset) without losing the work that I've done in the wrong place. We could probably envision a variety of ways of providing functionality in this direction: "detach and reset branch"; "reset other branch"; "create branch and reset other branch"; "replay work as new branch".Beta Was this translation helpful? Give feedback.
All reactions