如何在不合并的情况下删除功能分支后保留对公共文件的修改?

how to preserve modifications to common files after deleting feature branch without merge?

假设我有一个功能分支,除了对分支的核心修改之外,我还对 .gitignore 公共文件进行了更改。假设我决定在提交后删除功能分支,但放弃与主分支合并。如何在删除功能分支时保留对 .gitignore 文件所做的更改而不丢失它们?

编辑:如果我想保留对多个常用文件的更改怎么办?

作为 Tim Biegeleisen noted in a comment,您 没有 在 Git 中执行此操作。对于像这样的单个文件,完全绕过 Git 绕过更新文件可能同样简单,甚至更容易:

cp .gitignore /tmp/save    # the .gitignore update was good, but
git checkout master
git branch -D feature      # the feature idea turned out to be bad
mv /tmp/save .gitignore
git add .gitignore
git commit

(然后写好提交信息)。

Jasen noted in another comment 一样,如果您自己提交此 .gitignore 更新,您可以轻松地 cherry-pick 从功能分支提交。您可以在删除功能分支之前 或之后 执行此操作,但是如果您这样做 找到 提交会容易得多 before 删除功能分支。例如:

git checkout master
git cherry-pick feature~3   # the good idea was 3 commits back
git branch -D feature

如果提交消息需要一些调整,请将 --edit 添加到您的 git cherry-pick 命令中。

最后——如果有多个文件要更新,这更有用,因为 /tmp/save 方法不够用——你可以使用 git restore(仅在 Git 2.23 或稍后)从其他提交中以提交的形式复制特定文件。因此,如果功能分支中的最终提交对 .gitignore 文件有很好的改进,但您不想要它的任何其他内容:

git checkout master
git restore --source=feature --staged --worktree -- .gitignore
git branch -D feature
git commit

这里的 --staged --worktree 导致 new-and-improved 文件已经是 staged-for-commit,因此不需要单独的 git add

如果你没有 git restoregit checkout 有一个模式,它与上面的模式完全相同:

git checkout master
git checkout feature -- .gitignore
git branch -D feature
git commit

This git checkout <em>specifier</em> -- <em>paths</em> 命令具有效果与 git restore --source=<em>specifier</em> --staged --worktree -- <em>paths</em>。请注意,这种形式的 git checkout,带有 -- <em>paths</em> 部分,意味着 go ahead and destroy any unsaved无需询问即可工作(通常git restore也是如此)。

如果您已经删除了功能分支怎么办?

要回答标题问题,上述所有 Git 方法仍然有效 只要您能找到 正确的提交哈希 ID。此哈希 ID 将在 HEAD 的 reflog 中找到。在 reflog 中找到分支名称(feature,在这种情况下)会更容易,但不幸的是,当删除分支名称时,reflog 也会被删除。

因此,运行 git reflog——默认显示 HEAD reflog——并找到合适的提交哈希 ID。然后用鼠标cut-and-paste hash ID作为--source for git restore,例如