【问题标题】:Git branch still exists after deleting locally and remotely本地和远程删除后git分支依然存在
【发布时间】:2016-10-06 18:42:12
【问题描述】:

我有一个名为 Atomics 的开发分支(更准确地说,atomics)。它已完成开发。它测试OK,所以它被合并到Master中。我现在准备完全删除它,因为它不再需要了。

真的认为这个问题很清楚并且回答得很好:Delete a Git branch both locally and remotely。唉,没用……

这就是我所做的:

# Accepted answer, succeeded
$ git push origin --delete atomics

# Shit, it did not delete the local branch
$ git branch -a
...
* master
atomics

# Another answer. Whoops, causes an error
git push --delete origin atomics
error: unable to delete 'atomics': remote ref does not exist

# Try yet another answer:
git fetch --all --prune

# Check again
$ git branch -a
...
* master
atomics

根据 Torek 的回答:

$ git branch -d atomics
error: The branch 'atomics' is not fully merged.

# See below on the prelude that may have caused this
# (yet another Git black-hole)

# Yep, did not work
$ git fetch --prune origin
$ git branch -a
* master
atomics
...

如果重要的话,这是 Apple 的 Git:

$ git --version
git version 1.8.5.2 (Apple Git-48)

此时,我有两个问题。首先,我们如何删除实际工作的本地和远程分支?考虑到引用的问题,这似乎是多余的,但即使答案被接受,问题似乎也没有得到回答。

其次,我如何从这种部分删除的特殊 Git 状态中恢复?


这是前奏。 --squash 是为了保证log on Master is accurate

$ git checkout master
$ git merge --squash atomics
# These files already existed in Master, but a 'git push' after the merge
# did nothing. Also, 'git status' showed they were modified.
$ git add a.h b.h a.cpp b.cpp
$ git commit a.h b.h a.cpp b.cpp -m "Mergae Atomics into Master"
$ git push

编辑:我接受了 Torek 的回答,因为这个人太努力了,没有从中得到什么。不幸的是,该程序不适用于这个问题;当另一个开发分支被删除时,它在以下实验中不起作用。工具坏了,没有多少问答可以修复它。

【问题讨论】:

  • 您可以尝试阅读-Documentation...
  • @jthill - 或者,该工具可以修复 :o 但要回答您的问题,是的,我在手册页上花费了大量时间。然后我还要跟进 Stack Overflow,这会浪费更多时间。花费了太多时间,以至于有些人认为这是浪费时间。
  • 我们stopped using Git development branches。所有这些问题现在都解决了。我使用 问题无法再重现的原因投了第一票。

标签: git branch


【解决方案1】:

TL;DR:以任意顺序使用(至少)两个命令。删除本地(和/或远程跟踪,这也是本地的)。删除遥控器。

在您的输出中,atomics 是一个本地 分支。要删除它,请确保您不在它上面(您不在上面,它会以 * 为前缀,这只是一般的第一步),然后使用 git branch -d 将其删除。

[编辑以解释关于git branch -d发生的事情的编辑评论:如果Git抱怨本地分支没有完全合并,Git试图告诉你可能有一些您将无法访问的提交,这些提交不会保存在其他任何地方。如果没问题——如果你真的想抛弃它们,或者如果你想保留它们但很确定它们安全地保存在某处——你可以告诉 Git 强制删除,使用 git branch -Dgit branch --delete --force。这指示 Git 忽略可能被放弃的提交。 结束编辑]

push --delete 的内容是告诉某个远程站点的某个 other Git 删除 他的 本地分支。其他网站上发生的事情通常不会影响您的本地内容。有一些例外 - 特别是 git fetchgit push 可以进行本地更改 - 但默认情况下,任何一个都不会影响任何本地分支,无论它成功或失败获取其他分支Git 来做。

您可能还需要git fetch --prune origin 来删除您的远程跟踪分支(尽管名称如此,但它在您的存储库中是本地的)。您可以改用git branch -r -d origin/atomics(本地删除远程跟踪分支origin/atomics)。

