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


当前回答

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

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

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'在同一个父文件夹中)。我建议您也这样做,但我想让上面的步骤尽可能简单。

其他回答

我也有同样的问题。对我来说,我使用Git push将代码移动到服务器。我从不改变服务器端的代码,所以这是安全的。

在存储库中,您正在按下输入:

git config receive.denyCurrentBranch ignore

这将允许您在存储库是工作副本时更改存储库。

运行Git推送后,转到远程机器并键入以下内容:

git checkout -f

这将使您所推动的更改反映在远程计算机的工作副本中。

请注意,如果在您要推入的工作副本中进行更改,这并不总是安全的。

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

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

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'在同一个父文件夹中)。我建议您也这样做,但我想让上面的步骤尽可能简单。

事实上,将远程设置为一个未签出的分支就足够了。当您在不同的分支签出您的遥控器后,您可以按。

旧版本的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 push production

这很简单,你不需要登录到远程服务器并进行拉取或其他操作。请注意,如果您不将生产检出用作工作分支,这将是最好的工作方式!(OP的工作环境略有不同,我认为@Robert Gould的解决方案很好地解决了这个问题。此解决方案更适合部署到远程服务器。)

首先,你需要在你的服务器上的某个地方建立一个裸库,在你的webroot之外。

mkdir mywebsite.git
cd mywebsite.git
git init --bare

然后创建文件hooks/post-receive:

#!/bin/sh
GIT_WORK_TREE=/path/to/webroot/of/mywebsite git checkout -f

并使文件可执行:

chmod +x hooks/post-receive

在本地机器上,

git remote add production git@myserver.com:mywebsite.git
git push production +master:refs/heads/master

都准备好了!现在,将来您可以使用git push production来部署您的更改!

这个解决方案的功劳归http://sebduggan.com/blog/deploy-your-website-changes-using-git/。在那里可以找到关于正在发生的事情的更详细的解释。