有什么方法可以在将功能分支变基到另一个分支后安全地删除它?

Any way to safely delete a feature branch after rebasing it onto another?

我如何安全地 删除功能分支的本地副本,当它基于 origin/master 而不是合并时。我知道我可以 git branch -D,但我想避免盲目地这样做,让 git 告诉我哪些分支可以安全删除。

例如:我有功能分支 my-feature,我将其推送到 origin/my-feature,进行 PR,然后 origin/my-feature 重新基于 origin/master,然后删除。本地 my-feature 仍然存在。* 是否有任何方法可以检测到 origin/master 中已有效包含更改?

git diff origin/master...my-feature 不起作用,因为与 origin/master 的共同祖先没有改变。检查 git diff origin/master..my-feature 是否为空有效,但只能在变基后立即进行。如果任何其他更改基于我的更改,这将显示这些更改。

有没有办法删除远程版本被删除的本地分支? (但是 不是 从来没有远程版本的本地分支)。或者,如果我避免删除 origin/my-feature,那么我可以在本地做些什么来安全地删除 origin/my-featuremy-feature

* 如果我足够自律,我会尽量记住在删除远程分支后立即删除我的本地分支,但有时我会忘记。

让我先插入一些背景信息。我相信您是在谈论当有人在 GitHub 上使用 "rebase and merge" clicky 按钮时会发生什么。这会将提交复制到添加到目标分支尖端的一组新提交:

...--o--o--*--o   <-- master
            \
             A--B--C   <-- pullrequested

变为:

...--o--o--*--o--A'--B'--C'   <-- master
            \
             A--B--C   <-- pullrequested

这意味着 git branch --merged 没有帮助:它将测试提交 C 是否是提交 C' 的祖先,而 C 是否不是 C'.

(令人讨厌的是,GitHub 的 "rebase and merge" clicky 按钮似乎将提交重新复制到新的哈希 ID,即使在不需要的情况下也是如此。这可能是为了让作者和提交者分开,对于无法直接访问原始存储库的拉取请求。无论如何,结果是您的拉取请求分支的尖端,例如 C,不是目标尖端的祖先分支,例如 master.)

Checking that git diff origin/master..my-feature is empty works, but only immediately after rebasing.

不仅如此,如果没有额外的提交,差异通常只是空的,即,如果整体图表如下所示:

...--o--o--*--A'--B'--C'   <-- master
            \
             A--B--C   <-- pullrequested

一样,您可以使用git cherry查看是否所有提交(这里是A-B-C)都被复制了。如果有人将其捆绑到脚本中可能会很好。

git cherry 是完美的,从来不知道。我创建了一个别名来清理所有已合并到 upstream/master:

的分支
branch-cleanup = "!f(){ for b in $(git for-each-ref refs/heads --format=\"%(refname:short)\"); do if [[ ! $(git cherry -v upstream/master $b | grep \"^+\") ]]; then git branch -D $b; fi; done };f"

更具可读性:

for b in $(git for-each-ref refs/heads --format="%(refname:short)"); do  # Go through each branch
  # git cherry prefixes each commit with "+" if it's not included and "-" if it is, so check if there are no "+" lines:
  if [[ ! $(git cherry upstream/master $b | grep "^+") ]]; then
    git branch -D $b
  fi
done