将 Git 分支带到其他分支的提交状态
Bring Git branch to state of commit in other branch
假设我有 2 个最近分开的分支机构 A(旧分支机构)和 B(新分支机构)。在 A2 中我犯了一些错误(破坏了一些我想保留的文件的历史记录),我用 B2 修复了。
我想将分支 B 的工作目录变为提交 A3 的状态,但不要 merge/commit。相反,我宁愿只进行 (staged/unstaged) 本地更改,以便在下一次提交后,B3 将与 A3 相同(但不以任何方式链接到 A2 或 A3):
A1 - [A2 - A3 - A4] (A will be deleted after the fix)
\
B2 - B3=(state of)A3 - A4
我这样做的原因是我弄乱了中间状态A2,我想用B2修复它,然后直接用A3继续。
我想到的最简单的方法是在另一个文件夹中检出 A3,删除 B 的内容并用 A3 的内容覆盖。
有Git命令可以直接实现吗?
新的(自 Git 2.23 起)git restore
命令可以作为单个命令执行此操作,使用 git restore --source <em>从工作树的顶层提交</em> --worktree -- .
。由于这种 git restore
不会影响 Git 的索引,因此这里没有上演。但这对 想要 来说是一件非常奇怪的事情,所以在你做之前要非常确定它真的是你想要的。
(将 --staged
添加到上面的 git restore
也会使所有内容都暂存提交。请注意,这与 git checkout <em>commit</em> -- .
as git restore
运行s 默认处于“无覆盖”模式,而 git checkout
使用“覆盖”模式。 )
请注意,这不会将任何 分支 带到任何状态。分支 没有 这种状态:分支名称仅标识提交哈希 ID。此 git restore
命令只是修改 工作树 的内容以匹配指定的提交,单独保留索引/暂存区。随后的 git commit
使用 Git 索引中的任何内容,因此您必须 运行 git add
才能影响后续提交。
@torek 的回答对我有用,他们显然比我更了解 git。
如果你只是想让分支 B 从 A3 出来,你可以 git checkout B; git reset --hard A3
这给你:
A1 - A2 - A3 - A4
\ \
\ B
[ B2 - B3 ] These will get removed eventually; are no longer on a branch
如果您想在 B
分支的历史记录中保留提交 B2
,那么您有两个选择:
选项 1
只需创建一个新分支“abandoned-b-branch”,然后执行上述操作。这意味着如果需要,您将始终可以参考那个被遗弃的 b 分支。
选项 2
git checkout B
git revert -n B2
git merge -n A3 # or even use cherry-pick -n
这使您的工作树处于 A3
,但您的 B2
按原样提交并且仍在 A1
.
编辑 1 - 解决已澄清的问题
我设置了相同的场景
* a3420df (branch-A) A4
* e8b5e69 A3
* 3f9837f A2
| * 1465593 (branch-B) B2
|/
* 6835b02 A1
- Commit
A1
只有一个文件,A1
- 提交
A2
添加 A2
- 提交
A3
添加 A3
并删除 A2
- 提交
A4
添加 A4
- 提交
B2
添加 B2
你更新的问题说你想要
A1 - [A2 - A3 - A4] (A will be deleted after the fix)
\
B2 - B3=(state of)A3 - A4
我这样做了:
git checkout branch-B
git revert -n 1465593
git cherry-pick -n 3f9837f e8b5e69
这使工作树处于 A3
状态,文件 A1
和 A3
。然后我可以继续将其提交为 B3,然后应用 A4
git commit -m "B3"
git cherry-pick -n a3420df
git commit -m A4
给我留下分支 B(最后一个)看起来像
* 262a312 (HEAD -> branch-B) A4
* 7bca645 B3
* 1465593 B2
* 6835b02 A1
在工作树中,我有 A1、A3、A4。提交 A2
已从我的分支历史记录中消失,但我的历史记录中仍有 B2。
假设我有 2 个最近分开的分支机构 A(旧分支机构)和 B(新分支机构)。在 A2 中我犯了一些错误(破坏了一些我想保留的文件的历史记录),我用 B2 修复了。
我想将分支 B 的工作目录变为提交 A3 的状态,但不要 merge/commit。相反,我宁愿只进行 (staged/unstaged) 本地更改,以便在下一次提交后,B3 将与 A3 相同(但不以任何方式链接到 A2 或 A3):
A1 - [A2 - A3 - A4] (A will be deleted after the fix)
\
B2 - B3=(state of)A3 - A4
我这样做的原因是我弄乱了中间状态A2,我想用B2修复它,然后直接用A3继续。
我想到的最简单的方法是在另一个文件夹中检出 A3,删除 B 的内容并用 A3 的内容覆盖。
有Git命令可以直接实现吗?
新的(自 Git 2.23 起)git restore
命令可以作为单个命令执行此操作,使用 git restore --source <em>从工作树的顶层提交</em> --worktree -- .
。由于这种 git restore
不会影响 Git 的索引,因此这里没有上演。但这对 想要 来说是一件非常奇怪的事情,所以在你做之前要非常确定它真的是你想要的。
(将 --staged
添加到上面的 git restore
也会使所有内容都暂存提交。请注意,这与 git checkout <em>commit</em> -- .
as git restore
运行s 默认处于“无覆盖”模式,而 git checkout
使用“覆盖”模式。 )
请注意,这不会将任何 分支 带到任何状态。分支 没有 这种状态:分支名称仅标识提交哈希 ID。此 git restore
命令只是修改 工作树 的内容以匹配指定的提交,单独保留索引/暂存区。随后的 git commit
使用 Git 索引中的任何内容,因此您必须 运行 git add
才能影响后续提交。
@torek 的回答对我有用,他们显然比我更了解 git。
如果你只是想让分支 B 从 A3 出来,你可以 git checkout B; git reset --hard A3
这给你:
A1 - A2 - A3 - A4
\ \
\ B
[ B2 - B3 ] These will get removed eventually; are no longer on a branch
如果您想在 B
分支的历史记录中保留提交 B2
,那么您有两个选择:
选项 1
只需创建一个新分支“abandoned-b-branch”,然后执行上述操作。这意味着如果需要,您将始终可以参考那个被遗弃的 b 分支。
选项 2
git checkout B
git revert -n B2
git merge -n A3 # or even use cherry-pick -n
这使您的工作树处于 A3
,但您的 B2
按原样提交并且仍在 A1
.
编辑 1 - 解决已澄清的问题
我设置了相同的场景
* a3420df (branch-A) A4
* e8b5e69 A3
* 3f9837f A2
| * 1465593 (branch-B) B2
|/
* 6835b02 A1
- Commit
A1
只有一个文件,A1
- 提交
A2
添加A2
- 提交
A3
添加A3
并删除A2
- 提交
A4
添加A4
- 提交
B2
添加B2
你更新的问题说你想要
A1 - [A2 - A3 - A4] (A will be deleted after the fix)
\
B2 - B3=(state of)A3 - A4
我这样做了:
git checkout branch-B
git revert -n 1465593
git cherry-pick -n 3f9837f e8b5e69
这使工作树处于 A3
状态,文件 A1
和 A3
。然后我可以继续将其提交为 B3,然后应用 A4
git commit -m "B3"
git cherry-pick -n a3420df
git commit -m A4
给我留下分支 B(最后一个)看起来像
* 262a312 (HEAD -> branch-B) A4
* 7bca645 B3
* 1465593 B2
* 6835b02 A1
在工作树中,我有 A1、A3、A4。提交 A2
已从我的分支历史记录中消失,但我的历史记录中仍有 B2。