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

Dun*_*nno 27 git git-stash

我的藏匿堆栈是否被推送到远程仓库?还是完全被忽略了?我只是好奇我是否应该每隔一段时间倾向于放弃一些以节省服务器上的空间.

bcm*_*cfc 30

不是.藏匿处是当地的.

$ man git stash:

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

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


tor*_*rek 29

作为一般规则,没有.如果你愿意,你可以推它.

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

那么什么是参考名称?

大多数情况下,您命名分支引用,例如master,或"远程分支"之类的origin/master.令人困惑的是,是什么混帐所谓的"远程分支"实际上是一个本地实体,而不是一个分支的远程而是一个分支你的下一个特殊的名字库.

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

"远程分支"只是名称以其开头的引用,refs/remotes/然后包含远程名称(通常origin).所以refs/remotes/origin/master是一个"远程分支":当地的实体,一个名称回购,你的Git使用,以保持"里的曲目master是在origin最后一次检查的git与origin".无论何时从/向取/取origin,1 git都会根据它在"那边"看到的内容更新你的名字.origin/branch

标签只是简单的引用refs/tags/.

通常你会遗漏所有这些前缀,只是写下来master表示你的主分支refs/heads/master,origin/master意思refs/remotes/origin/masterv2.3意思refs/tags/v2.3.Git自动计算出哪一个,因为它很明显.精确的规则在gitrevisions中描述.(烦人,git checkout而且git branch并不总是严格遵循gitrevisions规则:当他们知道的东西,就是要一个分支的名字,他们只是承担refs/heads/部分. 其它 Git命令都描述工作,虽然.)

stash脚本使用简单拼写的引用refs/stash.所以你可以通过写作来命名这个参考stash; git会发现它不是分支,也不是远程分支,也不是标记,最终会使用refs/stash来解析名称.2

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

这意味着如果你写了:

$ git push origin stash:ssss
Run Code Online (Sandbox Code Playgroud)

git会找到你的存储(只有一个存储)并尝试将其推送到名为的远程引用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'
Run Code Online (Sandbox Code Playgroud)

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

$ 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'
Run Code Online (Sandbox Code Playgroud)

但是,这有效:

$ git push origin stash:refs/heads/ssss
Run Code Online (Sandbox Code Playgroud)

这一次,它在遥控器上创建了一个名为的新分支ssss.它也可以用于推送到远程标签().refs/tags/tagname

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

$ git push af7ec93:refs/tags/foo
Run Code Online (Sandbox Code Playgroud)

(假设有一个提交,其ID af7ec93当然是以)开头的.

另一个关于"藏匿堆栈"的说明

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


1从1.8.2开始,这在git中确实如此; 但是旧版本的git有时会在获取时跳过更新远程分支,尤其是在git fetch被调用时git pull.

2如果您咨询gitrevisions,你会看到,这是不太准确之一:它会找到stash作为refs/stash 之前寻找一个分支名称.

3git push通常自动构建全名:如果你正在推动你的master,refs/heads/master也就是说它知道这是一个分支,那么就在遥控器上git push master:newbranch创建refs/heads/newbranch.但是,您可以拼出一个全名,以便在遥控器上创建一个标签.例如,当您按空的本地引用以删除remote-ref:时git push :refs/tags/delete_me,这也适用于删除操作.


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