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

或者我的选择是:

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


当前回答

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

虽然目前投票最多的答案应该是有效的,但我不喜欢它创建了一堆临时分支,它需要手动检查stash提交并将其保存为一个stash,这可能会导致像这个评论提到的问题,并导致重复的On(无分支):On测试:。肯定有更好的办法!

因此,虽然你不能直接推送存储,但一个stash只是一个提交(实际上是两次提交),并且根据git推送手册页,你可以推送提交:

<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的手册页,在那里我发现了这个:

创建 创建一个stash(这是一个常规提交对象)并返回其对象名称,而不将其存储在ref名称空间中的任何位置。这对脚本很有用。这可能不是你想要使用的命令;参见上面的“保存”。 商店 将通过git stash create(这是一个悬空合并提交)创建的给定stash存储在stash ref中,更新stash reflog。这对脚本很有用。这可能不是你想要使用的命令;参见上面的“保存”。

因为我已经有了提交,所以存储听起来就是我想要的。所以我可以这样做:

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。fetch命令也可以安全地重复执行。虽然存储库将跳过存储与最新存储库相同的存储库,但它不能防止旧存储库的副本。不过,这可以解决,就像我在git-rstash脚本中所做的那样,请参见下面。


为了完成,你还可以轻松地推送所有的存储(使用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

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

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

我已经创建了一个bash脚本,可以作为子命令调用(例如git rstash push 0),所以我不需要记住这一切。Git-rstash可以在这里找到。

其他回答

我将简单地创建一个新的stash分支,并在不需要该分支时删除该分支。

在机器1上:

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

在机器2上:

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 branch when not needed from local
git push -d origin stash-branch // Delete branch when not needed from remote

我将混合上面的2个答案,只是为了分享我是如何用zsh shell来做的。

非常感谢@Scott Weldon和@sehe对这个问题的回答!我从他们身上学到了很多!!由于这个问题,我还广泛地学习了shell脚本编写!


一个关于代码功能的非常简单的解释

请参考以上的答案链接,以更好地(推荐)理解:

代码的作用:

Stash goes from Machine 1 --> to remote --> to Machine 2

机器1:

1. Push the stash to remote (using for loop for multiple stashes)

机器2:

1. Check stash(es) in remote. (This is just to check whether there are  previous stashes in remote. If there are, you must delete them if you don't want them in you stash list. Command for deleting remote stashes are given in bonus)
2. Fetch the stash(es) to a local ref folder named "ref/stashes" in your .git folder in your local repository. (Its like downloading the stashes on your PC)
3. Convert the fetched stash(es) to proper data. (Its like extracting or installing the stashes on your PC)

奖金:

1. Check stash(es) in remote
2. Delete stash(es) from remote 

代码:

在机器1上:

1. git push origin $(for sha in $(git rev-list -g stash); do echo $sha:"refs/stashes/$(git rev-parse --short $sha)"; done)

在机器2上:

1. git ls-remote
2. git fetch origin "refs/stashes/*":"refs/stashes/*"
3. for sha in $(git rev-list --no-walk --reverse --glob='refs/stashes/*'); do git stash store --message "$(git show --no-patch --format=format:%s $sha)" $sha; done

奖金:

1. git ls-remote
2. git push origin :refs/stashes/<stashFile-1> :refs/stashes/<stashFile-2>

以上代码用于多个存储,也可以用于一个存储。只需确保您的远程ref/stashes文件夹只有您在本地回购中想要的存储。

请参阅下面两个一行程序,我成功地使用它们将所有存储从多个源回购推到远程主机上的单个目标回购。

这是基于sehe的原始答案,结合Alan Krueger的评论,Keith Robertson的评论,Sebastian Schrader的评论,并添加远程主机:dir。

# on each src_host:repo_dir
git send-pack <dst_host>:<dst_repo_dir> $(for sha in $(git rev-list -g stash); do echo $sha:refs/heads/stash_$sha; done)

# on the dst_host:repo_dir
for a in $(git rev-list --no-walk --glob='refs/heads/stash_*' | tac); do git checkout $a && git reset HEAD^ && git update-ref --create-reflog -m "$(git show -s --format=%B $a)" refs/stash $a && git restore . && git branch -D stash_$a; done; git checkout master

(我还没有足够的声望点,否则我会在sehe的原始答案下添加一条评论)

我有点晚了,但我相信我找到了一些适合我的东西,如果你的情况相同或相似,它可能也适用于你。

我在它自己的分支里做一个特性。分支不会合并到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.

从git-reset (1): "——mixed:重置索引,但不重置工作树(即,更改的文件被保留,但不标记为提交)[…]"

因此,您最终将对文件进行更改,但不需要提交到master,也不需要存储。

然而,这将需要你git重置——在你做了“[非提交]”的存储库中硬HEAD^,因为那个提交是垃圾。

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

虽然目前投票最多的答案应该是有效的,但我不喜欢它创建了一堆临时分支,它需要手动检查stash提交并将其保存为一个stash,这可能会导致像这个评论提到的问题,并导致重复的On(无分支):On测试:。肯定有更好的办法!

因此,虽然你不能直接推送存储,但一个stash只是一个提交(实际上是两次提交),并且根据git推送手册页,你可以推送提交:

<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的手册页,在那里我发现了这个:

创建 创建一个stash(这是一个常规提交对象)并返回其对象名称,而不将其存储在ref名称空间中的任何位置。这对脚本很有用。这可能不是你想要使用的命令;参见上面的“保存”。 商店 将通过git stash create(这是一个悬空合并提交)创建的给定stash存储在stash ref中,更新stash reflog。这对脚本很有用。这可能不是你想要使用的命令;参见上面的“保存”。

因为我已经有了提交,所以存储听起来就是我想要的。所以我可以这样做:

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。fetch命令也可以安全地重复执行。虽然存储库将跳过存储与最新存储库相同的存储库,但它不能防止旧存储库的副本。不过,这可以解决,就像我在git-rstash脚本中所做的那样,请参见下面。


为了完成,你还可以轻松地推送所有的存储(使用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

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

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

我已经创建了一个bash脚本,可以作为子命令调用(例如git rstash push 0),所以我不需要记住这一切。Git-rstash可以在这里找到。