如何将提交从主干移动到 Git 中的分支?

发布于 2024-08-23 22:21:53 字数 582 浏览 16 评论 0原文

我向 master 做了一堆提交,并在事后意识到它们应该在一个分支中。

我研究了有关变基、合并和重置母版的各种内容。但任何操纵的尝试都没有产生看起来像我想要做的那样的历史。

我的尝试让我相信需要结合使用rebase --ontoreset --hard 才能将master 及时移回过去。但我对 Git 分支的理解还有一些不足之处。这样做的一部分是学习如何使用它。

应该指出的是,我试图进行的任何更改都没有被推出。

当前

  * remote/trunk
--o--a--b--c--d--e--f     <- master
  |
  o                       <- remote branch foo

期望结果

  * remote/trunk
--o                       <- master
  |
  o--a--b--c--d--e--f     <- remote branch foo

I made a bunch of commits to the master and realized after the fact that they should have been in a branch.

I've looked at various things about rebasing and merging and resetting the master. But no attempts at manipulation have yielded a history that looks like what I'm trying to do.

My attempts lead me to believe it requires some combination of rebase --onto and reset --hard to move the master back in time. But my understanding of Git's branching leaves something to be desired. Part of doing this is to learn how I can use it.

Should be noted none of the changes that I'm trying to move have been pushed out.

Current

  * remote/trunk
--o--a--b--c--d--e--f     <- master
  |
  o                       <- remote branch foo

Desired Outcome

  * remote/trunk
--o                       <- master
  |
  o--a--b--c--d--e--f     <- remote branch foo

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吾家有女初长成 2024-08-30 22:21:53

马丁的答案的一个变体不一定适用于你的情况,但我还是想发布它:)

假设你忘记在提交o时创建分支,所以你有:

x--y--z--o--a--b--c--d--e--f  master
         |
         +
   [forgot to make a branch here]

然后你意识到你真正想要的是:

x--y--z--o   master
         |
         +--a--b--c--d--e--f  topic

在这种情况下你可以做的是使用它的哈希在 o 创建一个分支:

git branch topic # creates new branch 'topic' - will be at commit `f`
git checkout o -b newmaster # creates new branch called newmaster pointing on commit `o` (please replace `o` with the actual hash)
git branch -M newmaster master # force rename newmaster to master (means master points on hash `o`)

你将位于 master 分支(提交 o) ,所以作为最后一步,您可以:

git checkout topic

哈希当然可以只是前 5 个字符..

编辑

您使用 git-svn 应该不重要,真正重要的是在o之后的任何时候你都没有发布你的master分支。git

中的分支实际上只是一个指向提交的指针。这就是分支如此便宜的原因:您只需创建一个指针,然后就有一个分支。

我不知道如何跟踪远程分支,您可能需要在重命名/移动分支后进行设置。

A variation on Martin's answer that won't necessarily be applicable to your situation, but I wanna post it anyway :)

Suppose you forgot to create the branch at commit o, so you have:

x--y--z--o--a--b--c--d--e--f  master
         |
         +
   [forgot to make a branch here]

And then you realized that what you really wanted was:

x--y--z--o   master
         |
         +--a--b--c--d--e--f  topic

What you can do in this case is create a branch at o using it's hash:

git branch topic # creates new branch 'topic' - will be at commit `f`
git checkout o -b newmaster # creates new branch called newmaster pointing on commit `o` (please replace `o` with the actual hash)
git branch -M newmaster master # force rename newmaster to master (means master points on hash `o`)

You'll be at the master branch (commit o), so as a last step you can:

git checkout topic

The hash of course can be just the first 5 characters ..

EDIT

It shouldn't matter much that you're using git-svn, what really matters is that you haven't published your master branch at any point after o

A branch in git is really nothing but a pointer to a commit. That's why branching is so cheap: you just create a pointer, and you have a branch.

I don't know about tracking remote branches though, you might need to set that up after renaming/moving your branches.

紙鸢 2024-08-30 22:21:53

我不确定重命名分支是否是正确的解决方案,因为它会让您从:

  * remote/trunk
--M--a--b--c--d--e--f     <- master
  |
  F                       <- remote branch foo

到:

--F                       <- master
  |
  M--a--b--c--d--e--f     <- remote branch foo
  * remote/trunk

(假设您重命名 remote/foo ,这是不可取的:您应该首先跟踪它,然后重命名它,但即使最终结果与您需要的不同),

这不是您想要的“期望结果”(foo 需要从 F 开始,而不是 M):

  * remote/trunk
--M                       <- master
  |
  F--a--b--c--d--e--f     <- remote branch foo

您只能通过 变基 --到

git checkout --track -b origin/foo  # create a local branch named after the remote one
git branch tmp                      # mark current foo HEAD to 'F'
git branch -f foo master            # put foo where it should b: at 'f'
git branch -f master tmp^           # reset master to M, parent of tmp
git checkout tmp                    # go to where we must replay the commits
git rebase --onto tmp master foo    # replay a to f on top of tmp
git svn dcommit                     # push the local foo in order to update remote/foo

给你:

  * remote/trunk
--M                             <- master
  |
  F--a'--b'--c'--d'--e'--f'     <- local foo and remote branch foo

I am not sure renaming the branches is the right solution, since it would get you from:

  * remote/trunk
--M--a--b--c--d--e--f     <- master
  |
  F                       <- remote branch foo

to:

--F                       <- master
  |
  M--a--b--c--d--e--f     <- remote branch foo
  * remote/trunk

(provided you rename remote/foo, which is not advisable: you should track it first, and then rename it, but even though the end result differ from what you need)

which is not the "Desired Outcome" you want (foo needs to start from F, not M):

  * remote/trunk
--M                       <- master
  |
  F--a--b--c--d--e--f     <- remote branch foo

You can only achieve that through a rebase --onto

git checkout --track -b origin/foo  # create a local branch named after the remote one
git branch tmp                      # mark current foo HEAD to 'F'
git branch -f foo master            # put foo where it should b: at 'f'
git branch -f master tmp^           # reset master to M, parent of tmp
git checkout tmp                    # go to where we must replay the commits
git rebase --onto tmp master foo    # replay a to f on top of tmp
git svn dcommit                     # push the local foo in order to update remote/foo

giving you:

  * remote/trunk
--M                             <- master
  |
  F--a'--b'--c'--d'--e'--f'     <- local foo and remote branch foo
深空失忆 2024-08-30 22:21:53

几乎正确了 hasen j 的建议,但我必须做一些小的修改(并且我使用 git-svn):

# create the branch with your commits
git branch performance
# fork the master to a new branch at the commit before your local, non pushed commits
git branch newmaster 2d0516dfe8252de87
# checkout your branch 
git checkout performance
# rename the newmaster
git branch -M newmaster master
# now checkout the master
git checkout master

你不能重命名你所在的分支,所以我检查了我移动提交的性能分支。

Nearly correct what hasen j suggests, but I had to make a few small modifications (and I use git-svn):

# create the branch with your commits
git branch performance
# fork the master to a new branch at the commit before your local, non pushed commits
git branch newmaster 2d0516dfe8252de87
# checkout your branch 
git checkout performance
# rename the newmaster
git branch -M newmaster master
# now checkout the master
git checkout master

You can't rename a branch you are on, so I checked out the performance branch where I moved my commits.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文