是否可以将 git stash 推送到远程存储库?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1550378/
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
Is it possible to push a git stash to a remote repository?
提问by Andrew Grimm
In git, is it possible to create a stash, push the stash to a remote repository, retrieve the stash on another computer, and apply the stash?
在 git 中,是否可以创建存储、将存储推送到远程存储库、在另一台计算机上检索存储并应用存储?
Or are my options:
或者是我的选择:
- Create a patch and copy the patch to the other computer, or
- Create a minor branch and commit the incomplete work to that branch?
- 创建补丁并将补丁复制到另一台计算机,或
- 创建一个小分支并将未完成的工作提交到该分支?
采纳答案by u0b34a0f6ae
It's not possible to get it via fetch or so, the mirror refspec is fetch = +refs/*:refs/*
, and even though stash is refs/stash
it doesn't get sent. An explicit refs/stash:refs/stash
has no effect either!
不可能通过 fetch 左右获取它,镜像 refspec 是fetch = +refs/*:refs/*
,即使 stashrefs/stash
也不会发送。显式refs/stash:refs/stash
也没有效果!
It would only be confusing anyway since that wouldn't fetch all stashes, only the latest one; the list of stashes is the reflogof the ref refs/stashes
.
无论如何它只会令人困惑,因为这不会获取所有隐藏内容,只会获取最新的隐藏内容;stash 列表是ref的reflogrefs/stashes
。
回答by sehe
Note:I've just rewritten this answer with 24 hours more git-fu under my belt :) In my shell history, the whole shebang is now three one-liners. However, I've uncondensed them for your convenience.
注意:我刚刚用 24 小时以上的 git-fu 重写了这个答案:) 在我的 shell 历史中,整个 shebang 现在是三个单行。但是,为了您的方便,我已将它们浓缩。
This way, I hope you will be able to see how I did things, instead of just having to blindly copy/paste stuff.
这样,我希望你能够看到我是如何做的,而不是盲目地复制/粘贴东西。
Here is step by step.
这是一步一步。
Assume is source in ~/OLDREPO containing stashes. Create a TEST clone containing no stashes:
假设是 ~/OLDREPO 中包含隐藏的源。创建一个不包含 stashes 的 TEST 克隆:
cd ~/OLDREPO
git clone . /tmp/TEST
Push all the stashes as temp branches:
将所有隐藏作为临时分支推送:
git send-pack /tmp/TEST $(for sha in $(git rev-list -g stash); \
do echo $sha:refs/heads/stash_$sha; done)
Loop on the receiving end to transform back into stashes:
在接收端循环以转换回 stash:
cd /tmp/TEST/
for a in $(git rev-list --no-walk --glob='refs/heads/stash_*');
do
git checkout $a &&
git reset HEAD^ &&
git stash save "$(git log --format='%s' -1 HEAD@{1})"
done
Cleanup your temporary branches if you will
如果您愿意,请清理您的临时分支
git branch -D $(git branch|cut -c3-|grep ^stash_)
Do a git stash list and you will something like this:
做一个 git stash list,你会是这样的:
stash@{0}: On (no branch): On testing: openmp import
stash@{1}: On (no branch): On testing: zfsrc
stash@{2}: On (no branch): WIP on sehe: 7006283 fixed wrong path to binary in debianized init script (reported as part of issue
stash@{3}: On (no branch): WIP on debian-collab: c5c8037 zfs_pool_alert should be installed by default
stash@{4}: On (no branch): WIP on xattrs: 3972694 removed braindead leftover -O0 flag
stash@{5}: On (no branch): WIP on testing: 3972694 removed braindead leftover -O0 flag
stash@{6}: On (no branch): WIP on testing: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{7}: On (no branch): WIP on xattrs: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{8}: On (no branch): WIP on testing: 28716d4 fixed implicit declaration of stat64
stash@{9}: On (no branch): WIP on emmanuel: bee6660 avoid unrelated changes
On the original repository, the same looked like
在原始存储库上,看起来像
stash@{0}: WIP on emmanuel: bee6660 avoid unrelated changes
stash@{1}: WIP on testing: 28716d4 fixed implicit declaration of stat64
stash@{2}: WIP on xattrs: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{3}: WIP on testing: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{4}: WIP on testing: 3972694 removed braindead leftover -O0 flag
stash@{5}: WIP on xattrs: 3972694 removed braindead leftover -O0 flag
stash@{6}: WIP on debian-collab: c5c8037 zfs_pool_alert should be installed by default
stash@{7}: WIP on sehe: 7006283 fixed wrong path to binary in debianized init script (reported as part of issue #57)
stash@{8}: On testing: zfsrc
stash@{9}: On testing: openmp import
回答by Victor Zamanian
I'm a little late to the party, but I believe I found something that works for me regarding this and it might for you too if your circumstances are the same or similar.
我参加聚会有点晚了,但我相信我找到了一些对我有用的东西,如果你的情况相同或相似,它也可能对你有用。
I'm working on a feature in its own branch. The branch isn't merged into master and pushed until its finished or I've made commits that I feel comfortable showing to the public. So what I do when I want to transfer non-staged changes to another computer is:
我正在它自己的分支中开发一个功能。该分支不会合并到 master 中并在其完成之前推送,或者我已经提交了我觉得可以向公众展示的提交。因此,当我想将非暂存更改传输到另一台计算机时,我要做的是:
- Make a commit, with a commit message
like "
[non-commit] FOR TRANSFER ONLY
", featuring the content you want transfered. - Login to the other computer.
Then do:
git pull ssh+git://<username>@<domain>/path/to/project/ rb:lb
The URL might differ for you if you access your repository in a different way. This will pull changes from that URL from the remote branch "rb" into the local branch "lb". Note that I have an ssh server running on my own computer, and am able to access the repository that way.
git reset HEAD^
(implies--mixed
)This resets the HEAD to point to the state before the "[non-commit]" commit.
- 使用“
[non-commit] FOR TRANSFER ONLY
”之类的提交消息进行提交,其中包含您要传输的内容。 - 登录到另一台计算机。
然后做:
git pull ssh+git://<username>@<domain>/path/to/project/ rb:lb
如果您以不同的方式访问您的存储库,您的 URL 可能会有所不同。这会将来自远程分支“rb”的该 URL 的更改拉入本地分支“lb”。请注意,我有一个 ssh 服务器在我自己的计算机上运行,并且能够以这种方式访问存储库。
git reset HEAD^
(暗示--mixed
)这会将 HEAD 重置为指向“[非提交]”提交之前的状态。
From git-reset(1):
"--mixed
: Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) [...]"
来自 git-reset(1):“ --mixed
:重置索引但不重置工作树(即,更改的文件被保留但未标记为提交)[...]”
So you will have your changes to the files in the end, but no commits are made to master and no need for a stash.
因此,您最终将对文件进行更改,但不会向 master 提交任何提交,也不需要存储。
This will however require you to git reset --hard HEAD^
in the repository in which you made the "[non-commit]", since that commit is garbage.
然而,这将要求您git reset --hard HEAD^
在您进行“[非提交]”的存储库中,因为该提交是垃圾。
回答by Sir Robert
It's a little late, but this answer might help someone. I wanted to know this because I wanted to be able to push an in-progress feature/bug/whatever and work from the same point on another computer.
有点晚了,但这个答案可能对某人有所帮助。我想知道这一点,因为我希望能够推送正在进行的功能/错误/任何内容,并在另一台计算机上从同一点开始工作。
What works for me is to commit my in-progress code (in a branch that I'm working on alone). When I get to my other computer, do a pull, then undo the commit with:
对我有用的是提交我正在进行的代码(在我独自工作的分支中)。当我到达我的另一台计算机时,执行拉取操作,然后使用以下命令撤消提交:
git reset --soft HEAD^
Continue working as you were, with all your in-progress changes there, uncommitted, and unstaged.
继续按原样工作,所有正在进行的更改都在那里,未提交且未暂存。
Hope it helps.
希望能帮助到你。
回答by Daniel Dubovski
There seems to be a very neat trick to solve this. you can use git diff > file.diff
(and commit the file) , then restore the changes using git apply file.diff
(from anywhere) to achieve the same result.
似乎有一个非常巧妙的技巧可以解决这个问题。您可以使用git diff > file.diff
(并提交文件),然后使用git apply file.diff
(从任何地方)恢复更改以获得相同的结果。
This was explained hereas well.
这也解释here。
回答by Eimantas
I'd go with second approach although no idea why you can't commit it to master/featured branch . It is possible to do cherry-picking too.
我会采用第二种方法,尽管不知道为什么你不能将它提交到 master/featured branch 。也可以采摘樱桃。
回答by argent_smith
AFAIK the whole idea of stash is to hide something not-so-important under the localcarpet. Nobody should know about your favorite crap ;-) The only "but" is: But if I develop on a couple of workstations? Then scp
is way better.
AFAIK stash 的整个想法是在当地的地毯下隐藏一些不那么重要的东西。没有人应该知道你最喜欢的废话 ;-) 唯一的“但是”是:但是如果我在几个工作站上开发?然后scp
就好多了。
回答by blueFast
The following does not work with the stash, but with the uncommitted changes in the working dir. It creates a branch, autocommits all current changes, and pushes to the remote:
以下内容不适用于存储,但适用于工作目录中未提交的更改。它创建一个分支,自动提交所有当前更改,并推送到远程:
commit_and_push_ ( ) {
# This will:
# 1. checkout a new branch stash-XXX
# 2. commit the current changes in that branch
# 3. push the branch to the remote
local locbr=${1:-autostash-XXX}
git checkout -b $locbr
git add .
git commit -a -m "Automatically created commit"
git push origin $locbr
echo "Autocommitted changes in branch $locbr ..."
}
Use like:
像这样使用:
commit_and_push_ my-temp-branch
commit_and_push_
回答by Scott Weldon
The currently accepted answeris technically correct, you can't directly tell Git to push all your stashes to a remote, and then pull everything into your local stashes on another computer.
在目前接受的答案是技术上是正确的,你不能直接通知Git所有的储物箱推到远程,然后拉成的一切另一台计算机上的本地藏匿。
And while the currently top-upvoted answershould work, I didn't like that it creates a bunch of temporary branches, and that it requires manually checking out the stash commit and saving it as a stash, which can lead to issues like this comment mentioned, and leads to a duplicate On (no branch): On testing:
. Surely there must be a better way!
虽然目前最高投票的答案应该有效,但我不喜欢它创建了一堆临时分支,并且它需要手动检查存储提交并将其保存为存储,这可能会导致类似此评论的问题提到,并导致重复On (no branch): On testing:
。当然必须有更好的方法!
So while you can't directly push stashes, a stash is just a commit (actually two commits), and per the git push
man page you can push commits:
因此,虽然您不能直接推送 stash,但 stash 只是一次提交(实际上是两次提交),并且根据git push
手册页您可以推送提交:
The
<src>
is often the name of the branch you would want to push, but it can be any arbitrary "SHA-1 expression"...
该
<src>
往往是你想推分支的名字,但它可以是任意“SHA-1的表达” ...
I chose to push the stashes to refs/stashes/*
so that I wouldn't clutter up my remote with extra branches. So I can do that with:
我选择将 stashes 推到,refs/stashes/*
这样我就不会用额外的树枝弄乱我的遥控器。所以我可以这样做:
git push origin stash@{0}:refs/stashes/$(git rev-parse --short stash@{0})
(The rev-parse
command gets the short hash of the stash, which will be unique for the repo.)
(该rev-parse
命令获取存储的短散列,这对于回购来说是唯一的。)
Next, I need to fetch the stash from the other computer. Git only fetches branches by default, so I need to fetch the stashes specifically:
接下来,我需要从另一台计算机获取存储。Git 默认只获取分支,所以我需要专门获取 stashes:
git fetch origin refs/stashes/*:refs/stashes/*
Now to convert the stash commit back into an actual stash. As mentioned, while I could just check out the stash commit, reset, and stash as usual, I don't like that it requires extra steps, or that it might not maintain the index state for the stash. I was looking online for a way to do that automatically, but my search-fu failed me. Finally I looked through the man page for git stash
, where I found this:
现在将存储提交转换回实际存储。如前所述,虽然我可以像往常一样检查存储提交、重置和存储,但我不喜欢它需要额外的步骤,或者它可能无法维护存储的索引状态。我在网上寻找一种自动执行此操作的方法,但我的搜索功能失败了。最后,我查看了 手册页git stash
,在那里我找到了这个:
create
Create a stash (which is a regular commit object) and return its object name, without storing it anywhere in the ref namespace. This is intended to be useful for scripts. It is probably not the command you want to use; see "save" above.store
Store a given stash created via git stash create (which is a dangling merge commit) in the stash ref, updating the stash reflog. This is intended to be useful for scripts. It is probably not the command you want to use; see "save" above.
create
创建一个 stash(这是一个常规提交对象)并返回其对象名称,而不将其存储在 ref 命名空间中的任何位置。这旨在对脚本有用。它可能不是您要使用的命令;请参阅上面的“保存”。store 将
通过 git stash create(这是一个悬空合并提交)创建的给定 stash 存储在 stash ref 中,更新 stash reflog。这旨在对脚本有用。它可能不是您要使用的命令;请参阅上面的“保存”。
Since I already have the commit, store
sounds like what I want. So I can do:
由于我已经提交了,store
听起来像我想要的。所以我可以这样做:
git stash store --message "$(git show --no-patch --format=format:%s <SHA>)" <SHA>
Replacing <SHA>
with the stash that was just fetched.
替换<SHA>
为刚刚获取的 stash。
(The git show
command gets the commit message from the stash commit, to use as the message for the stash log.)
(该git show
命令从存储提交中获取提交消息,用作存储日志的消息。)
The stash now shows up as normal in my local repo:
存储现在在我的本地存储库中正常显示:
$ git stash list
stash@{0}: On master: temp
...
To clean up the remote, the stashes can be deleted from the remote like so:
要清理遥控器,可以像这样从遥控器中删除隐藏:
git push origin :refs/stashes/<SHA>
This method also has the benefit of being idempotent: if you run the push
command again, it will report Everything up-to-date
. The fetch
command can also be safely run repeatedly. While the stash store
will skip storing the stash if it is the same as the most recent stash, it doesn't prevent duplicates of older stashes. This can be worked around though, as I do in my git-rstash
script, see below.
这种方法还有一个好处是幂等:如果你push
再次运行命令,它会报告Everything up-to-date
. 该fetch
命令也可以安全地重复运行。虽然stash store
如果它与最近的存储相同,将跳过存储存储,但它不会阻止旧存储的重复。不过,这可以解决,就像我在我的git-rstash
脚本中所做的那样,见下文。
For completion, you can also easily push all stashes (with bash):
为了完成,您还可以轻松推送所有存储(使用bash):
for i in $(seq 0 $(expr $(git rev-list --walk-reflogs --count stash) - 1))
do
git push origin stash@{$i}:refs/stashes/$(git rev-parse --short stash@{$i})
done
or import all fetched stashes:
或导入所有获取的隐藏:
for stash in $(ls .git/refs/stashes)
do
git stash store --message "$(git show --no-patch --format=format:%s $stash)" $stash
done
I've created a bashscript that can be called as a subcommand (e.g. git rstash push 0
) so I don't have to remember all this. git-rstash
can be found here.
我创建了一个bash脚本,它可以作为子命令调用(例如git rstash push 0
),所以我不必记住所有这些。 git-rstash
可以在这里找到。
回答by Bhojendra Rauniyar
I would simply create a new stash branch and the remove whenever that branch is not required.
我会简单地创建一个新的存储分支,并在不需要该分支时删除。
git add . // Add work-in-progress job
git checkout -b stash-branch // Create and checkout to stash-branch
git commit -m 'WIP: job description' // Commit message
git push origin stash-branch // Push to remote
git pull origin stash-branch // Pull the stash-branch
git checkout master // Checkout to working branch
git rebase stash-branch // Rebase the stash-branch
git reset --soft // Equivalent to stash!!
git branch -d stash-branch // Delete when not needed from local
git push -d origin stash-branch // Delete when not needed from remote