git stash stack 是否推送到远程仓库?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23952575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 10:03:56  来源:igfitidea点击:

Is git stash stack pushed to the remote repo?

gitgit-stash

提问by Dunno

Is my stashstack pushed to the remote repo? Or is it completely ignored?

我的stash堆栈被推到了remote repo? 或者它被完全忽略了?

I'm just curious if I should tend to it every once in a while to drop some of it to save space on the server.

我只是很好奇我是否应该每隔一段时间倾向于它以删除其中的一些以节省服务器上的空间。

回答by bcmcfc

No. Stashes are local.

不。Stash 是本地的。

$ man git stash:

$ man git stash

Use git stash when you want to record the current state of the working directory and the index, but want to go back to a clean working directory. The command saves your local modifications away reverts the working directory to match the HEAD commit.

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

I wouldn't keep too many of them around locally though. You'll lose track of them over time and they'll become somewhat useless.

不过,我不会在本地保留太多它们。随着时间的推移,你会忘记它们,它们会变得有些无用。

回答by torek

As a general rule, no. You couldpush it though, if you wanted.

一般来说,没有。如果你愿意,你可以推动它。

Here's the thing about push (and, for that matter, fetch): these work based on "refspecs", where you name a local reference name—or, for push and specific cases, a raw commit-ID—and then also a remote reference name.

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

So what the heck is a reference name?

那么参考名称到底是什么呢?

Most of the time, you name a branch reference, such as master, or a "remote branch" like origin/master. Confusingly, what git calls a "remote branch" is actually a local entity, not a branch ona remote but rather a branch in yourrepository under a special name.

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

A branch is really just a reference whose name starts with refs/heads/. That's really almost all a branch is. (There's one other special thing about a branch: branches automatically movewhen you make new commits in them. That is, if you're on your masterbranch and you make a new commit, git updates refs/heads/masterto point to the new commit.)

分支实际上只是名称以refs/heads/. 这几乎是一个分支的全部内容。(关于分支还有另外一件特别的事情:当你在其中进行新的提交时,分支会自动移动。也就是说,如果你在你的master分支上并且你做了一个新的提交,git updatesrefs/heads/master指向新的提交。)

A "remote branch" is just a reference whose name starts with refs/remotes/and then contains the name of the remote (usually origin). So refs/remotes/origin/masteris a "remote branch": a local entity, a name in yourrepo, that your git uses to keep track of "where masterwas on originlast time git checked in with origin". Whenever you fetch or push from/to origin,1git updates your origin/branchnames based on what it sees "over there".

“远程分支”只是一个引用,其名称以 开头,refs/remotes/然后包含远程的名称(通常是origin)。所以refs/remotes/origin/master是一个“远程分支”:当地的实体,一个名称回购,你的Git使用跟踪“里的master是在origin最后一次混帐与检查origin”。每当您从/向 fetch 或 push 时origin1git 都会根据它在“那边”看到的内容更新您的姓名。origin/branch

Tags are simply references that start with refs/tags/.

标签只是以 开头的引用refs/tags/

Normally you leave out all these prefixes and just write masterto mean your master branch in refs/heads/master, origin/masterto mean refs/remotes/origin/master, and v2.3to mean refs/tags/v2.3. Git figures out which one automatically, since it's obvious. The precise rules are described in gitrevisions. (Annoyingly, git checkoutand git branchdon't always exactly follow the gitrevisionsrules: when they know something is meant to be a branch name they just assumethe refs/heads/part. Othergit commands do work as described, though.)

通常,您会省略所有这些前缀,而只写master表示您的 master 分支 in refs/heads/masterorigin/mastermeanrefs/remotes/origin/masterv2.3mean refs/tags/v2.3。Git 会自动找出哪一个,因为这很明显。gitrevisions中描述了精确的规则。(烦人,git checkout而且git branch并不总是严格遵循gitrevisions规则:当他们知道的东西,就是要一个分支的名字,他们只是承担refs/heads/部分。 其它Git命令做的工作描述,虽然)。

The stashscript uses a reference that is simply spelled refs/stash. So you can name this reference by writing stash; git will find that it's not a branch, nor a remote branch, nor a tag, and will finally resort to using refs/stashto resolve the name.2

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

... which means, what?

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

This means that if you wrote:

这意味着如果你写:

$ git push origin stash:ssss

git would find your stash (just the one single stash) and attempt to push it to a remote reference named ssss. This would most likely fail; here's what happened when I tried it:

git 会找到你的 stash(只是一个单独的 stash)并尝试将它推送到一个名为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'

Just for fun, I tried the next command, and got a different error:

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

$ 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'

However, this worked:

但是,这有效:

$ git push origin stash:refs/heads/ssss

This time, it created a new branch on the remote, named ssss. It would also work to push to a remote tag (refs/tags/tagname).

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

A stash does not make much sense as either a branch or a tag, but you can push it as if it were one. All the remote knows, once you try this, is that you're sending some commit object(s) and their associated trees, blobs, etc., and that it should store the "tip-most" commit under the (full) name you supply.3This is why you can push raw commit-IDs, e.g., to create a tag on the remote:

stash 作为分支或标签都没有多大意义,但您可以将其作为一个推送。一旦您尝试此操作,所有遥控器都知道您正在发送一些提交对象及其关联的树、blob 等,并且它应该在(完整)名称下存储“最尖端”提交你供应。3这就是为什么您可以推送原始提交 ID,例如,在远程创建标签:

$ git push af7ec93:refs/tags/foo

(assuming there's a commit whose ID starts with af7ec93of course).

(假设有一个 ID 以af7ec93当然开头的提交)。

One other note about the "stash stack"

关于“存储堆栈”的另一条说明

The "stack" is made by using the reflog for the refs/stashreference. When you write stash@{1}, this uses the same gitrevisionsrules to resolve to a commit-ID. Since git pushallows you to use anything that resolves to a valid ID, you could push these to remote names as well. But you probably shouldn't; just like the top-most stash item under refs/stash, these do not make a lot of sense as regular commits. (Stashes are stored internally as merge commits, but their contents are oddly packaged, and trying to use them as ordinary commits produces not-so-useful results.)

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



1This is literally true in git since 1.8.2 or so; but older versions of git sometimes skip updating a remote-branch when fetching, particularly when git fetchis invoked by git pull.

1从 1.8.2 左右开始,这在 git 中确实如此;但是旧版本的 git 有时会在获取时跳过更新远程分支,特别是当git fetchgit pull.

2If you consult gitrevisions, you'll see that this is not quite accurate either: it will find stashas refs/stashbeforelooking for a branch name.

2如果您查阅gitrevisions,您会发现这也不太准确:它会stashrefs/stash以前一样查找分支名称。

3git pushusually builds the full name automatically: if you're pushing your master, which is refs/heads/master, it knows that this is a branch, so git push master:newbranchcreates refs/heads/newbranchon the remote. However, you can spell out a full name, so as to create a tag on the remote instead, for instance. This also works for deletion operations, when you push an empty local reference to delete a remote-ref: git push :refs/tags/delete_me, for example.

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



As bcmcfc already said, keeping a large pile of stashes tends to be a bad idea. What I do instead is keep a large pile of branches (which I avoid pushing unless I really want to save them on some remote(s)); these have names, and hence are a little more manageable (but only a little). There's no difference in efficiency, since stashes and branches both merely serve to contain commits—either the special stash merge commits, or ordinary commits. However, you may want to make sure your push.defaultis configured to avoid pushing all your branches, if you use branches instead of stashes.

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