git - 恢复分支看起来像主人?

时间:2016-06-30 07:01:31

标签: git branch git-reset git-revert

我有两个分支developmaster。开发中有许多提交尚未在master中。虽然我需要使develop分支看起来与master完全相同。为了保留develop中发生的所有更改,我将从develop创建新分支,以便所有这些更改都不会丢失。

但在做完"复制" develop的{​​{1}},如何安全地重置或恢复为master

我看到了这个:Git: reset/revert a whole branch to another branches state?

所以要重置,我可以这样做:

git checkout develop
git reset --hard master

但问题是develop分支已被推送到远程,而其他人已经推送develop

也许有更安全的方法可以使用还原或其他方法来做到这一点?但我希望以一种可以恢复到master状态的方式恢复(如果可能),而不是手动选择每个提交,因为一些最新的提交需要保存在develop中,因为它们来自主(修补程序)。

因此develop提交的历史看起来像这样(大多数顶部意味着按日期提交最新提交):

commit hotfix2 - in both develop and master
some other commits that are only in develop
commit hotfix1 - in both develop and master
some commits that are only in develop
all commits that came when develop was created from master

2 个答案:

答案 0 :(得分:2)

以非破坏性方式撤消提交的标准流程是使用git revert。此命令基本上采用目标提交的反向差异并尝试应用它。因此,您将获得一个撤消所有更改的新提交。

要一次撤消多个提交,您还可以指定提交范围。假设您只想要撤消两个范围(这些修补程序之间的范围),这实际上是可以管理的。

您还可以使用标记--no-commit-n而不是自动创建提交。这允许您将多个git revert -n <commit>命令链接到另一个,而无需为每个命令创建还原提交。然后,当您完成选择要撤消的所有提交或提交范围时,您可以进行一次将所有提交组合在一起的提交。

在您的情况下,由于您有另一个具有完全(工作目录)状态的分支,您希望将develop分支放入其中,因此这样做要容易得多。您所要做的就是将master的工作树签出到develop分支中,并将该状态提交到develop分支。您可以使用git checkout master -- .执行此操作。不幸的是,这不适用于master分支未知的路径。因此,如果您在develop分支中添加了新文件,则会保留这些文件,您必须单独删除它们。

相反,我们从master开始一个新的分支(然后具有完全相同的内容),并重置该分支,使其基于develop。这样,我们将工作目录状态保持为master,但提交将跟随develop。之后,我们可以快进{1}}提交:

develop

通过将# checkout a new branch off master git checkout -b new-develop master # make a soft reset to develop git reset --soft develop # commit the changes git commit # get back to develop and fast forward git checkout develop git merge --ff-only new-develop git branch -d new-develop 链接到git revert -n独占的所有提交,这将导致同样的结果。还有其他一些方法可以达到这种状态,但这确实是最简单的。

无论您使用哪种方式进入此状态,都应考虑在之后进行合并。合并实际上不会做任何事情(因为两个分支具有相同的内容),但它将组合历史中的分支,因此您可以看到它们实际上会聚。

因此,假设历史最初看起来像这样:

develop

你想把它变成这个:

                       master
                         ↓
* ------------ h1 ------ h2
 \              \         \
  * -- * -- * -- * -- * -- *
                           ↑
                         develop

master ↓ * ------------ h1 ------ h2 ----- M \ \ \ / ↖ * -- * -- * -- * -- * -- * -- F develop 是我们上面创建的修复提交。这假定您希望在F时将develop合并到mastergit merge develop),然后快进masterdevelopgit merge master)开始从那时起新的开发工作。当然,如果您愿意,也可以在另一个方向进行。

或者,我们也可以在一个步骤中合并develop和修复M。您可以有效地将F合并到develop中,并以您最终使用master的内容的方式合并所有内容。这看起来像这样:

master

你可以像这样手动到达那里:

                                master
                                  ↓
* ------------ h1 ------ h2 ---- FM
 \              \         \      /  ↖
  * -- * -- * -- * -- * -- * ---/   develop

实际上,这是一种常见的情况,git merge附带了一个合并策略。因此,除了上述内容之外,我们可以使用# since we merge into master, we start there git checkout master # start the merge, but don’t attempt to fast-forward and do not # commit the merge automatically (since we want to change it) git merge --no-ff --no-commit develop # reset the index that was prepared during the merge git reset # now checkout the files from master and commit the merge git checkout master -- . git add . git commit 合并策略并丢弃我们合并到当前分支中的任何内容:

ours

答案 1 :(得分:0)

下面的命令将从origin / master

获取所有文件(当前分支中添加的新文件除外)
git checkout origin/master .

然后,可以使用git rm删除新文件,例如

git rm newfile