ChatGPT解决这个技术问题 Extra ChatGPT

拉动后将已提交(但未推送)的更改移动到新分支

git

我已经完成了相当多的工作(“您的分支比 'origin/master' 领先 37 次提交。”)确实应该进入它自己的分支而不是 master。这些提交只存在于我的本地机器上,并没有被推送到 origin,但情况有些复杂,因为其他开发人员一直在推送到 origin/master,而我已经取消了这些更改。

如何追溯地将我的 37 个本地提交移动到新分支上?根据文档,git rebase --onto my-new-branch master...origin/master 似乎应该这样做,但两者都只给我错误“致命:需要一个修订版”。 man git-rebase 没有说明提供对 rebase 的修订,它的示例也没有这样做,所以我不知道如何解决这个错误。

(请注意,这不是Move existing, uncommited work to a new branch in GitHow to merge my local uncommitted changes into another Git branch? 的重复,因为这些问题涉及本地工作树中未提交的更改,而不是已在本地提交的更改。)

看看这个solution。似乎很容易和干净。

M
Mark Longair

这应该没问题,因为您还没有将提交推送到其他任何地方,并且您可以在 origin/master 之后自由地重写您的分支的历史记录。首先,我将运行 git fetch origin 以确保 origin/master 是最新的。假设您当前在 master,您应该能够:

git rebase origin/master

... 这会将不在 origin/master 中的所有提交重播到 origin/master。 rebase 的默认操作是忽略合并提交(例如您的 git pull 可能引入的那些),它只会尝试将您的每个提交引入的补丁应用到 origin/master。 (您可能必须在此过程中解决一些冲突。)然后您可以根据结果创建新分支:

git branch new-work

...然后将您的 master 重置回 origin/master

# Use with care - make sure "git status" is clean and you're still on master:
git reset --hard origin/master

在使用 git branchgit reset 等进行这种操作分支时。我发现经常使用 gitk --all 或类似工具查看提交图很有用,只是为了检查我是否了解所有不同的 refs 在哪里指点。

或者,您可以先根据您的主服务器的位置 (git branch new-work-including-merges) 创建一个主题分支,然后如上所述重置 master。但是,由于您的主题分支将包含来自 origin/master 的合并,并且您尚未推送您的更改,因此我建议您进行变基以使历史更整洁。 (此外,当您最终将主题分支合并回 master 时,更改会更加明显。)


@Olie:不,根据问题中的假设以及我在答案顶部列出的假设,答案是正确的。应该在单独的新分支上的提交已经在 master 中; rebase 重写 master 分支,以便新的提交线性地位于 origin/master 之上,然后 git branch new-work 创建一个 new-work 分支,指向 master 的尖端(当前分支)without< /i> 将当前分支切换到 new-work。所以现在 new-work 包含所有新提交。然后重置将当前分支(仍然是 master)移回 origin/master
@Quintesse:如果您丢了工作,我很抱歉,但我确信这个答案对于原始提问者所描述的情况是正确的。 (我刚刚回复了 Olie 的言论,希望能澄清一下。)无论如何,以防万一它有助于恢复您的工作,我应该说,如果您的工作是在过去几天内完成的(本问答中的假设之一) ) 你应该可以很容易地通过 git reflog 来检索它。
@Olie:也许是一种更好的解释方式:git 中的分支就像指向特定提交的标签;如果您在该分支上创建它们,它们会自动移动到新提交,或者可以使用 git reset 和其他各种方式移动。 git branch new-work 只是说“创建一个指向此提交的分支,而我仍然在我的当前分支上(在这种情况下是主分支)”。所以不需要有一个命令将提交从 master 移动到新分支 - 您只需在那里创建一个新分支,当您重置 master 时,新分支将留在 master 所在的位置
派对有点晚了,但@Olie,只是因为新分支上的 git status 没有显示 master 之前的提交并不意味着它们实际上并不存在(假设这就是你担心的原因)。尝试将新分支推送到原点:您将看到提交在那里
@FélixGagnon-Grenier,不要担心“迟到”——总是有人查找旧问题,每一个澄清都有帮助。谢谢! :)
S
Stachu

如果您的提交数量很少,并且您不在乎这些是否合并为一个大型提交,那么这很有效,并且不像 git rebase 那样可怕:

