昨天,我发布了一个关于如何从我的一台机器克隆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版本)。这是一个可能的原因吗?


当前回答

让我加上我的50美分,因为投票最多的答案https://stackoverflow.com/a/3251126/3455918建议将远程repw转换为裸库,如果这不是我想要的呢?

最后,我必须在远程机器上有相同的代码,但不只是.git边缘的某个地方的一团字节。

第二次投票(在撰写本文时)的解决方案https://stackoverflow.com/a/2933656/3455918可以完成这项工作,但在测试之后,我最终不得不不断地在远程机器上的分支之间切换,以“释放”我想从本地机器推送到的分支。

这招对我很管用:

到目前为止对我有效的另一个解决方案不是我的,功劳是给了一个对第一个解决方案发表评论的用户@kxr。

在远程机器上,您必须在repo目录中执行此命令。

git配置receive.denyCurrentBranch updateInstead

在此之后,您就完成了!

显然,这种解决方案可能有一些缺点,但对于将本地机器代码同步到远程回购的简单任务来说,它可能已经足够好了。

如果有人在评论中解释为什么在github上创建一个全新的repo,将你的本地文件夹链接到它,并开始做git push origin master而没有错误,我会很感激。

但是尝试在远程服务器上进行同样的回购会产生错误:

! [远程拒绝]master -> master(分支当前签出)

其他回答

使用Git,两个常规(非裸)存储库不能直接来回推/拉文件。必须有一个中间裸存储库。显然,这有点像一对已婚夫妇有了一个孩子,但这对夫妇要离婚了。父母之间不会相互交谈,但他们会通过孩子进行交流。

因此,您有一个存储库,您将这个存储库克隆到一个裸存储库,然后将其克隆到第三个。第一个和第三个可以通过第二个存储库(裸存储库)交换信息。我想这是有道理的,因为你不希望别人在未经你同意的情况下将东西签入你的存储库,因为这可能会导致合并冲突等。

这里有一个例子:

在PC上,在~/workspace

git init
echo "line 1" > afile.txt
git add .
git commit -m ‘initial import’
git clone --bare . ../remote-repository.git
git remote add origin ../remote-repository.git
git push --set-upstream origin master

在笔记本电脑上,在~/workspace中(不要init git等)

git clone //LJZ-DELLPC/remote-repository.git/ .

//然后进行各种提交,并推送它们:

echo "line 2" > afile.txt
git add afile.txt
git commit -m 'added line 2'
git push    

然后回到PC,在~/workspace中

git pull

//然后进行各种提交,并推送它们:

git push

在笔记本电脑 git拉

等等。

下面是一台机器上的一个绝对具体的例子,直接从命令窗口复制,这样我们就知道没有遗漏任何步骤,它确实可以工作,等等:

lylez@LJZ-DELLPC ~
$ cd gitdir
/home/lylez/gitdir

lylez@LJZ-DELLPC ~/gitdir
$ ls

lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1

lylez@LJZ-DELLPC ~/gitdir
$ cd repo1
/home/lylez/gitdir/repo1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git init
Initialized empty Git repository in /home/lylez/gitdir/repo1/.git/

lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 1" > afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m 'initial import'
[master (root-commit) f407e12] initial import
 1 file changed, 1 insertion(+)
 create mode 100644 afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git clone --bar . ../repo1-bare-clone
Cloning into bare repository '../repo1-bare-clone'...
done.

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git remote add origin ../repo1-bare-clone

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push --set-upstream origin master
Branch master set up to track remote branch master from origin.
Everything up-to-date

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ..

lylez@LJZ-DELLPC ~/gitdir
$ ls
repo1  repo1-bare-clone

lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1-remote

lylez@LJZ-DELLPC ~/gitdir
$ cd repo1-remote
/home/lylez/gitdir/repo1-remote

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git clone ../repo1-bare-clone .
Cloning into '.'...
done.

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ echo "line 2" >> afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git commit -m 'added line 2'
[master 5ad31e0] added line 2
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 260 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
   f407e12..5ad31e0  master -> master

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cd ../repo1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ../repo1-bare-clone
   f407e12..5ad31e0  master     -> origin/master
Updating f407e12..5ad31e0
Fast-forward
 afile.txt | 1 +
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1
line 2

lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 3" >> afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m 'added line 3'
[master 3fa569e] added line 3
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 265 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../repo1-bare-clone
   5ad31e0..3fa569e  master -> master

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ../repo1-remote/

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
   5ad31e0..3fa569e  master     -> origin/master
Updating 5ad31e0..3fa569e
Fast-forward
 afile.txt | 1 +
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2
line 3

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git --version
git version 2.1.1

lylez@LJZ-DELLPC ~/gitdir/repo1-remote

您应该只推送到一个裸露的存储库。裸存储库是指没有检出分支的存储库。如果要cd到一个裸存储库目录,则只能看到.git目录的内容。

您可以通过在目标服务器上编辑.git/config来绕过这个“限制”。添加以下命令,允许git存储库被推入,即使它被“签出”:

[receive]
denyCurrentBranch = warn

or

[receive]
denyCurrentBranch = false

第一个将允许推送,同时警告可能会弄乱分支,而第二个将只是静静地允许它。

这可以用于将代码“部署”到不用于编辑的服务器上。这不是最好的方法,但对于部署代码来说是一种快速的方法。

以防有人觉得有用。对我来说,这是一个git服务器权限问题。我检查了项目从乞求和推送一个简单的文件,然后我得到“推送拒绝:推送到原点/主被拒绝”

下面是一个测试,你可以看看裸服务器的东西是如何工作的:

想象一下,您有一个工作站和一个服务器,服务器上托管着活动站点,您希望不时地更新这个站点(这也适用于两个开发人员通过一个中间人来回发送他们的工作的情况)。

初始化

在你的本地计算机上创建一个目录,并将cd放入其中,然后执行以下命令:

# initialization
git init --bare server/.git
git clone server content
git clone server local

首先创建一个裸服务器目录(注意末尾的.git)。此目录将仅作为存储库文件的容器。 然后将服务器存储库克隆到新创建的内容目录。这是您的活动/生产目录,将由服务器软件提供服务。 前两个目录位于您的服务器上,第三个是您工作站上的本地目录。

工作流

下面是基本的工作流程:

进入本地目录,创建一些文件并提交。最后将它们推送到服务器: #创造疯狂的东西 Git提交-av Git push origin master 现在进入内容目录并更新服务器的内容: git拉 重复1 - 2。这里的内容可能是另一个开发人员也可以推送到服务器上的,并且您可以从他那里获取本地内容。