【问题标题】:git: Simple solution for pushing between working copiesgit:在工作副本之间推送的简单解决方案
【发布时间】:2010-01-24 13:08:30
【问题描述】:

我想做的事: 在我的(ssh 远程访问)大学机器上,我从事一个项目,我已将其置于 git 源代码控制之下(git init,然后在每次更改后 git commit -a ,一切正常)。现在我想在家里的私人机器上处理那个项目。应该很简单,因为 git 是分布式 vcs,对吧?

我阅读了git tutorial,它建议在大学做一个git pull,以便在家完成更改。那是行不通的,因为我家中的机器无法远程访问。所以我想我会在家里做一个git push。这行得通,但它很复杂(在大学之后需要git reset,等等),since non-bare repositories are not designed for pushing

问题 1: 有没有比在我的设置中添加额外的裸存储库更简单的方法(这意味着我有:(1)“主要”裸存储库,(2)大学工作副本,(3)家庭工作副本)?
如果我真的需要那个设置,我可以留在 SVN。

问题 2: 如果确实需要该设置,我如何创建该裸存储库(我猜是git clone --bare)并将其设为“主”存储库 ,即告诉工作副本git push 应该去那里

PS: 我知道有一个 post-receive 钩子可以让你推入非裸仓库。我试过了,但效果不好,因为大学机器上的 git 版本很旧(1.5.5.6)并且错过了钩子使用的一些命令。更新不是一种选择,无论如何我更喜欢没有第三方脚本的解决方案。

【问题讨论】:

  • @rant: 但是如果你忘记更新一次,svn 就不能变基。
  • 在类似的场景中,我使用了非裸仓库(即使不推荐),因为它仍然比中间仓库更容易,将 receive.denyCurrentBranch=warn 添加到推送到回购,直到现在都没有问题。对git reset --hard 的需求起初感觉有点奇怪,但考虑到这些选项,它仍然是我最好的工作流程。确保在推入之前已提取工作副本更改。还有什么,即是什么意思?

标签: git repository dvcs git-push


【解决方案1】:

你真的不应该推送到签出的分支,因为它有效地从远程工作副本下拉扯地毯。然后很难确定是否因为分支头已移动而修改了工作树,或者是否还有可能被 reset --hard 丢失的本地更改。

最简单的做法是推送到不同的分支。然后,当您可以访问远程计算机并需要对其进行处理时,您可以将其合并到工作副本的结帐分支中(或将本地分支重新定位到该分支上)。

从家里:

git push origin HEAD:from-home

来自“工作”:

git merge from-home

您可以将配置设置为默认为特定的推送参考规范。

例如

git config remote.origin.push +master:from-home

裸存储库通常更自然。您可以从现有存储库克隆它,或者像我通常做的那样,初始化一个新存储库并将我想要的主分支从现有存储库推送到它。

如果您要在每个位置使用工作副本,更好的是使用此技巧直接修改遥控器的遥控器,而不是专门重命名的分支。

因此,在 origin 上,创建一个名为“home”的远程 - 由于您的网络配置,您显然无法从中获取。没关系。

在 home 上,告诉它,“当我推送到 origin 时,让它更新 origin 的远程 home

git config remote.origin.push +master:home/master

现在,事情变得非常顺利。在家里,运行git push origin,然后转到origin,然后运行git statusgit branch -a -v——你会看到类似:“master 落后 home/master 3 次提交,可以快速转发。”

换句话说,使用 home 将更改推送到 origin 的远程命名 home,在功能上与使用 origin 从 home 拉取相同。

这里的一个缺点是,当您在家中创建额外的分支时,您需要不断地进行新的 git 配置设置。这是您为网络设置支付的开销。值得庆幸的是,它很简单,每个分支创建只发生一次。

【讨论】:

  • 另外,如果你的大学账户上有“裸”repo,你可以使用 git-clone 的 --local--reference 标志来消除多个克隆的资源消耗。
  • --local 对于本地克隆是自动的。
  • 很好的答案,@Charles。我进一步扩展了它,在发现你可以使用它来推送到一个命名的 remote 引用后,它更加出色和透明。
【解决方案2】:
  1. This question 总结了我尝试同步两个工作副本的经验。最终我认为拥有一个裸存储库更加自然和简单。它不是 SVN 意义上的“主”存储库 - 例如,您可以在大学拥有一个,在家里拥有一个,并在它们之间进行推拉。

  2. 可能有人会发布将裸存储库设置为推送目标的正确方法,但不查看文档,我会简单地删除工作副本并再次从裸存储库克隆它。

【讨论】:

    【解决方案3】:

    我通过使用git-bundle 解决了这个问题。在我的笔记本电脑上,我使用git pull 来获取上游更改。正如预期的那样,这适用于 ssh。然后,我执行git bundle 将我的本地更改放入一个包中,将包文件复制到远程服务器,然后ssh 到服务器并从包文件中执行git pull

    来自文档:

    有些工作流要求一台机器上的一个或多个开发分支复制到另一台机器上,但两台机器不能直接连接,因此不能使用交互式 Git 协议(git、ssh、http)。此命令提供对 git fetch 和 git pull 的支持,通过将对象和引用打包到原始计算机的存档中,然后在通过某种方式(例如,通过sneakernet)移动存档后使用 git fetch 和 git pull 将它们导入另一个存储库.由于存储库之间不存在直接连接,因此用户必须为目标存储库持有的捆绑包指定基础:捆绑包假定基础中的所有对象都已在目标存储库中。

    我的存储库足够小,我可以使用 --all 将整个 git 树添加到包中。但是,如果您的存储库更大,您可能只想将最近的更改添加到包中(例如,使用 --since=10.days master 来获取最近 10 天)。文档有更多示例。

    这是我的代码。在这种情况下,笔记本电脑和服务器的存储库都在同一个地方:~/src/(这是一个非裸存储库,即工作副本)。 ~/tmp 目录同时存在于服务器和笔记本电脑上。

    TMPDIR=~/tmp
    cd ~/src
    git pull $server:~/src/
    git bundle create $TMPDIR/bundle --all
    rsync $TMPDIR/bundle $server:$TMPDIR
    ssh $server "cd ~/src;git pull $TMPDIR/bundle"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-06
      • 1970-01-01
      • 2016-10-30
      • 1970-01-01
      • 2017-08-17
      • 2010-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多