6

这是场景。我有两台机器,“台式机”和“笔记本电脑”。

在桌面上我这样做:

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"

然后我希望我桌面上的 git repo 看起来像我笔记本电脑上的 git repo。在笔记本电脑上,我发出以下命令: git push origin master

但后来我得到:

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 这样的集中式存储库。首先是安全性。二是简单。第三是由于情况我不会进入这里,我不能指望有互联网连接到某个远程服务器,我只是通过局域网连接了我的两台机器。最后,我想学习如何按照我在这里要求的方式做事,以获得特定的知识。

  • 我也不想使用裸仓库,因为裸仓库在根目录中有一堆杂物。这是丑陋和混乱的。我从 subversion 迁移到 git 的全部原因是 git 看起来像一个更清洁、去中心化的解决方案。另外,我有一些非技术人员将在桌面的根目录中操作,他们会被杂乱无章的东西弄糊涂。git 的美妙之处在于(我认为)所有内容都隐藏在 .git 文件夹中。编辑:显然我对这一点还不够清楚。想象一下,我有一个“文档”文件夹,其中包含以下子文件夹:mydata1 和 mydata2。这不是一个人为的例子,这正是我要处理的问题。mydata1 应仅包含“test.img”和该文件,但它现在具有:

    分支配置描述 HEAD hooks info objects refs

我希望能够直接 cd 进入 mydata1 并开始编辑文件,但我必须尝试通过分支 cd,或者甚至只是为了完成工作。并且为“文档”中的每个子文件夹都拥有这种目录结构是行不通的。拜托,请不要告诉我这样做。请只回答问题。谢谢。

这两点是我在这里发布这个问题的全部原因。请仅在您对此问题有答案的情况下回复。:) 谢谢!!

4

4 回答 4

12

这样做的一种方法是拉,而不是推。设置好两台机器后,在第一台机器上:

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

现在您可以从任何一台机器上提取提交。如果您想推动,我不确定如何通过分散设置来实现。

于 2013-01-17T01:55:42.757 回答
2

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

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

这是出了什么问题

我正在尝试为 Magento 安装 Sweet Tooth 插件,并按照我们安装 Magento 扩展程序的常规步骤进行操作。这意味着获取一堆文件并将它们放在我的 App、JS 和 Skin 目录中。

在 app/design/adminhtml 目录中有一个“base”文件夹。如果您对 Magento 有所了解,那么您就会知道他们有无数关于弄乱基本文件的警告。简而言之 - 不要这样做。

我假设由于我的本地仓库没有“基本”目录,所以我可以将它放在我的本地机器上。不幸的是,令我沮丧的是,这意味着当我添加它时,它添加了一个“基本”目录,其中只有 Sweet Tooth 的文件。然后当我把它放在服务器上时,它清除了我的整个基本目录和 Boom!Magento 失败了。

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

git reset --hard HEAD@{1}

此命令将您带回上一次提交,并且立即一切恢复正常。当然,现在我的服务器和桌面不同步了,因为我的服务器现在落后了一个提交。

为了雪上加霜,我犯了一个非常愚蠢的错误,并从我的计算机中删除了扩展程序的文件,并在我的桌面上进行了另一次提交,所以现在服务器和桌面因两次提交而不同步,git 现在将这些文件放在其缓存中.

这是我解决它的方法

显然,这让你处于一个非常烦人的地方,因为在我的服务器上执行 git pull 每次都会清除我的“基本”目录。此外,由于前面有两个提交,我不能只回滚一个提交。

我打电话给 Rackspace,他在这一点上是我心目中的神,并找到了两种不同的方法来解决这个问题,具体取决于您是想从服务器端还是桌面端执行此操作。

事实证明,您确实无法从服务器端执行此操作,因为文件现在不再位于桌面上。虽然他们建议执行 git commit -a 然后从服务器推送,然后从桌面拉取,但这只是行不通,文件不再在桌面上。

因此,您必须从桌面修复它,并且需要将那些该死的文件从缓存中取出。

从桌面修复同步问题

为了从缓存中取出文件,我一遍又一遍地发出以下命令,直到我删除的文件也根据 git 被删除。

git rm -r --cached /folder/directory 目录

git rm --cached /folder/file 文件

现在这已经不在缓存中了,我可以进行提交,最后让 git 知道这些文件实际上已经消失了。

紧随其后的是向主推。然后剩下要做的就是从服务器和中提琴中拉出来,重新开始营业!

** 结论和经验教训 **

这里吸取的教训是一些重要的教训,我正在为其他有类似问题的程序员以及我自己写这篇文章,以提醒我不要再做任何事情。

  1. 如果您在服务器上的本地存储库中没有文件夹,请不要将其添加到只有几个文件的本地存储库中,这会将服务器上的目录清零。

  2. 如果您不小心搞砸了,请确保使用 git 删除文件,不要从本地文件系统中删除它们

  3. git rest --hard HEAD@{1} 有时可以成为你最好的朋友

我希望这对处于类似情况的其他人有所帮助。我花了几个小时在网上翻阅文档,但找不到任何与我在这里遇到的复杂性有关的东西,所以如果我可以帮助别人节省一些时间并减少一些白发,那么我的噩梦将为世界带来一些好处!

于 2013-11-12T06:52:14.770 回答
1

我可能错过了为什么您不想使用裸仓库,并且我相信仅拉式解决方案应该可以正常工作,但我也相信在使用裸仓库时,“垃圾”仍然可以以您想要的方式隐藏.

在您的桌面上,如果您:

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

克隆副本中的工作应该是正常的。您将从原点(即裸仓库)推送和拉取,但您不需要直接在其中工作。

于 2013-01-17T02:09:15.353 回答
1

推送不起作用的原因正是您提到的。默认情况下,如果该存储库(接收推送的远程)当前工作空间指向同一分支,则您无法推送到该分支。因此,如果您的遥控器master当前已签出,您将无法推送到master.

两个快速解决方案:

如果您在 repo 中已经有任何提交,只需直接签出一个哈希,这将使您处于无头状态,这意味着您不在任何分支:

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

You are in 'detached HEAD' state...

另一种使用全新 repo 的方法,如果您想推送到master,只需将初始分支更改为其他未命名的分支master

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

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

于 2013-01-18T01:59:52.973 回答