我如何将我最近的承诺转移到一个新的分支机构,并在这些承诺完成之前重新定义主? 例如:

master A - B - C - D - E

为此:

newbranch     C - D - E
             /
master A - B 

当前回答

TLDR

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 reset HEAD~3
git stash
git checkout newbranch
git stash pop

如果你的主要目标是旋转回主 你想保持文件变更 你不关心错误的命令上的消息 你没有推,但 你想这很容易记住 你不想要如临时/新分支, 查找和复制命令, 和其他头痛等并发症

这是什么不做

目标

OP表示,目标是“在这些承诺完成之前重新掌握”而不失去变化,而这个解决方案就是这样。

不要这样做,如果你推了大师的变化

如果你只是重新编写你的本地大师没有影响,当它被推向上流,但推一个重新编写的历史给合作伙伴可能会导致头痛。

如果你想将你的承诺转移到一个现有分支,它会看起来如下:

git checkout existingbranch
git merge branchToMoveCommitFrom
git checkout branchToMoveCommitFrom
git reset --hard HEAD~3 # Go back 3 commits. You *will* lose uncommitted work.
git checkout existingbranch

警告: 这个方法工作,因为你正在创建一个新的分支与第一个命令: git 分支新分支. 如果你想将承诺转移到一个现有分支,你需要将你的变化融入现有分支之前执行 git 重新设置 --hard HEAD~3 (见移动到一个现有分支上)。

除非有其他情况涉及,否则可以轻松地通过连接和旋转。

# Note: Any changes not committed will be lost.
git branch newbranch      # Create a new branch, saving the desired commits
git checkout master       # checkout master, this is the place you want to go back
git reset --hard HEAD~3   # Move master back by 3 commits (Make sure you know how many commits you need to go back)
git checkout newbranch    # Go to the new branch that still has the desired commits

git reset --hard a1b2c3d4

最后,您可能需要强迫将最新的更改推到主重复:

git push origin master --force

警告: 使用 Git 版本 2.0 及以后,如果您稍后 git 将新分支转移到原始(主)分支上,您可能需要在转移期间明确的 --no-fork-point 选项,以避免失去所承担的承诺。

從其他文章中採取一些想法,避免任何與重新安裝有關的事情,並且非常偏見,我的解決方案是:

git 分支 # 更改可在新分支 git 推 # 上传,您可能需要与“--set-upstream”混淆,例如 git 推 --set-upstream https:/// 检查新分支在 git 通过 GUI 破坏现行目录从 git 存储库重新克隆

我不自豪,但我保留了我的数据。

大多数以前的答案都是危险的错误!

不要这样做:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

git reset --keep HEAD~3
git checkout -t -b newbranch
git cherry-pick ..HEAD@{2}

首先,它放弃了3个最新的承诺( - 保持像 - 硬,但更安全,因为它失败,而不是扔掉未承诺的变化)。 然后它放弃了新分支. 然后它将这些3个承诺返回新分支. 因为它们不再被一个分支提到,它这样做,使用 git 的回归: HEAD@{2} 是 HEAD 使用的承诺提到 2 个操作之前,即在我们 1 检查之前。

# newbranch will omit the 3 most recent commits.
git checkout -b newbranch HEAD~3
git branch --set-upstream-to=oldbranch
# Cherry-picks the extra commits from oldbranch.
git cherry-pick ..oldbranch
# Discards the 3 most recent commits from oldbranch.
git branch --force oldbranch oldbranch~3


技术解释

假设你分离起源 / 主,当它包含的承诺M1,M2,M3,然后做三个承诺自己:

M1--M2--M3  <-- origin/master
         \
          T1--T2--T3  <-- topic

但然后有人用强迫起源/大师重新编写历史,以删除M2:

M1--M3'  <-- origin/master
 \
  M2--M3--T1--T2--T3  <-- topic

M1--M3'  <-- origin/master
     \
      T1'--T2'--T3'  <-- topic (rebased)

因此,下列命令失败的原因:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

但在这个特殊情况下,我们希望这些3个承诺被视为主题分支的一部分,为了实现这一点,我们需要在以前的修订中排除上流,这不包括3个承诺。

對於那些想知道為什麼它工作(正如我開始的那樣):

你想回到C,然后移动D和E到新分支。

A-B-C-D-E (HEAD)
        ↑
      master

在Git分支新Branch之后:

    newBranch
        ↓
A-B-C-D-E (HEAD)
        ↑
      master

此分類上一篇: git reset --hard HEAD~2:

    newBranch
        ↓
A-B-C-D-E (HEAD)
    ↑
  master

因为一个分支只是一个指标,大师指向最后一个承诺。当你做了新的Branch,你只是做一个新的指标到最后一个承诺. 然后使用Git重新设置你移动了大师指标回两个承诺. 但因为你没有移动新的Branch,它仍然指向承诺它最初做了。