是否可以将git stash推送到远程存储库?


205

在git中,是否可以创建存储,将存储推到远程存储库,在另一台计算机上检索存储,然后应用存储?

还是我的选择:

  • 创建补丁并将补丁复制到另一台计算机,或者
  • 创建一个次要分支并将未完成的工作提交给该分支?

Answers:


68

不可能通过fetch或类似方式获取它,镜像refspec是fetch = +refs/*:refs/*,即使隐藏,refs/stash它也不会发送。显式refs/stash:refs/stash也不起作用!

无论如何,这只会令人困惑,因为那不会获取所有存储,只有最新存储。存放清单是ref 的reflogrefs/stashes


4
您可以从git远程获取最新存储,但是不能存储到存储中,只能存储到另一个引用中。喜欢的东西git fetch some-remote +refs/stash:refs/remotes/some-remote/stashgit stash apply some-remote/stash。但是您无法获得较旧的存储,因为它们存储在无法获取的reflog中。见stackoverflow.com/questions/2248680/...
sj26

75

注意:我刚刚用24小时的git-fu重写了这个答案:)在我的shell历史中,整个shebang现在是三个单线。但是,为方便起见,我将它们简化了。

这样,我希望您能够看到我的工作方式,而不必盲目地复制/粘贴内容。


这是逐步的。

假定〜/ OLDREPO中包含隐藏项的源。创建一个不包含存储的TEST克隆:

cd ~/OLDREPO
git clone . /tmp/TEST

将所有存储卡推送为临时分支:

git send-pack /tmp/TEST $(for sha in $(git rev-list -g stash); \
    do echo $sha:refs/heads/stash_$sha; done)

在接收端循环以转换回存储:

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

清理临时分支机构

git branch -D $(git branch|cut -c3-|grep ^stash_)

做一个git stash列表,您将像这样:

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

在原始存储库上,看起来像

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

1
我很快就学到了很多东西,我觉得我可能应该在较早的方法中简单地使用许多命令,稍后再尝试。
sehe 2011年

9
这对我来说效果很好,只是我需要一个步骤git add .之前,git stash save ...因为git stash除非已暂存它们,否则它们不会存储新文件。同样,git rev-list ...通过管道传递通过的结果将tac反转存储的顺序,以便它们以相同的顺序出现。
艾伦·克鲁格

1
@sehe出色的剧本!!有两个建议:1)-反转最终的引用列表,以使目标存储库中的存储与原始存储库中的存储相同。2)for使用git branch -D stash_$a(在创建隐藏时清除)结束最终循环,这样,如果出现问题并重试,就不会重新处理已经成功隐藏的提交。
基思·罗伯逊

1
非常感谢您抽出宝贵的时间来说明您所做的事情,而不是“仅发布解决方案”。
Marjan Venema

1
如果更换:该解决方案可进一步提高git stash save "$(git log --format='%s' -1 HEAD@{1})"git update-ref --create-reflog -m "$(git show -s --format=%B $rev)" refs/stash $rev(你原来的藏匿处的消息update-ref是什么git stash save在幕后)。
塞巴斯蒂安·施拉德

31

我参加聚会有点晚了,但是我相信我发现一些对我有用的东西,如果您的情况相同或相似,也可能对您有用。

我正在自己的分支中开发一项功能。该分支不会合并到master中,直到完成为止,或者我做出了让公众感到舒服的提交。因此,当我要将非分段的更改转移到另一台计算机时,我要做的是:

  • 使用诸如“ [non-commit] FOR TRANSFER ONLY”之类的提交消息进行提交,其中包含要传输的内容。
  • 登录到另一台计算机。
  • 然后做:

    git pull ssh+git://<username>@<domain>/path/to/project/ rb:lb

    如果以其他方式访问存储库,则URL可能与您不同。这会将来自该URL的更改从远程分支“ rb”拉入本地分支“ lb”。请注意,我有一台运行在自己计算机上的ssh服务器,并且能够通过这种方式访问​​存储库。

  • git reset HEAD^(暗示--mixed

    这会将HEAD重置为指向“ [non-commit]”提交之前的状态。

来自git-reset(1):“ --mixed:重置索引,但不重置工作树(即,已更改的文件将保留,但未标记为提交)[...]”

这样一来,您最终将对文件进行更改,但无需提交任何内容即可掌握,也不需要存储。

但是,这将需要您git reset --hard HEAD^在进行“ [非提交]”的存储库中,因为该提交是垃圾。


然后要创建一个新的功能分支,然后再将其删除,这会更加肮脏……
Taegost,

我猜@Taegost取决于您的环境。可能是某些CI / CD内容阻止了将分支推到上游的意愿。但是,是的,根据您的喜好,您可能只想创建一个分支来完成同一件事。
Victor Zamanian '19

22

有点晚了,但是这个答案可能会对某人有所帮助。我想知道这一点,因为我希望能够推送正在进行的功能/错误/所有内容,并从另一台计算机上的同一点开始工作。

对我有用的是提交正在进行的代码(在我一个人正在处理的分支中)。当我到达另一台计算机时,请拉一下,然后使用以下命令撤消提交:

git reset --soft HEAD^

继续进行您的工作,并在那里进行所有正在进行的,未提交的,未暂存的更改。

希望能帮助到你。


当我尝试执行此操作时,原始服务器仍会维护未提交的提交。关闭,但对我来说没有雪茄。
rezwits

@rezwits是的,远程保留它,但是很容易从源中删除临时分支。
罗伯特爵士(Sir Robert

事实上,这就是我一直在做的!
rezwits

19

解决这个问题似乎有一个非常巧妙的技巧。您可以使用git diff > file.diff(并提交文件),然后使用git apply file.diff(从任何地方)恢复更改以实现相同的结果。

这里也对此进行了解释。


5
如果您有未跟踪的文件:1. git add。2. git diff HEAD> file.diff
–rickpatty

向自己发送diff信息,完全可以避免回购中的提交/占用空间!(例如:通过Signal桌面应用进行自我注释)或电子邮件。
约翰眉

9

我会用第二种方法,尽管不知道为什么不能将其提交到master / featured branch。也可以采摘樱桃。


27
没有技术原因不承诺要掌握/功能,只是我想说“这不是真正的承诺,它只是保存我的工作,以便可以在另一台机器上使用它”。
安德鲁·格林

4

据我所知,藏匿的整个想法是将一些不太重要的东西藏在当地的地毯下。没有人会知道您最喜欢的废话;-)唯一的“但是”是:但是,如果我在几个工作站上进行开发?那就scp更好了。


9
这个有趣的东西应该发表评论。;-)
Andrew Grimm

2
总git-ssh-newbie在这里,但是你可以在github上使用scp吗?
科恩2012年

不,github的git-ssh前端已编程,因此您永远没有ssh shell /控制台。它只能运行服务器端git进程。
argent_smith 2012年

1
因此,如果您的master分支位于github上,那么scp并不是这种情况的真正选择吗?在这种情况下还有其他建议来转移存储吗?
科恩2012年

1
我试图强调一点是,AFAIK根本无法进行存储区转移。
argent_smith 2012年

2

目前接受的答案技术上讲,是正确的,您不能直接告诉Git将所有存储区推送到远程,然后将所有内容存储到另一台计算机上的本地存储区中。

而且,尽管当前最喜欢的答案应该起作用,但我不喜欢它创建一堆临时分支,并且它不要求手动检出存储提交并将其另存为存储,这可能导致出现此类评论提到,并导致重复On (no branch): On testing:。当然,必须有更好的方法!

因此,虽然您不能直接推送存储,但是存储只是一个提交(实际上是两个提交),并且在git push手册页中,您可以推送提交:

<src>往往是你想推分支的名字,但它可以是任意“SHA-1的表达” ...

我选择将藏匿物推入,refs/stashes/*以免多余的树枝使遥控器杂乱无章。所以我可以这样:

git push origin stash@{0}:refs/stashes/$(git rev-parse --short stash@{0})

(该rev-parse命令获取存储的短哈希,这对于存储库将是唯一的。)

接下来,我需要从另一台计算机上获取存储空间。Git默认只获取分支,因此我需要专门获取存储:

git fetch origin refs/stashes/*:refs/stashes/*

现在将存储提交转换回实际存储。如前所述,尽管我可以像往常一样检查存储的提交,重置和存储,但我不喜欢它需要额外的步骤,或者它可能不会保持存储的索引状态。我当时在网上寻找一种自动执行此操作的方法,但是我的搜索引擎失败了。最后,我在的手册页中进行了查找git stash,发现了以下内容:

创造
创建一个存储(这是一个经常犯的对象),并返回其对象名,而不会有任何将其存储在裁判的命名空间。旨在对脚本有用。它可能不是您要使用的命令;请参阅上方的“保存”。

store将
通过git stash create(是一个悬挂的合并提交)创建的给定stash存储在stash ref中,以更新stash reflog。旨在对脚本有用。它可能不是您要使用的命令;请参阅上方的“保存”。

既然我已经有了提交,store听起来就像我想要的。所以我可以做:

git stash store --message "$(git show --no-patch --format=format:%s <SHA>)" <SHA>

替换<SHA>为刚刚获取的存储。

(该git show命令从隐藏提交获取提交消息,用作隐藏日志的消息。)

现在,该存储区在我的本地存储库中正常显示:

$ git stash list
stash@{0}: On master: temp
...

要清理遥控器,可以从遥控器中删除隐藏项,如下所示:

git push origin :refs/stashes/<SHA>

该方法还具有幂等的优势:如果push再次运行该命令,它将报告Everything up-to-date。该fetch命令也可以安全地重复运行。虽然stash store将跳过存储藏匿如果是一样的最新的藏匿处,它不能阻止年长藏匿的副本。就像我在git-rstash脚本中一样,可以解决此问题,请参见下文。


要完成操作,您还可以轻松推动所有存储 ):

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

或导入所有获取的存储区:

for stash in $(ls .git/refs/stashes)
do
  git stash store --message "$(git show --no-patch --format=format:%s $stash)" $stash
done

我创建了一个 可以称为子命令的脚本(例如git rstash push 0),因此我不必记住所有这些。 git-rstash可以在这里找到。


1

以下内容不适用于存储,但适用于工作目录中未提交的更改。它创建一个分支,自动提交所有当前更改,然后推送到远程:

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 ..."
}

使用方式如下:

commit_and_push_ my-temp-branch
commit_and_push_

0

我只需创建一个新的存储分支,并在不需要该分支时将其删除。

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

-9

像这个家伙一样使用Dropbox。这样,您将不必担心推入存储空间,因为将备份所有代码。

http://blog.sapegin.me/all/github-vs-dropbox


2
在任何人下意识的反应之前,我并不是说要使用Dropbox而不是Github,而是将尚未准备好提交的代码存储在Dropbox中,该代码仍将在本地进行版本控制。
纽约市技术工程师,

4
将所有项目复制到远程云将花费太多时间。
Stav Alfi's
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.