我通常通过ssh(使用screen和vim)在远程服务器上工作,我在那里有一个Git仓库。有时我不在线,所以我的笔记本电脑上有一个单独的仓库(从我的远程仓库克隆而来)。
但是,由于我通常在防火墙后面或没有公共IP,所以我无法从这个本地仓库拉取到远程端。
我读过应该只推送到裸仓库。那么我应该如何将我的更改推送到我的远程仓库呢?
我通常通过ssh(使用screen和vim)在远程服务器上工作,我在那里有一个Git仓库。有时我不在线,所以我的笔记本电脑上有一个单独的仓库(从我的远程仓库克隆而来)。
但是,由于我通常在防火墙后面或没有公共IP,所以我无法从这个本地仓库拉取到远程端。
我读过应该只推送到裸仓库。那么我应该如何将我的更改推送到我的远程仓库呢?
最佳方案
推送到非裸库的远程仓库,最清晰、最不会混淆和最安全的方法是将其推送到代表您笔记本电脑分支的远程仓库中的专用分支上。
让我们看看最简单的情况,假设您每个仓库只有一个主分支:master。当您从笔记本电脑向远程仓库推送时,不要将 master -> master 推送,而是将 master -> laptop-master(或类似名称)推送。这样推送不会影响远程仓库中当前选定的主分支。从笔记本电脑执行此操作的命令非常简单:
git push origin master:laptop-master
这意味着本地的主分支将被推送到远程仓库中名为 "laptop-master" 的分支。在远程仓库中,你将有一个新的名为 "laptop-master" 的分支,当你准备好时,可以将其合并到你的远程主分支中。
另一种选择
也可以只将主分支(master)推送到主分支(master),但是在非裸露(bare)仓库的当前检出(checkout)分支进行推送通常是不建议的,因为如果您不了解发生了什么,它可能会让人感到困惑。这是因为向已检出的分支推送不会更新工作树(work tree),因此在被推送的已检出分支中检查 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。但是,将推送到单独的分支,然后合并通常更好,因为它执行实际的合并(因此与merge一样适用于未提交的更改)。
git config receive.denyCurrentBranch ignore
。请注意保持翻译内容的准确性和原意不变,并简明易懂。 - prusswangit push origin master:laptop-master && ssh user@remotemachine 'cd repos_path && git merge laptop-master'
- Richreceive.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
--local
是可选的吗? - Yukulélé--local
只影响当前目录,--global
影响所有带有 ~/.gitconfig
的 git 仓库,请参阅 man git-config
。 - Ciro Santilli OurBigBook.com我建议在您的服务器上拥有一个裸仓库和一个本地工作(非裸)仓库。您可以将更改从笔记本电脑推送到服务器裸仓库,然后从该裸仓库拉取到服务器工作仓库。我这么说的原因是,您可能在服务器上有许多完整/不完整的分支,您希望在笔记本电脑上复制这些分支。
这样,您就不必担心在将更改推送到服务器时检出的分支状态会影响服务器工作仓库。
# 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
这可以在裸库或中央仓库中完成,以便接受从非裸库推送的任何文件。
如果在非裸库中执行此操作,则无法将任何文件从非裸库推送到裸库。$git log
来检查它。
git pull github master
的脚本。 - Jake Berger