如何推送到非裸 Git 存储库?
我通常通过 ssh(屏幕和 vim)在远程服务器上工作,我在远程服务器上有一个 Git 存储库。有时我不在线,所以我的笔记本电脑上有一个单独的存储库(从远程克隆)。
但是,我无法从远程端的存储库中提取数据,因为我通常位于防火墙后面或者没有公共 IP。
我读过我应该只推送到一个裸存储库。然后我应该如何将更改推送到远程存储库?
I usually work on a remote server via ssh (screen and vim), where I have a Git repository. Sometimes I'm not online, so I have a separate repository (cloned from my remote) on my laptop.
However, I can't pull from this repository on remote side because I'm usually behind a firewall or I don't have a public IP.
I've read that I should push just to a bare repository. How should I then push my changes to my remote repository?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
最佳选择
推送到非裸远程存储库的最干净、最不混乱和最安全的方法可能是推送到远程中代表笔记本电脑分支的专用分支。
让我们看一下最简单的情况,假设每个存储库中只有一个分支:master。当您从笔记本电脑推送到远程存储库时,而不是推送 master ->主控、推送主控-> laptop-master(或类似的名称)。这样,推送不会影响远程存储库中当前签出的主分支。要从笔记本电脑执行此操作,命令非常简单:
这意味着本地 master 分支将被推送到远程存储库中名为“laptop-master”的分支。在您的远程存储库中,您将有一个名为“laptop-master”的新分支,然后您可以在准备好时将其合并到远程主控中。
替代选项
也可以只推送 master -> master,但通常不建议推送到非裸存储库当前签出的分支,因为如果您不了解发生了什么,可能会造成混乱。这是因为推送到签出分支不会更新工作树,因此在推送到的签出分支中检查 git status 将显示与最近完全相反的差异推。如果在推送完成之前工作树是脏的,那么会变得特别混乱,这也是不建议这样做的一个重要原因。
如果你想尝试只推 master -> master,那么命令就是:
但是当您返回到远程存储库时,您很可能想要执行 git reset --hard HEAD 以使工作树与内容同步那是被推动的。 这可能很危险,因为如果您想要保留的远程工作树中有任何未提交的更改,它们就会被清除。在尝试之前,请确保您知道这样做的后果是什么,或者至少先进行备份!
编辑从 Git 2.3 开始,您可以使用“push-to-deploy”git Push:https://github.com/blog/1957-git-2-3-has-been-released。但是推送到单独的分支然后合并通常会更好,因为它执行实际的合并(因此可以像合并一样处理未提交的更改)。
Best Option
Probably the cleanest, least confusing, and safest way to push into your non-bare remote repository, is to push to dedicated branches in the remote that represent your laptop branches.
Let's look at the simplest case, and assume you have just one branch in each repo: master. When you push to the remote repo from your laptop, instead of pushing master -> master, push master -> laptop-master (or a similar name). This way the push doesn't affect the currently checked-out master branch in the remote repo. To do this from the laptop, the command is pretty simple:
This means that the local master branch will be pushed to the branch named "laptop-master" in the remote repository. In your remote repo, you'll have a new branch named "laptop-master" that you can then merge into your remote master when you are ready.
Alternate Option
It's also possible to just push master -> master, but pushing to the currently checked-out branch of a non-bare repo is generally not recommended, because it can be confusing if you don't understand what is going on. This is because pushing to a checked-out branch doesn't update the work tree, so checking
git status
in the checked-out branch that was pushed into will show exactly the opposite differences as what was most recently pushed. It would get especially confusing if the work tree was dirty before the push was done, which is a big reason why this is not recommended.If you want to try just pushing master -> master, then the command is just:
But when you go back to the remote repo, you'll most likely want to do a
git reset --hard HEAD
to get the work tree in sync with the content that was pushed. This can be dangerous, because if there are any uncommitted changes in the remote work tree that you wanted to keep it will wipe them out. Be sure you know what the consequences of this are before you try it, or at least make a backup first!EDIT Since Git 2.3, you can use "push-to-deploy" git push: https://github.com/blog/1957-git-2-3-has-been-released. But pushing to a separate branch and then merging is usually better since it does an actual merge (hence works with uncommitted changes just like merge does).
receive.denyCurrentBranch updateInstead
此选项已添加到 Git 中2.3,如果工作树是干净的,它会让服务器更新它的工作树。
因此,如果您确保在本地拉取之前始终进行提交,并在服务器上保持干净的工作树(应该这样做以避免合并冲突),那么此选项是一个很好的解决方案。
示例用法:
输出:
receive.denyCurrentBranch updateInstead
This options was added in Git 2.3, and it makes the server update its working tree if it is clean.
So if you ensure that you always commit before you pull locally, and keep a clean working tree on the server (which you should do to avoid having merge conflicts), then this option is a good solution.
Sample usage:
Output:
我建议在您的服务器中拥有一个裸存储库和一个本地工作(非裸)存储库。您可以将更改从笔记本电脑推送到服务器裸存储库,然后从该裸存储库拉取到服务器工作存储库。我这么说的原因是因为您可能在服务器中有许多完整/不完整的分支,您希望在笔记本电脑上复制它们。
这样,在将更改推送到服务器时,您不必担心在服务器工作存储库上签出的分支的状态。
I would suggest to have a bare-repository and a local working (non-bare) repos in your server. You could push changes from laptop to server bare repo and then pull from that bare repo to server working repo. The reason I say this is because you might have many complete/incomplete branches in server which you will want to replicate on the laptop.
This way you don't have to worry about the state of the branch checked out on server working repo while pushing changes to server.
另一种选择是设置反向 ssh 隧道,以便您可以拉取而不是推送。
如果您希望隧道在后台运行
Another option is to setup a reverse ssh tunnel so that you can pull instead of push.
And if you want the tunnel to run in the background
您可以执行
以下操作: $git config --bool core.bare true
这可以在裸存储库或中央存储库中完成,以便它将接受从非裸存储库推送的任何文件。
如果您在非裸存储库中执行此操作,那么我们无法将任何文件从非裸存储库推送到裸存储库。
如果您通过在 PC 中创建中央和非裸存储库来练习 GIT,它可能不会在某些 PC 中显示推送的文件,但它已被推送。你可以通过运行来检查它。
中央存储库中的
$git log
。除了推送到 GitHub 之外,它还会显示那里的文件。
You can do:
$git config --bool core.bare true
this can be done in bare or central repository so that it will accept any files that are pushed from non bare repositories.
If you do this in non bare repository then we cannot push any files from non bare to bare repository.
If you are practicing GIT by creating central and non bare repo in PC it might not show the pushed files in some PC's but it has been pushed. you can check it by running.
$git log
in central repo.Other than if you push to GitHub it will show the files there.