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


当前回答

最好的方法是:

mkdir ..../remote
cd ..../remote
git clone --bare .../currentrepo/

这将克隆存储库,但不会在…/remote中生成任何工作副本。如果查看远程,您将看到创建了一个名为currentrepo的目录。Git,这可能是你想要的。

然后从本地Git存储库中:

git remote add remoterepo ..../remote/currentrepo.git

进行更改后,您可以:

git push remoterepo master

其他回答

错误消息描述发生了什么。更现代的Git版本在分支签出时拒绝通过推送更新该分支。

在两个非裸存储库之间工作的最简单方法是

总是通过pull(或fetch和merge)来更新存储库,如果必须的话, 通过推入到一个单独的分支(导入分支),然后将该分支合并到远程机器上的主分支。

这个限制的原因是推送操作只能在远程Git存储库上操作,它不能访问索引和工作树。因此,如果允许的话,对签出分支的推操作将使HEAD与远程存储库上的索引和工作树不一致。

这将非常容易意外地提交一个更改来撤销所有已推送的更改,也使得很难区分尚未提交的任何局部更改和新HEAD、索引和工作树之间的差异,这些差异是由推送移动HEAD引起的。

你可能做了什么导致了这个:

当你去开发一个小程序时,这种事情就会发生。你要改变一些已经生效的东西,所以你施放了三级永久撤销法术:

machine1:~/proj1> git init

然后开始添加/提交。但随后,项目开始变得更加复杂,你想从另一台计算机(比如你的家用PC或笔记本电脑)上处理它,所以你做了这样的事情

machine2:~> git clone ssh://machine1/~/proj1

它会复制,一切看起来都很好,所以你可以从machine2上处理代码。

然后……您尝试从machine2推送提交,并在标题中得到警告消息。

The reason for this message is because the git repo you pulled from was kinda intended to be used just for that folder on machine1. You can clone from it just fine, but pushing can cause problems. The "proper" way to be managing the code in two different locations is with a "bare" repo, like has been suggested. A bare repo isn't designed to have any work being done in it, it is meant to coordinate the commits from multiple sources. This is why the top-rated answer suggests deleting all files/folders other than the .git folder after you git config --bool core.bare true.

Clarifying the top-rated answer: Many of the comments to that answer say something like "I didn't delete the non-.git files from the machine1 and I was still able to commit from machine2". That's right. However, those other files are completely "divorced" from the git repo, now. Go try git status in there and you should see something like "fatal: This operation must be run in a work tree". So, the suggestion to delete the files isn't so that the commit from machine2 will work; it's so that you don't get confused and think that git is still tracking those files. But, deleting the files is a problem if you still want to work on the files on machine1, isn't it?

那么,你到底应该怎么做呢?

这取决于你还打算在machine1和machine2上工作多少…

如果你已经完成了从machine1开始的开发,并将所有的开发都转移到machine2上……只需要做排名最高的答案所建议的:git config——bool core。完全正确,然后,可选地删除该文件夹中除.git之外的所有文件/文件夹,因为它们无法跟踪,可能会引起混乱。

如果你在machine2上的工作只是一次性的,你不需要在那里继续开发……那就别费事去做单纯的回购了;只是ftp / rsync / scp /等。你从机器*2*上的文件放到机器*1*上的文件上面,从机器*1*上提交/推送,然后删除机器*2*上的文件。其他人建议创建一个分支,但我认为如果您只是想合并从另一台机器上一次性完成的一些开发,那么这有点混乱。

如果你需要在machine1和machine2上继续开发……然后你需要正确地设置。您需要将您的repo转换为bare,然后您需要在machine1上创建一个副本,以便您在其中工作。可能最快的方法就是去做

machine1:~/proj1> git config --bool core.bare true
machine1:~/proj1> mv .git/ ../proj1.git
machine1:~/proj1> cd ..
machine1:~> rm -rf proj1
machine1:~> git clone proj1.git
machine1:~> cd proj1

非常重要:因为您已经将回购的位置从proj1移动到proj1。Git,您需要在machine2上的. Git /配置文件中更新它。之后,您可以从machine2提交更改。最后,我试着把我的裸回购放在一个中心位置,远离我的工作树(也就是说,不要把“proj1。Git '和'proj1'在同一个父文件夹中)。我建议您也这样做,但我想让上面的步骤尽可能简单。

错误消息error: refused to update检出branch: refs/heads/master由远程存储库发出,这意味着您试图将代码推到远程非裸存储库,该存储库当前在工作目录中检出了不同的代码。避免此问题的最佳方法是只推送到裸存储库—裸存储库永远不会发生此问题。

您可以简单地将远程存储库转换为裸存储库(裸存储库中没有工作副本—文件夹只包含实际的存储库数据)。

在远程存储库文件夹中执行以下命令:

git config --bool core.bare true

然后删除该文件夹中除.git外的所有文件。然后你就可以执行git推送到远程存储库而不会出现任何错误。

检查目标项目中的.git/config:

$ cat .git/config 
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[receive]
    denyCurrentBranch = updateInstead

如果核心。Bare为false,你可以设置为true:

$ git config core.bare true

然后在本地推送到远程:

git push remote_repo   // suppose the destination repo is remote_repo

它会成功,在remote_repo你可以检查git版本。

$ git log -1
commit 0623b1b900ef7331b9184722a5381bbdd2d935ba
Author: aircraft < aircraft_xxx@126.com>
Date:   Thu May 17 21:54:37 2018 +0800

现在你不能在你的“工作区”中使用git了:

$ git status
fatal: This operation must be run in a work tree

你应该裸露。裸背为假。

$ git config core.bare false

最好的方法是:

mkdir ..../remote
cd ..../remote
git clone --bare .../currentrepo/

这将克隆存储库,但不会在…/remote中生成任何工作副本。如果查看远程,您将看到创建了一个名为currentrepo的目录。Git,这可能是你想要的。

然后从本地Git存储库中:

git remote add remoterepo ..../remote/currentrepo.git

进行更改后,您可以:

git push remoterepo master