取消暂存文件(将 1 替换为 # of commits)

git reset --soft HEAD~1

创建一个新分支

git checkout -b NewBranchName

添加更改

git add -A

做出承诺

git commit -m "Whatever"

要显示易于理解的图表,请使用 git log --all --decorate --oneline --graph
嘿@EliuX - 我在这里错过了相关性。可以扩展吗?
这对于检查您是否在所做的事情中获得了想要的结果很有用
感谢你!!这是一个非常简单的解决方案,而且效果很好!!
不知道出了什么问题,但我只是失去了一些工作。当我切换到新分支时,我的工作丢失了——此时所有更改都消失了。
A
Ariel

我坚持同样的问题。我找到了我喜欢分享的最简单的解决方案。

1)使用您的更改创建新分支。

git checkout -b mybranch

2)(可选)在远程服务器上推送新的分支代码。

git push origin mybranch

3)结帐回到主分支。

git checkout master

4)使用远程服务器重置主分支代码并删除本地提交。

git reset --hard origin/master

这真的是最简单的方法
您可以省略第 2 步。我假设在最佳答案之后的时间里,git 发生了变化,并且以前不允许使用此过程。
这是我认为最好的答案。
这个答案需要移到顶部。谢谢你。
想详细说明为什么会这样。您有一组已提交给本地 master 但未在源上更新的提交。然后,您从本地更新创建一个分支,该分支反映了所有新更改。当您切换回主服务器并硬重置它时,它会重置回原点的主服务器。您的新分支仍然具有它在重置之前从本地 master 继承的更改。新分支不会与本地 master 一起重置。如果您是第一次这样做,您可能会考虑备份您的存储库并确认您的更改已在备份中。
A
Andriy

另一种方法假设 branch1 - 是提交更改的分支 branch2 - 是可取的分支

git fetch && git checkout branch1
git log

选择您需要移动的提交 ID

git fetch && git checkout branch2
git cherry-pick commit_id_first..commit_id_last
git push

现在从初始分支恢复未推送的提交

git fetch && git checkout branch1
git reset --soft HEAD~1

Cherry-pick 确实是最好的“复制/移动单个提交”命令,尤其是。当历史成为你的包袱时。
这是迄今为止对这个问题最方便的答案。谢谢你的命令!
您可以更新您的最后一条评论,其中 1 或 n 是未推送提交的数量吗?对于这个问题,这仍然是一个非常好的解决方案。
t
testing

或者,在您提交到错误的分支后,立即执行以下步骤:

git log git diff {previous to last commit} {latest commit} > your_changes.patch git reset --hard origin/{your current branch} git checkout -b {new branch} git apply your_changes.patch

我可以想象对于第一步和第二步有一种更简单的方法。


T
Tim Keating

关于什么:

从当前 HEAD 分支。确保你在 master 上,而不是你的新分支上。 git reset 回到您开始进行更改之前的最后一次提交。 git pull 仅重新拉取您在重置时丢弃的远程更改。

或者当您尝试重新合并分支时会爆炸吗?


啊,这基本上是上面@Mark-Longair 描述的选项B
A
A Kok

这是一个更简单的方法:

创建一个新分支在你的新分支上做一个 git merge master - 这会将你提交的(未推送的)更改合并到你的新分支删除你本地的 master 分支 git branch -D master 使用 -D 而不是 -d 因为你想强制删除分支。只需在您的主分支上执行 git fetch 并在您的主分支上执行 git pull 以确保您拥有团队的最新代码。


从本地主分支到目标分支的合并是一个很好的技巧。删除并重新拉取主分支是不必要的。只需 git reset --hard origin/master 即可丢弃主分支中未推送的更改。
u
user1429980

我一直在使用的一种更简单的方法(假设您要移动 4 个提交):

git format-patch HEAD~4

(查看对 4 个 .patch 文件执行最后一个命令的目录)

git reset HEAD~4 --hard

git checkout -b tmp/my-new-branch

然后:

git apply /path/to/patch.patch

按照你想要的任何顺序。


J
John Conde

签出您的源的新副本 git clone ........ 从所需位置创建分支 git checkout {position} git checkout -b {branch-name} 添加远程存储库 git remote add shared ../{original sources location} .git 获取远程源 git fetch shared 签出所需分支 git checkout {branch-name} 合并源 git merge shared/{来自共享存储库的原始分支}


S
Sebastian

对我来说这是最好的方法:

检查更改和合并冲突 git fetch 创建一个新分支 git branch my-changes 并推送到远程 将上游更改为新创建的分支 git master -u upstream-branch remotes/origin/my-changes 将您的提交推送到新的上游分支。切换回之前的上游 git branch master --set-upstream-to remotes/origin/master