2013-01-17 126 views
5

这是场景。我有两台机器,“桌面”和“笔记本电脑”。如何让两个git存储库保持同步?

在桌面上我做的:

mkdir git_test 
cd git_test 
git init 
dd if=/dev/urandom of=test.img bs=1k count=1000 
git add test.img 
git commit -m "Added first image" 

然后在笔记本电脑,我做的事:

git clone [USER]@desktop:/home/[USER]/git_test  
cd git_test 
dd if=/dev/urandom of=test2.img bs=1k count=1000 
git add test2.img 
git commit -m "Added second image" 

然后我想我的桌面上的混帐回购协议看起来像我的笔记本电脑的混帐回购协议。在笔记本电脑上,我发出以下命令: 混帐推起源主

但后来我得到:

remote: error: refusing to update checked out branch: refs/heads/master 
remote: error: By default, updating the current branch in a non-bare repository 
remote: error: is denied, because it will make the index and work tree inconsistent 
remote: error: with what you pushed, and will require 'git reset --hard' to match 
remote: error: the work tree to HEAD. 
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to 
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into 
remote: error: its current branch; however, this is not recommended unless you 
remote: error: arranged to update its work tree to match what you pushed in some 
remote: error: other way. 
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set 
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'. 

如何保持这两个回购同步?

错误消息似乎暗示git有我想要的功能,但出于某种原因,它似乎是一个更高级的工作流程。我听到有人曾经说过,你不能推到你现在所在的分支,有人能说这是一个可能的解决方案吗?我对这种性质的解决方案没有任何问题,例如,我可以在我的笔记本电脑上的某个分支上工作,并在我的桌面上处理另一个分支上的问题,然后以某种方式同步它们,使它们完全相同。

请注意以下事项!

  • 我不想使用集中式回购,像github上,有几个原因。首先是安全。第二个是简单。第三是由于情况我不会进入这里,我不能指望有一个互联网连接到一些远程服务器,我只有我的两台机器通过局域网连接。最后,我想学习如何按照我在这里所要求的方式来做事,以获得特定的知识。

  • 我也不想使用裸回购,因为裸回购在根目录中有一堆垃圾。这是丑陋和混乱。我从颠覆转向git的全部原因是,git看起来像是一个更清洁,分散的解决方案。另外,我还有一些非技术人员会在桌面的根目录中工作,他们会被这个问题困惑不解。 git的美妙之处在于(我认为)所有东西隐藏在.git文件夹中。编辑:显然,我不清楚这一点。想象一下,我有一个“Documents”文件夹,其中包含以下子文件夹:mydata1和mydata2。这不是一个人为的例子,这正是我想要处理的问题。 mydata1应该包含“test.img”,只有这个文件,而是它现在有:

    分支 配置 描述 HEAD 钩 信息 对象 裁判

我希望能够只需cd到mydata1并开始编辑文件,但是我必须尝试通过分支机构cd,或者甚至只是为了完成工作。并且对于这种类型的目录结构,每个子文件夹在“文档”中是不可行的。请不要告诉我这样做。请回答这个问题。谢谢。

这两点是整个原因我在这里发布这个问题。请只回答如果你有这个问题的答案。 :) 谢谢!!

+0

我指的是“cruft”,如下所示:“分支配置说明HEAD挂钩信息对象引用”我只想/ home/[User]/git_repo只包含我正在使用的文件。另外:.git文件夹被隐藏。 –

+0

您可以隐藏回购。 – nobar

回答

10

这样做的一种方法是拉,而不是推。在第一台机器上安装完两台机器之后:

git remote add origin [USER]@laptop:/home/[USER]/git_test 
git pull # Complains about untracked branch while adding the branch you want to track 
git branch --set-upstream master origin/master 
git pull 

现在您可以从任一机器提交提交。如果你想推动,我不知道如何去分散设置。

+0

拉绝对适用于我的工作流程,只要我不必处理裸回购或集中回购。感谢您的澄清。我会测试这个工作流程并回报。谢谢! –

+1

如果机器甚至是轻微的物理分离,一种可能性不大 - 创建一个类似于别名的bash别名git_push =“ssh remotemachine'cd git_test; git pull'”' – cjc343

+0

这绝对是一种可行的方式。考虑这两个回购是属于你还是其他人。你不会希望那个人把他的东西扔进你的仓库,他不希望你把你的东西扔进他的仓库。对于推动这项新工作的另一个故事,可能在另一个分支上,而不是推动它。 –

2

我可能会错过为什么你不想使用裸回购,我相信拉唯一的解决方案应该可以正常工作,但我也相信,“cruft”仍然可以隐藏在你工作时的愿望与光秃秃的回购。

在桌面上,如果您:

mkdir git_test 
git init --bare git_test 

然后:

git clone bare_repo_directory new_location 

