我想做什么:在我的(ssh可远程访问的)大学机器上,我处理了一个项目,我已将其置于git源代码控制下(git init
,然后{{1}每次改变后,一切正常)。现在我想在家里的私人机器上处理该项目。应该很简单,因为git是一个分布式的vcs,对吗?
我读了git tutorial,建议在大学做git commit -a
以便在家里完成更改。这是行不通的,因为我家里的机器无法远程访问。所以我以为我会在家里做git pull
。这很有效,但它很复杂(之后需要大学git push
等),since non-bare repositories are not designed for pushing。
问题1:是否有一种比在我的设置中添加额外的裸存储库更简单的方法(这意味着我有:(1)“主”裸存储库,(2)大学工作副本,(3)家庭工作副本)?
< Rant>如果我真的需要这个设置,我可以留在SVN。< / Rant>
问题2:如果确实需要这种设置,我该如何创建裸存储库(我猜是git reset
)和使其成为“主”存储库,即告诉工作副本git clone --bare
应该那里。
PS:我知道有一个后置接收挂钩可以让你进入非裸存储库。我试过了,但由于大学机器上的git版本相当陈旧(1.5.5.6)并且错过了钩子使用的一些命令,因此效果不佳。更新不是一种选择,我更喜欢没有第三方脚本的解决方案。
答案 0 :(得分:13)
你真的不应该推到已检出的分支,因为它有效地从远程工作副本下拉出地毯。如果由于分支头移动或者reset --hard
还会丢失本地更改而修改工作树,则很难解决。
最简单的方法是推送到另一个分支。然后,当您有权访问远程计算机并需要对其进行处理时,可以将其合并到工作副本的checkout out分支(或将本地分支重新绑定到其上)。
离家出走:
git push origin HEAD:from-home
来自'工作':
git merge from-home
您可以将配置设置为默认为特定的push refspec。
e.g。
git config remote.origin.push +master:from-home
裸存储库通常更自然。您可以从现有存储库中克隆它,或者我通常会执行的操作,初始化新存储库并从现有存储库中推送我想要的主分支。
更好的是,如果你要在每个位置使用工作副本,就是使用这个技巧直接修改遥控器的遥控器,而不是一个特殊重命名的分支。
因此,在原点上,创建一个名为“home”的遥控器 - 由于您的网络配置,您显然无法从中获取。那没关系。
在家中,告诉它,“当我推送到原点时,让它更新原点的远程命名主页:
git config remote.origin.push +master:home/master
现在,事情变得非常光滑。在家里,运行git push origin
,然后转到原点,然后运行git status
或git branch -a -v
- 您将看到的内容如下:“主人在3个提交后可以支持家庭/主人快进。“
换句话说,使用home将更改推送到原始远程命名的home,在功能上与使用origin从家中拉出相同。
这里的一个缺点是,当您在家中创建其他分支时,您需要不断执行新的git配置设置。这是您为网络设置支付的开销。值得庆幸的是,它很简单,只有每个分支创建一次。
答案 1 :(得分:1)
This question总结了我尝试同步两份工作副本的经验。最终我认为拥有一个裸存储库更自然,更简单。它不是SVN意义上的“主要”存储库 - 例如,你可以在uni和一个在家中拥有一个存储库,并在它们之间推送它。
有人可能会发布正确的方法来将裸存储库设置为推送目标,但是如果不查看文档,我只需删除工作副本并再次从裸存储库中克隆它。
答案 2 :(得分:1)
我通过使用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"