我有两个分支develop
和master
。开发中有许多提交尚未在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
答案 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
合并到master
(git merge develop
),然后快进master
(develop
在git 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