【讨论】:

  • 感谢托雷克。我执行的所有命令都在 Master 上,而不是 Atomics。
  • 再次感谢托雷克。我已经合并了一个dev branch into master,所以我准备尝试另一个实验。请你清楚地说明你在这些句子中指的是什么命令:“使用(至少)两个命令,以任何顺序。删除本地(和或远程跟踪,这也是本地的)。删除远程.. .." 出于本次讨论的目的,我在 Master 上,我想删除 Unwanted everywhere .
  • 我对你的大写符号有点困惑,现在原始问题已经被编辑了好几次了。 current 版本的问题显示,在名为origin 的遥控器上没有分支atomics,所以此时唯一要做的就是在本地操作它。 git branch -d atomics 将删除本地分支 atomics 如果 这是完全安全的,git branch -D atomics 将不顾安全地删除它。
  • 如果您认为大写令人困惑,那么您应该尝试 Git 并 完全 删除一个分支 everywhere 。我真的在这个简单的概念上浪费了几个小时。回到你的问题,我希望这个分支离开everywhereAlignas branch。它是一个 dev 分支,不再需要它,因为它已合并到 Master 中。完成它的两个命令是什么?
  • 唉,我发现 github Web 界面非常混乱。因此,我从 GitHub (git clone git://github.com/weidai11/cryptopp) 克隆了存储库,这让我可以更直接地使用它。让我们放弃这个到目前为止的特定答案,它是关于不同的存储库和/或分支名称。 (我正在输入第二个答案,这需要一点时间。)
【解决方案2】:

这是一个单独的答案,部分原因是我可以获取一些格式,还因为我们现在似乎在谈论不同的存储库和/或分支。

从 GitHub 复制,所以我可以看到实际存在的内容

我首先克隆git://github.com/weidai11/cryptopp

$ cd tmp
$ git clone git://github.com/weidai11/cryptopp
Cloning into 'cryptopp'...
remote: Counting objects: 7756, done.
remote: Compressing objects: 100% (75/75), done.
remote: Total 7756 (delta 33), reused 0 (delta 0), pack-reused 7681
Receiving objects: 100% (7756/7756), 7.48 MiB | 1.87 MiB/s, done.
Resolving deltas: 100% (5480/5480), done.
Checking connectivity... done.
$ cd cryptopp/

现在我可以查看在 GitHub 上看到的分支。在我自己的仓库中,我只有一个本地的master(刚刚由git clone创建)。

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/alignas
  remotes/origin/arm-neon
  remotes/origin/det-sig
  remotes/origin/master
  remotes/origin/solaris

我看到有一个名为alignas 的分支。让我们找到它指向的提交:

$ git rev-parse origin/alignas
d0760a44eab5e6da04690d4a0d80fc306abd0844

还有其他指向此提交的名称吗?如果分支完全合并到其他分支中,就会有,如果没有,则不会:

$ git branch -r --contains d0760a44eab5e6da04690d4a0d80fc306abd0844
  origin/alignas

因此,origin/alignas 上至少有一个提交不在任何其他分支上。简要介绍一下(稍作编辑):

$ git show --name-status origin/alignas
commit d0760a44eab5e6da04690d4a0d80fc306abd0844
Author: [redacted]
Date:   [redacted]

    Fix CRYPTOPP_ALIGN_DATA placement

M       rijndael.cpp

如果我现在要从 GitHub 中删除这个分支——我不能,我在 GitHub 上没有对此存储库的写权限,并且git:// 没有提供写权限——那个提交将从 GitHub 中删除,可能还有其他一些. (进一步检查表明,在此之前的提交主要是合并其他分支上的 的东西;我们会丢失合并提交,但被合并的东西受到其他分支的保护。)

从 GitHub 中删除(我不能,所以,只是假设)

如果你现在想从 GitHub 删除这个分支,即使至少有一个提交会丢失,你1 可以这样做:

git push --delete origin alignas

这将使您在自己的存储库中保留远程跟踪分支origin/alignas(假设您现在拥有它),但git fetch origin --prunegit remote prune origin 随后会从您自己的存储库中删除origin/alignas

git fetch origin --prune

或:

git remote origin prune

git fetch origin --prune 步骤应该完成这项工作,但至少在某些版本的 Git 中,这被破坏了一段时间。


1当然,假设您具有写入权限并且正在使用https://ssh://。对我来说两者都不是真的,所以我不能。

你的存储库中的本地分支

您可能在您的存储库中有本地分支alignas。我还没有它,但是在你从 GitHub 中删除 alignas 之前,虽然我的 我的 存储库中仍然有 origin/alignas,我现在可以这样做了:

$ git checkout alignas
Branch alignas set up to track remote branch alignas from origin.
Switched to a new branch 'alignas'

现在我确实有了那个分支:

$ git branch -l
* alignas
  master

这是我当前的分支。假设我想从 my 存储库副本中删除它(同时留下 origin/alignas 单独):

$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

(这一步是必要的,因为 Git 不会让我删除我站在的分支)

$ git branch -d alignas
warning: deleting branch 'alignas' that has been merged to
         'refs/remotes/origin/alignas', but not yet merged to HEAD.
Deleted branch alignas (was d0760a4).

我的 git 版本是 2.8.1。 Apple git 1.8.x 可能会给你一个关于分支没有正确合并的错误。

让我再次创建本地alignas,然后再次删除它,这次更用力:

$ git checkout alignas
Branch alignas set up to track remote branch alignas from origin.
Switched to a new branch 'alignas'

这和以前一样:我的Git使用远程跟踪分支origin/alignas创建本地分支alignas,然后把我放在那个分支上。

$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git branch -D alignas
Deleted branch alignas (was d0760a4).

再一次,我必须下车,然后我才能删除它。一旦我在本地删除它,我就不能不小心推送它(见下文)。

其他人

拥有此存储库副本的任何其他人拥有alignas 分支。例如,假设 Fred 有一个副本,并且他没有删除 他的 alignas。进一步假设他在 GitHub 上拥有此存储库的写入权限。

在您从 GitHub 删除 alignas 后,Fred 可以随时重新创建它。他所要做的就是git push origin alignasgit push origin --all,然后它就会返回到 GitHub。

要阻止这种情况,您必须阻止 Fred。 :-)

