我如何将在主分支上的最近提交移到一个新的分支,并将主分支重置为这些提交之前的状态?例如,从这个状态:
master A - B - C - D - E
转化为:
newbranch C - D - E
/
master A - B
我如何将在主分支上的最近提交移到一个新的分支,并将主分支重置为这些提交之前的状态?例如,从这个状态:
master A - B - C - D - E
转化为:
newbranch C - D - E
/
master A - B
刚刚遇到了这种情况:
Branch one: A B C D E F J L M
\ (Merge)
Branch two: G I K N
我执行了:
git branch newbranch
git reset --hard HEAD~8
git checkout newbranch
我原本预期提交I会成为HEAD,但现在是提交L...
为了确保能够准确地定位到历史中的某个位置,最好使用提交的哈希值进行操作。
git branch newbranch
git reset --hard #########
git checkout newbranch
简而言之
git checkout branch_to_remove_commits
git reset --hard ${hash_of_new_tip}
git checkout -b branch_to_store_commits
# Move commits (single hash, list of hashes or range ffaa..ffoo)
git cherry-pick ${commit_hash}
git push --set-upstream origin branch_to_store_commits
# Switch back to last branch
git checkout -
git push -f
对我来说
git log --pretty=oneline -n ${NUMBER}
最好的方法是识别需要的提交哈希值。
从当前分支创建一个新的分支:git branch 新分支名称
推送您的新分支:git push origin 新分支名称
还原您的旧(当前)分支到最后一个推送/稳定状态:git reset --hard origin/旧分支名称
origin
之外还有其他的upstream
,他们应该使用适当的upstream
。git branch <branch name>
2)查找新分支上提交的最新提交ID。
git log
3)复制该提交ID。请注意,最近的提交列表位于顶部。因此,您可以通过消息找到您的提交。您还可以通过提供一些提交ID范围来查找。
git cherry-pick d34bcef232f6c...
现在,您的任务已完成。如果您选择了正确的ID和正确的分支,则会成功。因此,在执行此操作之前,请小心。否则,可能会出现其他问题。git push
我很惊讶没有人推荐以下方法:
git checkout master
git checkout <commit hash from which you want to split>
git checkout -b new_branch
git rebase master
git checkout master
git reset --hard <commit hash you splitted>
解释:
1)创建一个新分支,将所有更改移至new_branch。
git checkout -b new_branch
2) 然后回到旧分支。
git checkout master
3) 执行 git rebase
git rebase -i <short-hash-of-B-commit>
4) 然后打开的编辑器包含最近的3个提交信息。
...
pick <C's hash> C
pick <D's hash> D
pick <E's hash> E
...
5)在所有这3个提交中将pick
更改为drop
。然后保存并关闭编辑器。
...
drop <C's hash> C
drop <D's hash> D
drop <E's hash> E
...
6) 现在当前分支(master
)中最后的三个提交已被移除。现在需要使用强制推送的方式,将分支推送到远程仓库,需要在分支名前加上+
符号。
git push origin +master
这里的大多数解决方案都是计算您想回退的提交数量。我认为这是一种容易出错的方法。计数需要重新计算。
您可以通过传递您想要作为HEAD或者换句话说,您想要作为最后一个提交的提交哈希来简单地设置。
(注意查看提交哈希)
为了避免这种情况:
1) git checkout master
2) git branch <feature branch> master
3) git reset --hard <commit hash>
4) git push -f origin master
您可以将受到这3个提交影响的文件放回到暂存区,然后将代码重新提交到一个新分支。假设您在master
分支上,并且想要将恰好3个提交移动到new-branch
分支:
git reset --soft HEAD~3
git checkout -b new-branch
git commit -m "message"
代码现在已经提交到一个新的哈希值中,位于new-branch
分支,避免了一些其他答案所强调的未来变基问题。为了避免任何合并冲突,请推送master
分支:
git checkout master
git push -ff
这个解决方案还提供了完全重新创建提交的灵活性。在上面的示例中,我用一个提交替换了3个提交。但是,您当然可以通过将上面的commit
步骤替换为以下内容来取消暂存已暂存的文件:
git reset # unstage all files
git add path/file_1
git commit -m "first-commit"
git add path/file_2
git commit -m "second-commit"
...
git checkout old-branch # in the example, master
git reset --hard h4sh # h4sh is the hash for the commit
git checkout -b new-branch
git push origin new-branch
之后,这两个分支都与我进行的7次提交相关。在执行 git checkout new-branch
之后,我的 git log
和 git status
都很好,但是,当访问旧分支( git checkout old-branch
)时,我收到了“git落后于7个提交,可以快进”的消息。对我有用的是以下内容:
git checkout old-branch
git status
> git is behind by 7 commits and can be fast-forwarded
git push origin old-branch -f
在这一步之后,Bitbucket树中的最后7个提交仅与新分支相关,并且之前的提交被标记为旧分支和新分支。