如果合并到当前分支

时间:2016-10-04 19:59:39

标签: git git-branch

git branch -d someBranchName的行为几乎是完美的,除了有时它删除了实际未合并到当前签出分支的分支,只是因为它们有一个远程分支。 [呃,当然他们有一个我推的远程分支,我不想删除它们只是因为他们碰巧有一个原始的远程分支。]

如何将Git的行为更改为仅合并到当前分支的git branch -d个分支,或者是否存在可以使用别名执行相同操作的备用命令?

2 个答案:

答案 0 :(得分:3)

AFAIK,没有办法告诉Git这样做。来自git branch的手册页:

  

-d, --delete

     

删除分支。分支必须在其上游分支中完全合并,或者如果没有使用HEAD--track设置上游,则必须在--set-upstream中合并。

解决方法是取消设置您尝试删除的分支的上游,尝试删除,并在需要时恢复上游。然而,手动操作很痛苦,所以让我们尝试自动化。

this answer,获取给定分支的上游:

upstream=$(git rev-parse --abbrev-ref <branch>@{u})

取消设置上游:

git branch --unset-upstream <branch>

之后,您可以使用正常的安全删除:

git branch -d <branch>

如果分支未被删除,请恢复上游:

git branch -u $upstream $1

将所有内容放在脚本中(如果分支没有上游,则添加一些逻辑):

#!/bin/bash

unset=0
upstream=$(git rev-parse --abbrev-ref $1@{u})
if [ $? -eq 0 ]
then
  unset=1
  git branch --unset-upstream $1
fi

git branch -d $1

if [ $? -ne 0 && unset ]
then
  git branch -u $upstream $1
fi

或者,将其简化为别名:

[alias]
    delete-maybe = "! unset=0; upstream=$(git rev-parse --abbrev-ref $1@{u} 2>/dev/null); [ $? -eq 0 ] && unset=1 && git branch --unset-upstream $1; git branch -d $1; [ $? -ne 0 ] && [ $unset -eq 1 ] && git branch -u $upstream $1; true"

您现在可以使用它来安全删除分支:

git delete-maybe mybranch

答案 1 :(得分:1)

没有为此内置任何内容,因此您必须编写脚本。 (然后你需要确保你使用你的脚本而不是Git的内置git branch -d。直截了当的方法是训练自己运行一个不同的命令,但这可能很难。偷偷摸摸的方式是插入你的自己的替代前端git命令。有关更多信息,请在运行git时搜索(例如)bash别名技巧以运行系统git args之外的其他内容:您的其他内容然后可以检查 args 是否会调用git branch并运行您的其他命令。或者,只需将您自己的git脚本放在您自己的{{1}中}或bin目录,然后从那里调出系统scripts。)

要在脚本中执行,您只需要两个项目:

  1. 当前分支。要阅读当前分支,请使用git。这将打印当前分支的全名:

    git symbolic-ref HEAD

    或者它将完全失败,如果您不在命名分支上(即,处于“分离的HEAD”模式),则将消息打印到stderr:

    $ git symbolic-ref HEAD
    refs/heads/master
    

    您也可以使用$ git symbolic-ref HEAD fatal: ref HEAD is not a symbolic ref 获取当前分支的简称:

    git rev-parse --abbrev-ref HEAD

    但是当你处于“分离的HEAD”模式时,这只会打印$ git rev-parse --abbrev-ref HEAD master 。 (由您来决定您的脚本如何在这种情况下工作。)由于HEAD根据定义是当前分支,您甚至可以跳过HEAD步骤并只使用文字字符串{ {1}}这里。

  2. 测试建议删除分支名称是否解析为当前分支的祖先提交。执行此操作的命令是rev-parse,其中包含选项HEAD

    git merge-base
  3. 假设您对分离的HEAD行为没有问题,因此我们只需要第2项,我们可以将其包装成一行:

    --is-ancestor

    (这有点缺陷,因为如果if git merge-base --is-ancestor $to_be_deleted HEAD; then ... really delete it ... else ... complain ... fi 由于某些无关的原因而失败,则会打印错误,但这可能已经足够了。)