Git:如何撤销本地提交和文件添加?

4
我错误地将文件添加到master并提交了。否则,我必须在分支feature_x中进行操作。
现在我知道有一些命令,比如git reset。我的问题是,如果我重置,它会撤销我的代码还是只会撤销master中的文件和提交?
如何避免重置而不丢失代码?
更新:
代码尚未推送到远程。 当我尝试时,产生了错误: 错误:src refspec feature_x does not match any。

你已经将提交推送到公共仓库了吗? - joran
@joran 目前还没有,因为它出现了错误“error: src refspec feature_x does not match any”。 - Volatil3
在本地创建一个新的分支feature_x,切换到该分支,然后将其推送到远程仓库。 - ismailsunni
分支已经存在于Bitbucket上了。我只是无法进行checkout操作。 - Volatil3
错误 src refspec feature_x does not match any 可能意味着本地不存在分支 feature_x。要从远程获取,请运行命令 git fetch && git checkout -b feature_x origin/feature_x。(在较新的git版本中,您可以将其缩短为 git fetch && git checkout feature_x )。 - das-g
5个回答

8
您当前在主分支上,有意外提交X、Y和Z,如下所示:
A - B - C - X - Y - Z  <- master

现在,您可以在当前位置创建一个新分支。
git branch feature-x

feature-x分支将指向与主分支相同的提交版本,这使得将主分支重置到早期版本是安全的:

git reset --hard HEAD~3    # Move master branch 3 commits back

现在您拥有这个。
          X - Y - Z  <- feature-x
         /
A - B - C  <- master

现在您可以再次检查feature-x分支:
git checkout feature-x

也许我终于学会了如何阅读这些 Git 分支图表。无论如何,这很清晰。 - WestCoastProjects
这帮助我在我的代码稳定之前回滚一步,以便拉取主分支中的内容。 - Neri

0

我通常使用:

git reset --soft HEAD^

如果我不确定是否要删除我的提交记录。
它会将您带回到暂存阶段。

我想要的是,撤销多个git add和提交到master的更改,并将更改推送到分支feature_x - Volatil3
也许你可以使用 git cherry-pick - ismailsunni
告诉我一个事情;如果我正在master分支上并运行了git add,那么它们会被添加到master节点中,而git push origin feature_x将无法将这些提交的文件发送到feature_x吗? - Volatil3
@Volatil3 git add 将文件添加到索引(即暂存区)。仅当您使用 git commit 提交它们时,已添加的更改才会成为提交/修订。它们将要提交到哪个分支取决于 git commit 期间检出的分支,而不是在 git add 期间检出的分支。如果您将一个分支推送到远程,只有它的提交将被推送,而不包括任何已添加但尚未提交的更改。 - das-g

0

我不太清楚命令行的方式,但大多数Git客户端都有一个名为“放弃”(discard)的按钮。在Sourcetree中,这个按钮位于您的工具栏的第三个位置。点击它可以删除所有本地更改,如果您已经提交了这些更改,请使用还原(revert)功能来撤销它们。


0
如果我理解正确,您在master分支上有提交记录,但您不想在master分支上保留这些提交记录,而是希望将它们保持不变。相反,您希望这些提交记录出现在feature_x分支上。我假设您想要的提交记录是master上的最后一次提交记录,因此在它们之间没有您想要保留在master上的提交记录。
在这里需要知道的重要信息是,在git中,一个提交记录所在的分支并不是其固有属性。分支只是指向特定修订版本的命名指针(类似于标签),如果在检出该分支时提交了新的修订版本,则该指针会自动移动到新的修订版本(与标签不同)。
因此,

如果feature_x分支尚不存在

如果您有未提交的更改(已添加到索引或未添加)需要保留,可以使用以下命令将其暂存并搁置:
``` git stash ```
切换到主分支:
``` git checkout master ```
创建指向与主分支相同提交的 `feature_x` 分支:
``` git branch feature_x ```
在继续之前,请确保:
- 以上所有命令均未失败或产生任何意外输出。 - `master` 仍然是当前所在分支。
现在,将主分支移动到您想要在 `master` 上的最后一次提交上。如果那是 Bitbucket 的 `master` 指向的提交,并且您在本地仓库中拥有 Bitbucket 仓库作为远程 `origin`(可通过 `git remote -v` 查看),则可以按如下操作:
确保本地仓库对远程仓库的了解是最新的:
``` git fetch ```
将当前所在分支(您的本地 `master` 分支)移动到远程 `master` 分支指向的提交:
``` git reset --hard origin/master ```
如果在不想要的提交之前,`master` 上还有一些提交,您希望将它们保留在 `master` 上,但是它们尚未出现在您的 Bitbucket 仓库中,则可能更容易从当前本地 `master` 分支向后导航。例如,您希望在 `master` 上不再有最后 5 次提交,而它们是纯线性的(其中没有合并),则可以执行以下操作:
``` git reset --hard master~5 ```
如果情况比这更复杂(例如,在您不想要的历史记录部分中存在合并),则使用图形工具帮助找出您想要在 `master` 上的最后一次提交的 ID(SHA1 哈希),然后将 `master` 移动到该提交。例如,如果提交ID为 `a1b2c3d4`,则可以执行以下操作:
``` git reset --hard a1b2c3d4 ```

如果分支feature_x已经存在...

...并且指向master的祖先

按照上述步骤进行,但在步骤1和步骤2之间(即在检出master之前),使用以下命令将feature_x移动到当前的master

git checkout feature_x
git merge --ff-only master

跳过第三步(创建分支feature_x)。

...并且它有一些提交不在master

但是你想将这些提交与来自master的相关提交一起保留在feature_x上,那么你有几种选择。

最简单和最安全的方法是在步骤1和步骤2之间(即在你检出master之前)将来自master的提交合并到feature_x中:

git checkout feature_x
git merge master  # You might want to modify the suggested commit message,
                  # as 'merge master into feature_x' will be confusing when
                  # those commits won't be ancestors of 'master' later on.

然后从步骤2开始,跳过步骤3,继续进行。

如果您想要在feature_x上获得线性历史记录,则有两种选择:将来自主分支的提交重新基于feature_x的提交(这样就好像您一开始就在feature_x上提交了它们,而且是在已经存在的提交之后),或者将来自feature_x的提交重新基于主分支上的提交(这样就好像先前在主分支上的提交是在feature_x上提交的,甚至是在已经存在的提交之前)。如果线性历史记录不是必须的,我建议不要使用这两个选项,因为重新基础可能会变得有点棘手,并且需要非常了解git。如果您仍然要追求其中之一,请确保知道自己在做什么(阅读您使用的命令的帮助页面),并且确保正确执行(确保您已经理解了这些帮助页面并尽量避免打错字)。特别是第一次重新基础时(但以后也是如此),可能值得制作存储库的本地副本,以便在出现问题时备份。


-1

如果你想从不同的分支推送你的代码,你不需要撤销你的提交。

  • 只需拉取主分支并从主分支创建新分支
  • 之后推送你的分支并创建合并请求
  • 合并你的代码
  • 将主分支拉取到本地

应该就可以了。


这些步骤的执行方法以及在问题场景中应该达到什么效果都不是很清楚。 - das-g
最初的问题是“我将我的更改提交到主分支,但我需要将其提交到另一个分支”。所以我认为他在提交之前忘记创建一个新分支,因此他无法将更改发送到源。因为通常你不能直接推送到主分支(为了代码的安全)。我说他不需要回滚任何东西。他所需要做的就是从本地主分支创建一个新分支,并推送包含所有更改的新分支。在将该新分支合并到主分支后,问题将得到解决。 - umut

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接