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

时间:2009-10-11 10:36:08

标签: git git-stash

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

或者是我的选择:

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

12 个答案:

答案 0 :(得分:70)

注意:我刚刚用24小时的git-fu改写了这个答案:) 在我的贝壳历史中,整个shebang现在是三个单行。但是,为了您的方便,我已经将它们解开了。

这样,我希望你能看到我做的事情,而不是盲目地复制/粘贴东西。


这是一步一步的。

假设〜/ OLDREPO中的来源包含藏匿处。创建一个不含stashes的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@{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 :(得分:59)

无法通过fetch获取它,镜像refspec为fetch = +refs/*:refs/*,即使存储为refs/stash,也不会被发送。明确的refs/stash:refs/stash也没有效果!

无论如何它只会令人困惑,因为那不会取得所有的藏匿处,只会取出最新的藏匿处; stashes列表是ref refs/stashes reflog

答案 2 :(得分:30)

我参加派对的时间有点晚了,但我相信我找到了一些对我有用的东西,如果你的情况相同或类似,也可能适合你。

我正在开发自己的分支中的一个功能。分支机构没有合并为主机,直到完成或我已经提交了我觉得很舒服的向公众展示。因此,当我想将非分段更改传输到另一台计算机时,我所做的是:

  • 使用提交消息进行提交 比如“[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^进行“[非提交]”,因为该提交是垃圾。

答案 3 :(得分:18)

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

对我来说有用的是提交我正在进行的代码(在我正在单独工作的分支中)。当我到达我的另一台计算机时,请执行pull,然后使用以下命令撤消提交:

git reset --soft HEAD^

继续按原样工作,在那里进行所有正在进行的更改,未提交,并且不进行更改。

希望它有所帮助。

答案 4 :(得分:12)

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

这也解释了here

答案 5 :(得分:9)

我会采用第二种方法,但不知道为什么你不能将它提交给master / featured分支。也可以做樱桃采摘。

答案 6 :(得分:4)

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

尽管currently top-upvoted answer应该可以工作,但我不喜欢它创建一堆临时分支,并且它需要手动检出存储提交并将其保存为存储,这可能导致问题类似于this comment mentioned,并导致重复的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的手册页,发现了这一点:

创建
创建一个存储区(这是一个常规的提交对象)并返回其对象名称,而不将其存储在ref名称空间中的任何位置。旨在对脚本有用。它可能不是您要使用的命令;请参阅上方的“保存”。

商店
将通过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-datefetch命令也可以安全地重复运行。尽管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 can be found here.

答案 7 :(得分:3)

AFAIK隐藏的整个想法是隐藏 local 地毯下不那么重要的东西。没有人应该知道你最喜欢的废话;-)唯一的“但是”是:但如果我在几个工作站上开发?然后scp更好。

答案 8 :(得分:0)

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

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_

答案 9 :(得分: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

答案 10 :(得分:0)

以其他答案为基础,如果您在 GitHub 等平台上有一个公共存储库,但不希望将正在进行的更改公开,您可以创建一个私有存储库并将其添加为远程存储库。

要同步更改:提交、推送到私有遥控器上的分支、拉动目标设备,然后执行软/混合重置。

答案 11 :(得分:-5)

就像这个人一样使用Dropbox。这样您就不必担心推送存储,因为所有代码都会被备份。

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