git - 恢复分支看起来像 master?
git - revert branch to look like master?
我有两个分支 develop
和 master
。开发中有很多 master
中没有的提交。尽管我需要使 develop
分支看起来与 master
完全相同。为了保留 develop
中发生的所有更改,我将从 develop
创建新分支,这样所有这些更改都不会丢失。
但是在完成 develop
的 "copy" 之后,我如何才能安全地重置或恢复到 master
的样子?
我看到了这个:
所以要重置,我可以这样做:
git checkout develop
git reset --hard master
但问题是 develop
分支已经被推送到远程并且其他人已经拉 develop
了。
也许有更安全的方法使用恢复或其他方式来做到这一点?但我想恢复(如果可能)以恢复到 master
状态,而不是手动选择每个提交,因为一些最新的提交需要保留在 develop
中,因为它们来自 master(修补程序)。
所以 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
以非破坏性方式撤消提交的标准过程是使用 git revert
。该命令基本上采用目标提交的反向差异并尝试应用它。所以你得到一个新的提交来撤销所有的更改。
为了一次撤消多个提交,您还可以指定一个提交范围。鉴于您只有两个范围要撤消(那些修补程序之间的范围),这实际上是可管理的。
您还可以使用标志 --no-commit
或 -n
来 不 自动创建提交。这允许您将多个 git revert -n <commit>
命令一个接一个地链接起来,而无需为每个命令创建还原提交。然后,当您完成选择要撤消的所有提交或提交范围时,您可以进行一次合并它们的提交。
在你的情况下,因为你有另一个分支,它具有你想要将 develop
分支放入的确切(工作目录)状态,所以这样做要容易得多。您所要做的就是将 master
的工作树检出到您的 develop
分支并将该状态提交到 develop
分支。您可以使用 git checkout master -- .
来执行此操作。不幸的是,这不适用于 master
分支未知的路径。因此,如果您在 develop
分支中添加了新文件,这些文件将被保留,您必须单独删除它们。
相反,我们从 master
开始一个新分支(然后具有完全相同的内容),并重置该分支,使其基于 develop
。这样,我们将工作目录状态从 master
保留下来,但提交将遵循 develop
。之后,我们可以快进 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
while on master
)然后快进 develop
(git merge master
while develop
) 从那时起重新开始开发工作。当然,如果你愿意的话,你也可以反着做。
或者,我们也可以一步完成合并 M
和修复 F
。您可以有效地将 develop
合并到 master
中,并以最终得到 master
内容的方式合并所有内容。这看起来像这样:
master
↓
* ------------ h1 ------ h2 ---- FM
\ \ \ / ↖
* -- * -- * -- * -- * -- * ---/ develop
您可以像这样手动到达那里:
# 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
实际上,这种情况很常见,git merge
附带的合并策略正是这样做的。因此,我们可以只使用 ours
合并策略并丢弃我们合并到当前分支的任何内容,而不是上面的内容:
git checkout master
git merge -s ours develop
下面的命令将从 origin/master
中获取所有文件(当前分支中添加的新文件除外)
git checkout origin/master .
然后,可以使用git rm 删除新文件例如
git rm newfile
我有两个分支 develop
和 master
。开发中有很多 master
中没有的提交。尽管我需要使 develop
分支看起来与 master
完全相同。为了保留 develop
中发生的所有更改,我将从 develop
创建新分支,这样所有这些更改都不会丢失。
但是在完成 develop
的 "copy" 之后,我如何才能安全地重置或恢复到 master
的样子?
我看到了这个:
所以要重置,我可以这样做:
git checkout develop
git reset --hard master
但问题是 develop
分支已经被推送到远程并且其他人已经拉 develop
了。
也许有更安全的方法使用恢复或其他方式来做到这一点?但我想恢复(如果可能)以恢复到 master
状态,而不是手动选择每个提交,因为一些最新的提交需要保留在 develop
中,因为它们来自 master(修补程序)。
所以 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
以非破坏性方式撤消提交的标准过程是使用 git revert
。该命令基本上采用目标提交的反向差异并尝试应用它。所以你得到一个新的提交来撤销所有的更改。
为了一次撤消多个提交,您还可以指定一个提交范围。鉴于您只有两个范围要撤消(那些修补程序之间的范围),这实际上是可管理的。
您还可以使用标志 --no-commit
或 -n
来 不 自动创建提交。这允许您将多个 git revert -n <commit>
命令一个接一个地链接起来,而无需为每个命令创建还原提交。然后,当您完成选择要撤消的所有提交或提交范围时,您可以进行一次合并它们的提交。
在你的情况下,因为你有另一个分支,它具有你想要将 develop
分支放入的确切(工作目录)状态,所以这样做要容易得多。您所要做的就是将 master
的工作树检出到您的 develop
分支并将该状态提交到 develop
分支。您可以使用 git checkout master -- .
来执行此操作。不幸的是,这不适用于 master
分支未知的路径。因此,如果您在 develop
分支中添加了新文件,这些文件将被保留,您必须单独删除它们。
相反,我们从 master
开始一个新分支(然后具有完全相同的内容),并重置该分支,使其基于 develop
。这样,我们将工作目录状态从 master
保留下来,但提交将遵循 develop
。之后,我们可以快进 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
while on master
)然后快进 develop
(git merge master
while develop
) 从那时起重新开始开发工作。当然,如果你愿意的话,你也可以反着做。
或者,我们也可以一步完成合并 M
和修复 F
。您可以有效地将 develop
合并到 master
中,并以最终得到 master
内容的方式合并所有内容。这看起来像这样:
master
↓
* ------------ h1 ------ h2 ---- FM
\ \ \ / ↖
* -- * -- * -- * -- * -- * ---/ develop
您可以像这样手动到达那里:
# 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
实际上,这种情况很常见,git merge
附带的合并策略正是这样做的。因此,我们可以只使用 ours
合并策略并丢弃我们合并到当前分支的任何内容,而不是上面的内容:
git checkout master
git merge -s ours develop
下面的命令将从 origin/master
中获取所有文件(当前分支中添加的新文件除外)git checkout origin/master .
然后,可以使用git rm 删除新文件例如
git rm newfile