【讨论】:

  • “如果我现在要从 GitHub 中删除这个分支......那个提交将从 GitHub 中删除” - 我已经尝试解析这个,但我没有不知道是什么意思。只要源代码有变化,我就可以忍受没有日志消息/历史作为妥协。如果不是这样,那么git checkout master; git merge alignas 出了什么问题?我知道这偏离了主题,但我正在努力解决断开连接的问题,以及如何将 dev 分支合并到 master 中不符合预期。
  • 再次感谢 Torek(由于篇幅原因,我不得不将其从第一条评论中删除)。总而言之,这三个命令按照它们应该从 master 执行的顺序排列:git push --delete origin alignas; git fetch origin --prune; git branch -d alignas。那是对的吗?我将执行它们,然后检查结果。如果结果是预期的(即,它已被删除所有地方),那么我将接受。如果它不起作用,那么我放弃并告诉人们“不要使用分支 x”。我也将停止使用 dev 分支,因为它们似乎不适用于更大的方案。
  • 另外,无需编辑。我也支持我的错误。我相信完全透明,不掩盖任何事情。
  • 最后,如果你想知道频繁的合并,那是因为Git kept breaking its index files,导致整个 repo 无法使用。我发现频繁的合并意味着我可以继续使用回购;否则我将不得不cp <changed files> <temp dir>; cd ..; rm -rf <dir>; git clone ... <dir>; cd <dir>; cp <temp dir>/* . 这是一种非常低效的做事方式。
  • (从食物回来)关于第一条评论:commit d0760a44eab5e6da04690d4a0d80fc306abd0844(其中有不同版本的rijndael.cpp)只有一个外部引用,即分支名称(@987654366 @ 在 GitHub 上,origin/alignas 在我的回购副本中)。 Git 的提交形成一个有向图。我们从所有外部引用(分支和标签名称)开始,然后进行 GC,就像 Lisp 一样:将它们标记为已引用。当引用的提交引用另一个 parent (或两个或更多用于合并)提交时,我们也会标记它们并递归。标记通过后,我们进行了一次扫荡(续):
【解决方案3】:

以下解决方案帮助了我:重写命令,但使用 -D 标志git branch -D your_branch

【讨论】:

    猜你喜欢
    • 2018-09-29
    • 2011-01-01
    相关资源
    最近更新 更多