git push --all --tags: 不兼容

13

当我尝试将所有分支和标签推送到远程时,Git 会发出以下错误:

# git push origin --all --tags
fatal: --all and --tags are incompatible

然而,这是可以正常工作的:

# git push origin refs/heads refs/tags
Everything up-to-date

问题:

  1. 为什么 git 命名 push-all-branches 选项为 --all 而不是 --branches 或者 --heads?执行 git push origin --all 只推送分支,而不是所有引用。这种命名背后的哲学是什么?这是否意味着标签在 Git 存储库中真的是二等公民?

  2. 为什么 Git 不允许同时使用 --all--tags 选项?


PS. 我知道有一个 --follow-tags 选项。我知道有些人不建议推送所有标签,但本主题与此无关。


man git-push:

--all

推送所有分支(即 refs/heads/ 下的引用);不能与其它 <refspec> 一起使用。

--tags

除了显式列出在命令行上的 refspecs 外,还会推送 refs/tags 下的所有引用。


1
我不确定文档怎样才能更清楚地表明 --all 不能与 --tags 一起使用。没有任何原因,只是在很久以前有人编写了这个代码,现在它就是这样运行的。 - torek
1
因为我还没有弄明白git push origin refs/heads refs/tags,但它确实很方便,所以我点了个赞。 - Romain Valeri
3
@torek 有人刚刚编写了那个,说真的,这背后没有什么技术性的东西吗?对我来说,这听起来就像面包和牛奶不兼容一样。如果你不允许别人做某事,你应该给出一个有效的理由。否则他们应该享有自由。Git显然是自由软件。 - Cyker
我认为这个问题可以追溯到引用被系统化之前。有人让 git push --all 意味着所有分支,由于Git的开发人员不愿意改变参数的含义,我们就被困在了这个问题上。这是相当不一致的,但是 git rm --cachedgit diff --staged 也是如此。他们最终确实改变了 git add -A,所以如果你开始一场运动,也许Git 3.0或4.0会有一些更明智的选项。 - torek
1
@Cyker 是的,正如下面提到的 Jeff King 发现的 bug 所示。 - VonC
显示剩余2条评论
1个回答

6

该消息 "--all 和 --tags 不兼容" 来自 builtin/push.c#cmd_push()

这是由 Marek Zawirski 在 2008 年 8 月(Git v1.6.1-rc1)的 commit b259f09 中引入的:

使 push 命令对选项的非法组合更详细

对于 git push,使用 --all--mirror--tags 和/或显式 refspecs 的组合可能不清楚。

Git 在这些情况下默默地失败,而我们可以更恰当地进行抱怨。

在2008年,Marek正在实现JGit中的git push, 并提出了上述补丁的建议,其中包括:

我忘记了这个问题,很久以前就有人报告过。

似乎很不清楚为什么使用$ git push --tags --all等命令时会失败,可能与实现有关。

虽然可以配置远程主机, 但是:

[remote "origin"]
  push = refs/heads/*
  push = refs/tags/*

Jeff King 发现了一个死锁的bug,这可能就是为什么需要这个补丁。

发送者会发送“tellme-more”,然后等待对方回复。
接收者会收到“tellme-more”,但不会再回复其他内容,可能是因为他没有这个提交(因为主分支比任何标签都要新)。

简而言之,将分支和标签分别推送似乎比一起推送更容易支持。

查看更多信息,“同时推送git提交记录和标签”,使用 git push --follow-tagsgit config --global push.followTags true 命令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接