git stash堆栈是否被推送到远程仓库?

时间:2014-05-30 10:38:30

标签: git git-stash

我的stash堆栈是否已推送到remote repo?还是完全被忽略了?

我只是好奇我是否应该每隔一段时间倾向于放弃一些以节省服务器空间。

2 个答案:

答案 0 :(得分:29)

作为一般规则,没有。如果你愿意的话,可以推送它。

这里有关于推送(以及,就此而言,提取)的事情:这些工作基于" refspecs",您在其中命名本地引用名称 - 或者,对于推送和特定情况,一个原始的commit-ID,然后是一个远程引用名。

那么什么是参考名称?

大多数情况下,您命名分支引用,例如master或"远程分支"比如origin/master。令人困惑的是,git称之为"远程分支"实际上是一个本地实体,而不是 on 远程,而是 存储库中的一个特殊名称下的分支。

分支实际上只是一个名称以refs/heads/开头的引用。这真的几乎都是一个分支。 (关于分支还有一个特别之处:当你在其中进行新的提交时,分支会自动移动。也就是说,如果你在master分支上,你做了一个新的提交,git更新refs/heads/master指向新的提交。)

A"远程分支"只是一个名称以refs/remotes/开头的引用,然后包含远程名称(通常为origin)。所以refs/remotes/origin/master是一个"远程分支":一个本地实体,你的 repo中的一个名称,你的git用它来跟踪" where {{上次git使用master"签到时,{}}}已登录origin。每当您从/ origin获取或推送时, 1 git会根据其所看到的内容更新您的origin名称"在那里"。

标签只是以origin/branch开头的引用。

通常您会遗漏所有这些前缀,只需将refs/tags/写成master中的主分支,refs/heads/master表示origin/masterrefs/remotes/origin/master表示平均v2.3。 Git自动计算出哪一个,因为它很明显。精确的规则在gitrevisions中描述。 (令人恼火的是,refs/tags/v2.3git checkout并不总是遵循gitrevisions规则:当他们知道某些内容是一个分支名称时,他们只是假设 git branch部分。其他 git命令确实按照描述工作。)

refs/heads/脚本使用简单拼写为stash的引用。因此,您可以通过编写refs/stash来命名此引用; git会发现它不是分支,也不是远程分支,也不是标记,最终会使用stash来解析名称。 2

......这意味着什么?

这意味着如果你写了:

refs/stash

git会找到你的存储(只有一个存储)并尝试将其推送到名为$ git push origin stash:ssss 的远程引用。这很可能会失败;这是我尝试时发生的事情:

ssss

为了好玩,我尝试了下一个命令,并得到了一个不同的错误:

error: unable to push to unqualified destination: ssss
The destination refspec neither matches an existing ref on the remote nor
begins with refs/, and we are unable to guess a prefix based on the source ref.
error: failed to push some refs to 'ssh://[redacted]/tmp/t'

然而,这有效:

$ git push origin stash:refs/ssss
Counting objects: 8, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 485 bytes | 0 bytes/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: error: refusing to create funny ref 'refs/ssss' remotely
To ssh://[redacted]/tmp/t
 ! [remote rejected] stash -> refs/ssss (funny refname)
error: failed to push some refs to 'ssh://[redacted]/tmp/t'

这一次,它在遥控器上创建了一个名为$ git push origin stash:refs/heads/ssss 的新分支。它也可以用于推送到远程标签(ssss)。

藏匿作为分支或标记没有多大意义,但你可以把它像一个那样推送它。一旦你尝试了这个,所有的遥控器就知道你正在发送一些提交对象及其相关的树,blob等,并且它应该存储"最尖端的"在你提供的(完整)名称下提交。 3 这就是为什么你可以推送原始提交ID,例如,在远程上创建一个标签:

refs/tags/tagname

(假设当然提交的ID以$ git push af7ec93:refs/tags/foo 开头)。

关于" stash stack"

的另一个注释

"堆栈"是通过使用af7ec93引用的reflog来创建的。当您编写refs/stash时,它会使用相同的gitrevisions规则来解析提交ID。由于stash@{1}允许您使用解析为有效ID的任何内容,因此您也可以将这些内容推送到远程名称。但你可能不应该这样做;就像git push下最顶级的存储项一样,这些并不像常规提交那样有意义。 (存储条件在内部存储为合并提交,但它们的内容奇怪地打包,并且尝试将它们用作普通提交会产生不太有用的结果。)


1 自从1.8.2左右以来,这在git中确实如此;但是旧版本的git有时会在抓取时跳过更新远程分支,尤其是refs/stash调用git fetch时。

2 如果您咨询gitrevisions,您会发现这也不太准确:它会发现git pullstash 寻找分支名称之前。

3 refs/stash通常会自动构建全名:如果您正在推送git pushmaster,则知道这是分支,因此refs/heads/master在遥控器上创建git push master:newbranch。但是,您可以拼出一个全名,以便在遥控器上创建一个标签。当你推送一个空的本地引用来删除一个remote-ref:refs/heads/newbranch时,这也适用于删除操作。


作为bcmcfc already said,保留大量的藏匿处往往是一个坏主意。我所做的是保留一大堆树枝(除非我真的想把它们保存在一些遥控器上,否则我会避免推动它);这些都有名字,因此更容易管理(但只有一点点)。效率没有区别,因为stashes和branches都只用于包含提交 - 特殊的stash merge提交或普通提交。但是,您可能希望确保git push :refs/tags/delete_me配置为避免推送所有分支,如果您使用分支而不是存储。

答案 1 :(得分:26)

没有。藏匿处是当地的。

$ man git stash

  

如果要记录工作目录和索引的当前状态,但想要返回干净的工作目录,请使用git stash。该命令保存您的本地修改,以恢复工作目录以匹配HEAD提交。

但是,我不会在当地保留太多这些东西。随着时间的推移,你会失去对它们的追踪,它们会变得有些无用。