我通常通过 ssh(screen 和 vim)在远程服务器上工作,在那里我有一个 Git 存储库。有时我不在线,所以我的笔记本电脑上有一个单独的存储库(从我的远程克隆)。
但是,我无法从远程端的这个存储库中提取,因为我通常在防火墙后面或者我没有公共 IP。
我读过我应该只推送到一个裸存储库。然后我应该如何将我的更改推送到我的远程存储库?
我通常通过 ssh(screen 和 vim)在远程服务器上工作,在那里我有一个 Git 存储库。有时我不在线,所以我的笔记本电脑上有一个单独的存储库(从我的远程克隆)。
但是,我无法从远程端的这个存储库中提取,因为我通常在防火墙后面或者我没有公共 IP。
我读过我应该只推送到一个裸存储库。然后我应该如何将我的更改推送到我的远程存储库?
最佳选择
推送到非裸远程存储库的最干净、最少混淆和最安全的方法可能是推送到远程中代表笔记本电脑分支的专用分支。
让我们看一下最简单的情况,并假设您在每个 repo 中只有一个分支:master。当您从笔记本电脑推送到远程仓库时,不是推送 master -> master,而是推送 master -> laptop-master(或类似名称)。这样推送不会影响远程仓库中当前签出的主分支。要在笔记本电脑上执行此操作,命令非常简单:
git push origin master:laptop-master
这意味着本地主分支将被推送到远程存储库中名为“laptop-master”的分支。在您的远程仓库中,您将拥有一个名为“laptop-master”的新分支,然后您可以在准备好后将其合并到您的远程 master 中。
备用选项
也可以只推送 master -> master,但通常不建议推送到当前已签出的非裸仓库分支,因为如果您不了解发生了什么可能会造成混淆。这是因为推送到签出分支不会更新工作树,因此签git status
入被推送到的签出分支将显示与最近推送的完全相反的差异。如果在推送完成之前工作树很脏,这会变得特别令人困惑,这是不推荐这样做的一个重要原因。
如果你想尝试只推 master -> master,那么命令就是:
git push origin
但是当你回到远程仓库时,你很可能想要做一个git reset --hard HEAD
让工作树与推送的内容同步。这可能很危险,因为如果您想要保留的远程工作树中有任何未提交的更改,它将清除它们。在尝试之前,请确保您知道这样做的后果,或者至少先进行备份!
编辑从 Git 2.3 开始,您可以使用“push-to-deploy” git push:https ://github.com/blog/1957-git-2-3-has-been-released 。但是推送到一个单独的分支然后合并通常会更好,因为它会进行实际的合并(因此可以像合并一样处理未提交的更改)。
receive.denyCurrentBranch updateInstead
此选项是在 Git 2.3中添加的,如果它是干净的,它会使服务器更新其工作树。
因此,如果您确保在本地拉取之前始终提交,并在服务器上保持干净的工作树(您应该这样做以避免合并冲突),那么这个选项是一个很好的解决方案。
示例用法:
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,它会在那里显示文件。