强制推送当前工作目录的git命令

11
我需要将当前的工作副本git push到远程,因为推送的源是一个Web主机,所以推送的文件需要处于当前使用状态。我确信没有人会在主机上编辑文件 :)
这个问题是这两个问题的后续, 是否可以在另一个git repo内部拥有一个git repo在初始化git repo时使用--bare开关有什么区别? 编辑:裸仓库不是我想要的,因为文件需要直接在远程机器上使用,并且需要在我放置它们的位置找到它们。
编辑2:我的理解是裸仓库不保留文件层次结构,而是将repo数据保存在根目录中。
3个回答

11

以下是创建在Web主机上创建一个允许直接推送、将其设置为本地repo的远程仓库并推送更改的git repo的逐步步骤。请注意,您需要具有Web主机的ssh访问权限并安装了git。

在您的Web主机上(通过ssh登录):

# create an empty repo on  your web host; note its path
mkdir site
cd site
git init

# configure it to allow pushes to the current checked-out branch
# without complaining (direct push)
git config receive.denyCurrentBranch ignore

现在使用您的本地代码库(在该代码库中运行这些git命令):

# create the reference to the web host remote for pushing
# /path/to/the/repo is the path to the repo you made above on the web host:
# it will be an absolute path OR relative to your ssh chroot (depends on the host)
git remote add deploy ssh://your_user@your_host/path/to/the/repo

# finally, push your changes!
git push deploy master

现在,你的更改已经被推送到了Web主机上的检出仓库。但是,它们不会反映在工作目录中(也就是说,你的更改不会立即生效)。这是因为你直接推送到了活动分支。要完成操作,你需要执行以下其中一种:

  • 手动执行git checkout -f以更新工作目录
  • 创建一个git post-receive钩子来自动执行。

要使用post-receive钩子进行即时、自动部署,请查看此Git网站部署指南


嗯,我所需要的一切都是通过recieve.denyCurrentBranch得到的。谢谢 :) - yasar
@yasar11732,请确保您阅读了有关保持工作目录最新的说明。如果没有这样做,您推送的更改将反映在git历史记录中,但不一定是您站点所检出的分支。 - shelhamer
哎呀,这对我来说是一项艰巨的工作,但我还是完成了。谢谢! - yasar
在origin中添加额外的pushurl可能很有用,此外,这篇文章还提供了一个示例,说明如何使用post-update和git reset --hard来更新工作副本:http://jasper.tandy.is/blogging/managing-multiple-working-copies-with-git/ - gauteh

9
这个问题很老了,但我找到了一个比这里列出的解决方案更好的解决方案(至少对于我的情况是如此)。根据 Git 2.3.0 的 手册,有另一种选项“updateInstead”,如果将内容推送到当前分支,则会更新工作目录(必须干净)。该选项旨在在交互式 ssh 不易访问的一侧同步工作目录(例如现场网站,因此要求推送时工作目录保持干净)。因此,git config receive.denyCurrentBranch updateInstead(在接收存储库上)对我非常完美。它允许我推送并自动更新接收存储库的工作目录(只要推送时该工作目录保持干净即可)。

4

虽然这篇文章比较旧,但是强烈不建议向工作树中推送内容。 https://git.wiki.kernel.org/index.php/GitFaq#Unexpected_behavior

更好的方法是创建一个裸仓库来镜像网站的工作树。

所谓裸仓库,就是一个没有工作树或者说没有文件被检出的仓库。总之,目录结构存在,可以被检出。 换句话说,它只是用于托管变更的主机。

如果不知道你的Web所使用的目录层次结构,我会假设它是使用chrooted home的标准网站布局 例如:/home/user/www

在安装了Git的服务器上使用ssh:

创建当前站点的工作树

cd /home/user/public_html
git init
git add .
git commit -m "Initial Commit"

创建一个裸仓库,用于从本地系统推送到远程仓库。
mkdir /home/user/deploy.git
cd /home/user/deploy.git
git init --bare

将您的工作树存储库和裸部署存储库链接起来

cd /home/user/public_html
git remote add deploy /home/user/deploy.git
git remote show deploy
* remote deploy
  URL: /home/user/deploy.git
git push deploy master

现在在您的本地系统上设置一个新的仓库。
git clone ssh://user@example.com/home/user/deploy.git
git branch -a
 *master
  remotes/origin/HEAD
  remotes/origin/master

现在我们设置了2个钩子,可以在你推送到远程仓库或者其他有访问权限的人推送到远程仓库时立即对其进行更改。由于git config receive.denyCurrentBranch ignore会带来长期麻烦,在远程服务器上启用post-update以进行部署。
cd /home/user/deploy.git/hooks
mv post-update.sample post-update
vi post-update

将您的帖子更新钩子更改为以下内容并保存。
#!/bin/sh
echo "Pulling changes into public_html [deploy post-update]"
cd /home/user/public_html || exit
unset GIT_DIR
git pull deploy master
exec git update-server-info

现在我们设置您的Web工作树,以便在提交更改时将其推送到部署。
cd /home/user/public_html/.git/hooks
mv post-commit.sample post-commit
vi post-commit

然后将 post-commit 钩子更改为以下内容。
#!/bin/sh
echo "Pushing changes to deploy [public_html post-commit]"
git push deploy

你仍然可以选择检出你的网站工作树,如果需要的话。这将使你在推送本地系统的主分支时,从部署中拉取你的更改到网站的工作树中。你可以分支、变基、还原等,而不影响你的网站工作树,也不必担心冲突标记,只需使用裸的部署存储库即可。如果你需要更多对提交内容的控制,你可以使用 post-receive 而不是或与 post-update 结合使用。希望这能帮助其他想要做与 OP 相同事情的人。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接