如何推送到非裸Git存储库?

如何推送到非裸Git存储库?,git,git-push,git-non-bare-repository,Git,Git Push,Git Non Bare Repository,我通常通过ssh(screen和vim)在远程服务器上工作,在那里我有一个Git存储库。有时我不在线,所以我的笔记本电脑上有一个单独的存储库(从远程克隆) 然而,我不能从这个远程存储库中提取,因为我通常在防火墙后面或者我没有公共IP 我已经读到,我应该只推到一个空的存储库。然后如何将更改推送到远程存储库?最佳选项 可能最干净、最容易混淆、最安全的方法是推送到远程存储库中代表笔记本电脑分支的专用分支 让我们看一个最简单的例子,假设在每个repo:master中只有一个分支。当您从笔记本电脑推送到远

我通常通过ssh(screen和vim)在远程服务器上工作,在那里我有一个Git存储库。有时我不在线,所以我的笔记本电脑上有一个单独的存储库(从远程克隆)

然而,我不能从这个远程存储库中提取,因为我通常在防火墙后面或者我没有公共IP


我已经读到,我应该只推到一个空的存储库。然后如何将更改推送到远程存储库?

最佳选项

可能最干净、最容易混淆、最安全的方法是推送到远程存储库中代表笔记本电脑分支的专用分支

让我们看一个最简单的例子,假设在每个repo:master中只有一个分支。当您从笔记本电脑推送到远程回购时,不要按master->master,而是按master->laptop master(或类似名称)。这样,推送不会影响远程回购中当前签出的主分支。要从笔记本电脑执行此操作,命令非常简单:

git push origin master:laptop-master
这意味着本地主分支将被推送到远程存储库中名为“laptop master”的分支。在远程回购中,您将有一个名为“laptop master”的新分支,您可以在准备好后将其合并到远程主机中

备用选项

也可以只按master->master,但通常不建议按到非裸回购的当前签出分支,因为如果您不了解发生了什么,可能会造成混乱。这是因为推送到签出分支不会更新工作树,因此在推送到的签出分支中检查
git status
,将显示与最近推送到的完全相反的差异。如果工作树在推送之前是脏的,那么它会变得特别混乱,这是不建议这样做的一个重要原因

如果要尝试只按master->master,则命令如下:

git push origin
但是,当您回到远程回购时,您很可能希望执行一个
git reset--hard HEAD
,以使工作树与推送的内容同步。这可能是危险的,因为如果远程工作树中有任何您想要保留的未提交的更改,它将清除这些更改。在尝试之前,请确保您知道这样做的后果,或者至少先进行备份


编辑自Git 2.3以来,您可以使用“推送部署”Git推送:。但是,推到一个单独的分支,然后进行合并通常会更好,因为它会进行实际的合并(因此可以像合并一样处理未提交的更改)。

我建议在您的服务器中有一个裸存储库和一个本地工作(非裸)repo。您可以将更改从笔记本电脑推送到服务器裸repo,然后从裸repo拉到服务器工作repo。我之所以这么说,是因为您可能需要在笔记本电脑上复制服务器中的许多完整/不完整分支


这样,在将更改推送到服务器时,您就不必担心在服务器上签出的分支的状态

receive.denyCurrentBranch updateInstead

已添加,它会使服务器更新其工作树(如果它是干净的)

因此,如果您确保在本地拉取之前始终提交,并且在服务器上保持一个干净的工作树(您应该这样做以避免合并冲突),那么此选项是一个很好的解决方案

示例用法:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls
输出:

a
b

另一个选项是设置一个反向ssh隧道,这样您就可以拉而不是推

# start the tunnel from the natted box you wish to pull from (local)
$ ssh -R 1234:localhost:22 user@remote

# on the other box (remote)
$ git remote add other-side ssh://user@localhost:1234/the/repo
$ git pull other-side
如果你想让隧道在后台运行

$ ssh -fNnR 1234:localhost:22 user@remote
你可以做:

$git config--bool core.bare true

这可以在裸存储库或中央存储库中完成,以便它可以接受从非裸存储库推送的任何文件。 如果您在非裸存储库中执行此操作,则我们无法将任何文件从非裸存储库推送到裸存储库

如果你通过在PC上创建中心和非裸机回购来练习GIT,它可能不会在某些PC上显示推送的文件,但它已经被推送了。您可以通过运行来检查它

中央回购中的$git log


除了推到GitHub之外,它会在那里显示文件。

推到笔记本电脑主机后是否可以自动进行分支?@rdoubleui:您的意思是“自动合并”?如果是这样的话,就不可能自动进行合并,因为没有人工干预,合并是不可能实现的。可能存在需要解决的冲突。在更高版本(?)中,
git config receive.denyCurrentBranch ignore
必须在推送到non-bare reposGreat answer@DanMoulding之前完成,谢谢@rdoubleui:您可以将如下命令行保存为bash函数:
git-push-origin-master:laptop-master&&sshuser@remotemachine“cd repos_path&&git merge laptop master”
@rdoubleui要自动进行合并,可以使用gitolite进行设置(有点复杂)使非裸提交所有内容变脏,并使用pre-git触发器将其推送到gitolite(裸)版本。在此之后,如果合并无法在非裸机中解决,它将拒绝您的推送,因此您知道必须先拉,解决合并,然后再次推送。我还没有建立这个,但我在这个过程中,并认为它可以工作。相关:有2个远程回购,一个裸机和一个正常,并使用挂钩。看起来很麻烦,但根据和的规定,你应该只推进一个无担保的回购协议。这可能就是为什么大多数git repo主机(例如GitHub、Bitbucket)都包含post接收挂钩,因此您可以将其发送到服务器上的URL,该URL运行一个脚本,该脚本可以执行例如
git pull GitHub master
。是否可以复制,而无需创建类似heroku的裸机repodoes@ANinJa我不明白,不是吗