我的stash
堆栈是否已推送到远程仓库
?还是被完全忽略了?
我只是好奇是否应该偶尔处理一下,将其中的一些内容删除以节省服务器空间。
不行。存储库是本地的。
$ man git stash
:
当您想记录工作目录和索引的当前状态,但希望回到干净的工作目录时,请使用git stash。该命令将保存您的本地修改并还原工作目录以匹配HEAD提交。
不过我不会在本地保留太多这样的内容。随着时间的推移,您会失去对它们的追踪,并且它们变得有些无用。
refs/remotes/
开头,然后包含远程的名称(通常为origin
)。因此,refs/remotes/origin/master
是一个“远程分支”:它是您存储库中的本地实体,是您的git用于跟踪“上一次与origin
检查时master
在哪里”的名称。每当您从/推送到origin
时,1 git会根据其所看到的内容更新您的origin/branch
名称。
标签只是以refs/tags/
开头的引用。master
表示你的主分支在refs/heads/master
中,origin/master
表示refs/remotes/origin/master
,v2.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
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
的新分支。你也可以将其推送到远程标签(refs/tags/tagname
)。虽然存储区不会将stash视为分支或标签,但你可以像推送分支或标签一样进行推送。一旦你尝试这样做,远程只知道你正在发送某些提交对象及其相关的树、blob等,并且应该将“最高”的提交存储在你提供的(完整)名称下。3 这就是为什么你可以推送原始提交ID来在远程创建标签的原因。$ git push af7ec93:refs/tags/foo
假设有一个提交ID以af7ec93
开头。
使用refs/stash
引用的reflog创建了“堆栈”。当您写入stash@{1}
时,这使用相同的gitrevisions规则来解析为提交ID。由于git push
允许您使用任何解析为有效ID的内容,因此您也可以将其推送到远程名称。但是您可能不应该这样做;就像refs/stash
下面最顶部的stash项一样,它们作为常规提交没有太多意义。(Stash存储在内部作为合并提交,但其内容被奇怪地打包,尝试将其用作普通提交会产生不太有用的结果。)
1自从git 1.8.2左右以来,在git中这完全是真实的。但在旧版本的git中,特别是在使用git pull
时,有时会在获取时跳过更新远程分支。
2如果您查询gitrevisions,您会发现这并不完全准确:它会将stash
视为refs/stash
,而不是查找分支名称。
3git push
通常会自动构建完整名称:如果您正在推送master
(即refs/heads/master
),则它知道这是一个分支,因此git push master:newbranch
将在远程创建refs/heads/newbranch
。但是,您也可以拼写完整的名称,以便在远程上创建标签,例如。当您推送空的本地引用以删除远程引用时,此操作也适用于删除操作:git push :refs/tags/delete_me
。
正如bcmcfc已经说过的那样,保留大量的存储往往是一个不好的想法。相反,我会保留大量的分支(除非我真的想在某些远程上保存它们,否则我会避免推送它们);这些分支有名称,因此更易于管理(但仅仅是一点点)。效率上没有区别,因为stashes和branches都仅用于包含提交-无论是特殊的stash合并提交还是普通提交。但是,如果您使用分支而不是stash,则可能希望确保您的push.default
配置为避免推送所有分支。