昨天,我发布了一个关于如何从我的一台机器克隆Git存储库到另一台机器的问题,我如何从另一台机器“克隆Git”?
现在我可以成功地将Git存储库从源存储库(192.168.1.2)克隆到目标存储库(192.168.1.1)。
但是当我对文件进行编辑,git commit -a -m "test"和git push时,我在目的地(192.168.1.1)上得到了这个错误:
git push
hap@192.168.1.2's password:
Counting objects: 21, done.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 1010 bytes, done.
Total 11 (delta 9), reused 0 (delta 0)
error: refusing to update checked out branch: refs/heads/master
error: By default, updating the current branch in a non-bare repository
error: is denied, because it will make the index and work tree inconsistent
error: with what you pushed, and will require 'git reset --hard' to match
error: the work tree to HEAD.
error:
error: You can set 'receive.denyCurrentBranch' configuration variable to
error: 'ignore' or 'warn' in the remote repository to allow pushing into
error: its current branch; however, this is not recommended unless you
error: arranged to update its work tree to match what you pushed in some
error: other way.
error:
error: To squelch this message and still keep the default behaviour, set
error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To git+ssh://hap@192.168.1.2/media/LINUXDATA/working
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'git+ssh://hap@192.168.1.2/media/LINUXDATA/working'
我正在使用两个不同版本的Git(远程上的1.7版本和本地机器上的1.5版本)。这是一个可能的原因吗?
旧版本的Git允许推入当前签出的非裸库分支。
事实证明,这是一件非常令人困惑的事情。所以他们添加了你看到的警告信息,这也是非常令人困惑的。
如果第一个存储库只是充当服务器,那么按照其他答案的建议将其转换为裸存储库,然后就可以完成了。
然而,如果你需要在两个都在使用的回购之间有一个共享分支,你可以通过下面的设置来实现
Repo1 -将充当服务器,也用于开发
Repo2—仅用于开发
按如下方式安装Repo1
创建一个分支来共享工作。
git branch shared_branch
为了安全起见,您还应该创建一个$(REPO)。Git /hooks/update拒绝对shared_branch以外的任何内容的任何更改,因为你不想让别人乱动你的私有分支。
repo1/.git/hooks (GIT_DIR!)$ cat update
#!/bin/sh
refname="$1"
oldrev="$2"
newrev="$3"
if [ "${refname}" != "refs/heads/shared_branch" ]
then
echo "You can only push changes to shared_branch, you cannot push to ${refname}"
exit 1
fi
现在在repo1中创建一个本地分支,您将在其中执行实际工作。
git checkout -b my_work --track shared_branch
Branch my_work set up to track local branch shared_branch.
Switched to a new branch 'my_work'
(可能需要git配置——global push.default upstream,以便git push工作)
现在您可以使用
git clone path/to/repo1 repo2
git checkout shared_branch
此时,您已经设置了repo1和repo2,以便在本地分支上工作,从repo1中的shared_branch中进行推和拉操作,而无需担心错误消息或repo1中的工作目录不同步。您使用的任何正常工作流都应该工作。
我发现一篇可能对其他人有用的文章是《Git 5分钟》。
我有一个在Git版本控制下的Xcode项目,我想把它推到DC中的虚拟分布式以太网(VDE)上。VDE运行Centos 5。
我读过的关于Git的文章中没有一篇谈到了裸库。这一切听起来都很简单,直到我尝试了我认为来自SVN背景的东西。
这里的建议使远程存储库裸露工作。更适合我的需求是克隆Xcode项目到projectname。Git,复制到远程服务器;然后,推神奇地起作用了。下一步将是让Xcode推送没有关于提交的错误,但现在我可以从终端做它。
So:
cd /tmp (or another other directory on your system)<br/>
git clone --bare /xcode-project-directory projectname.git<br/>
scp -r projectname.git sshusername@remotehost.com:repos/<br/>
在Xcode中提交后,从Xcode项目中推送更改:
cd /xcode-project-directory<br/>
git push sshusername@remotehost.com:repos/projectname.git<br/>
我确信有一种更流畅更复杂的方法来完成上述工作,但至少这是可行的。为了让一切都清楚,这里有一些澄清:
/xcode-project-directory是xcode项目的存放目录。可能是/Users/Your_Name/Documents/Project_Name。
Projectname字面上是项目的名称,但它可以是任何您愿意调用它的名称。少不更事的人不在乎,你会在乎的。
要使用scp,您需要在远程服务器上有一个允许SSH访问的用户帐户。任何运行自己服务器的人都会有这个。如果你正在使用共享主机或类似的东西,你可能就不走运了。
Remotehost.com是远程主机的名称。你可以使用它的IP地址。为了进一步清晰起见,我在远程主机上使用带有SSH密钥的giitosis,所以当我按下按钮时,不会提示输入密码。文章托管Git存储库,简单(和安全)的方式告诉你如何设置所有这些。
总结
您不能推送到存储库的一个签出分支,因为这会扰乱该存储库的用户,很可能以丢失数据和历史记录而告终。但是您可以推送到同一存储库的任何其他分支。
由于裸存储库从来没有检出过任何分支,所以您总是可以推入裸存储库的任何分支。
根据您的需要,有多种解决方案。
解决方案1:使用裸存储库
正如建议的那样,如果在一台机器上不需要工作目录,则可以移动到裸存储库。为了避免混淆存储库,你可以克隆它:
machine1$ cd ..
machine1$ mv repo repo.old
machine1$ git clone --bare repo.old repo
现在你可以把所有你想要的推送到和以前一样的地址。
解决方案2:推到一个非签出分支
但是如果您需要检出remote <remote>上的代码,那么您可以使用一个特殊的分支来进行推送。假设在本地存储库中,您已经调用了远程源,并且处于分支master上。然后你就可以
machine2$ git push origin master:master+machine2
然后你需要合并它当你在原始远程回购:
machine1$ git merge master+machine2
问题的解剖
当一个分支签出时,提交将添加一个新的提交,当前分支的头作为其父,并移动该分支的头作为新提交。
So
A ← B
↑
[HEAD,branch1]
就变成了
A ← B ← C
↑
[HEAD,branch1]
但如果有人可以推送到中间的那个分支,用户就会进入git所说的分离头部模式:
A ← B ← X
↑ ↑
[HEAD] [branch1]
现在用户不再在branch1中,没有显式地要求签出另一个分支。更糟糕的是,用户现在在任何分支之外,任何新的提交都会悬空:
[HEAD]
↓
C
↙
A ← B ← X
↑
[branch1]
假设,如果此时用户签出了另一个分支,那么这个悬空提交将成为Git垃圾收集器的公平游戏。
旧版本的Git允许推入当前签出的非裸库分支。
事实证明,这是一件非常令人困惑的事情。所以他们添加了你看到的警告信息,这也是非常令人困惑的。
如果第一个存储库只是充当服务器,那么按照其他答案的建议将其转换为裸存储库,然后就可以完成了。
然而,如果你需要在两个都在使用的回购之间有一个共享分支,你可以通过下面的设置来实现
Repo1 -将充当服务器,也用于开发
Repo2—仅用于开发
按如下方式安装Repo1
创建一个分支来共享工作。
git branch shared_branch
为了安全起见,您还应该创建一个$(REPO)。Git /hooks/update拒绝对shared_branch以外的任何内容的任何更改,因为你不想让别人乱动你的私有分支。
repo1/.git/hooks (GIT_DIR!)$ cat update
#!/bin/sh
refname="$1"
oldrev="$2"
newrev="$3"
if [ "${refname}" != "refs/heads/shared_branch" ]
then
echo "You can only push changes to shared_branch, you cannot push to ${refname}"
exit 1
fi
现在在repo1中创建一个本地分支,您将在其中执行实际工作。
git checkout -b my_work --track shared_branch
Branch my_work set up to track local branch shared_branch.
Switched to a new branch 'my_work'
(可能需要git配置——global push.default upstream,以便git push工作)
现在您可以使用
git clone path/to/repo1 repo2
git checkout shared_branch
此时,您已经设置了repo1和repo2,以便在本地分支上工作,从repo1中的shared_branch中进行推和拉操作,而无需担心错误消息或repo1中的工作目录不同步。您使用的任何正常工作流都应该工作。