可以推及一般拉至裸露的回购协议(引用它作为默认原点)从克隆,没有人会需要处理它包含的额外内容;克隆将只有.git目录。

推你需要运行:

git push origin master (assuming you're working out of master) 

为您的笔记本电脑:

git clone [USER]@desktop:path_to_bare 

和工作应该是在克隆副本正常。您将从原点(这是裸回购)进行推拉,但您不需要直接在其中工作。

1

推送不起作用的原因正是您提到的。默认情况下,如果该存储库(接收推送的远程)当前工作空间指向同一分支,则无法推送至布告。所以如果你的遥控器有master目前已经结帐,你将无法推送到master

两个快速的解决方案:

如果您已经在回购任何承诺,只是直接结帐的哈希,这将让你在一个无头的状态,这意味着你是不是在任何一间分行:

> git checkout <any-hash> 
Note: checking out '<any-hash>'. 

You are in 'detached HEAD' state... 

了一个全新的回购另一种方式,如果你想推到master,只是到最初的分支更改为其他未命名master

> git symbolic-ref HEAD refs/heads/non-existent 

这会使您处于与master类似的状态,在新的存储库中,在没有提交提交的分支中。只是你不会抓住主人,因此它将被允许接受推动。

1

我最近有一个问题,我的服务器和桌面不同步。在网上搜索了一段时间后,我无法找到解决我的确切情况的答案。所以我给Rackspace提供了支持,他们能够为我提供我认为比我在网上找到的更好的答案。

这个特定的线程是最接近我的问题,所以我想我会分享我如何解决这里的问题,以防将来遇到同样的问题。

这里是什么地方出了错

我试图安装Magento的甜食插件,并随后与通常的步骤中,我们都经历过安装Magento的扩展一起。这意味着将一堆文件放入我的App,JS和Skin目录中。

在app/design/adminhtml目录中有一个“base”文件夹。如果你知道Magento的任何信息,那么你知道他们有关于基础文件的混乱的数十万条警告。总之 - 不要这样做。

我认为,因为我的本地回购没有“基本”目录,我会把它放在我的本地机器上。不幸的是,令我沮丧的是,这意味着当我做了我的添加它添加了一个“基本”目录,只有Sweet Tooth的文件。当我把它放在服务器上时,它将我的整个基本目录和Boom摧毁了!下去了Magento。

幸运的是,我能够通过使用下面的救生命令,回到以前的服务器状态:

的git的复位 - 硬头@ {1}

这个命令,你回到以前的提交,并立即一切恢复正常。当然,现在我的服务器和桌面不同步,因为我的服务器现在已经落后了一次。

添加侮辱伤害我犯了一个非常愚蠢的错误,并从我的电脑中删除扩展名的文件,并做了我的桌面上的另一个提交,所以现在服务器和桌面不同步的两个提交和git现在有这些文件在其缓存中。

这里是我如何解决它

显然,这让你在一个非常恼人的地方,因为这样做我的服务器上的git拉将涂掉,每一次我的“基地”目录。另外,由于它提前两次提交,我不能只回滚一次提交。

我叫Rackspace,在这一点上,他是我心目中的上帝,并且发现了两种不同的方法来解决这个问题,这取决于您是要从服务器端还是桌面端执行此操作。

事实证明,你真的不能从服务器端做到这一点,因为文件现在不再在桌面上。虽然他们建议做一个git commit -a,然后从服务器上进行推送,然后从桌面上拉出来,但这种方式不起作用,这些文件不再在桌面上。

因此,您必须从桌面修复它,并且您需要从缓存中获取这些补丁文件。

修复同步问题从桌面

要获得这些文件从缓存中我发出以下命令过来,过来,一遍又一遍,直到进行了删除,我已删除的文件根据混帐。

的git RM -r --cached /文件夹/目录目录

的git RM --cached /文件夹/文件的文件

现在这是超出缓存我能够做一个提交,并最终让git知道这些文件实际上已经消失。

然后推送给主人。然后,所有剩下要做的事情就是从服务器和中提琴拉回来,重新开始!

**结论和经验教训**

的教训这里是一些大的,我写这篇文章对于有类似问题的其他程序员以及自己提醒我什么不该再次做。

  1. 如果你没有在你的本地回购的文件夹是在服务器上,不要把它与它只有几个文件添加到您的本地回购,这将在零出目录服务器。

  2. 如果你不小心搞砸,请务必使用Git删除文件,不要从您的本地文件系统删除

  3. 混帐休息--hard HEAD @ {1}是你最好的朋友有时

我希望这可以帮助其他任何处于类似情况的人。我花了几个小时在网上查看文档,但找不到任何与我遇到的复杂问题有关的任何内容,如果我可以帮助其他人节省一些时间并减少一些灰色头发,那么我的噩梦将为世界带来一些好处!