git force push current working directory

谁说胖子不能爱 提交于 2019-12-18 01:15:08

问题


I need to git push to remote, and that push need to be current working copy. Because, pushed source is a web host. So, pushed files need to be currently in use. I am sure no one will edit files at the host :)

This question is follow up of these 2 questions, Is it possible to have a git repo inside another git repo and what difference does --bare switch make when initing a git repo?

Edit: bare repo is not what I want, since files need to be directly used on remote machine, and need to be found on the locations where I put them.

Edit2: It is my understanding that bare repo doesn't keep the file hieararchy, and keep repo data in root directory


回答1:


Here is a step-by-step on how to create a git repo on your web host that will allow direct pushes, set it up as a remote for your local repo, and push changes to it. Note that you need to have ssh access to your web host, and have git installed.

On your web host (ssh'd in):

# 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

Now with your local repo (run these git commands inside the repo):

# 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

Now, your changes have been pushed to the checked-out repo on the web host. However, they will not be reflected in the working dir (that is, your changes will not take effect immediately). This is because you have pushed directly to the active branch. To finish up, you need to either

  • manually perform a git checkout -f to update the working dir
  • make a git post-receive hook to do it automatically.

To have instant, automatic deployment with a post-receive hook check out this git site deployment howto.




回答2:


This question is really old, but I found a much better solution (for my situation at least) than the solutions listed here.

From the manual for git config, as of Git 2.3.0:

Another option is "updateInstead" which will update the working directory (must be clean) if pushing into the current branch. This option is intended for synchronizing working directories when one side is not easily accessible via interactive ssh (e.g. a live web site, hence the requirement that the working directory be clean).

So git config receive.denyCurrentBranch updateInstead (on the receiving repository) worked perfectly for me. It allows me to push and updates the working directory of the receiving repository automagically (as long as that working directory is clean when the push happens).




回答3:


While this is rather old it is extremely discouraged to push to a working tree. https://git.wiki.kernel.org/index.php/GitFaq#Unexpected_behavior

A better method would be to create a bare repo mirroring the website's working tree.

All a bare repo is, is a repository with no working tree or rather with no files checked out. The hierarchy exists all things considered and can be checked out. In otherwords, it acts as a host for changes only.

Without knowing the directory hierarchy you are working with for your web, I am going to assume it is a standard website layout using chrooted home EG: /home/user/www

On the server using ssh with git installed:

Create a working tree of the current site

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

Create a bare repository to remote push to from your local system

mkdir /home/user/deploy.git
cd /home/user/deploy.git
git init --bare

Link your working tree repository and your bare deploy repository

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

Now set up a new repo on your local system

git clone ssh://user@example.com/home/user/deploy.git
git branch -a
 *master
  remotes/origin/HEAD
  remotes/origin/master

Now we setup 2 hooks to instantly make changes to your web remote repo when you push to it or if someone else you give access to pushes to it. Since git config receive.denyCurrentBranch ignore will lead to trouble in the long run

On the remote server enable post-update for deploy

cd /home/user/deploy.git/hooks
mv post-update.sample post-update
vi post-update

Change your post-update hook to the below and save

#!/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

Now we set up your web working tree to push its changes to deploy if something is committed to it.

cd /home/user/public_html/.git/hooks
mv post-commit.sample post-commit
vi post-commit

Then change post-commit hook to the following

#!/bin/sh
echo "Pushing changes to deploy [public_html post-commit]"
git push deploy

You still have the option to checkout your web working tree if you need to. This will let you pull your changes from deploy to your web's working tree when you push your local system's master. You can branch, rebase, revert, etc without affecting your web's working tree, without worrying about conflict markers, by instead just using the bare deploy repository. If you need more control over what's committed you can use post-receive instead of or in conjunction with post-update.

Hope this helps someone else looking to do the same as the OP.



来源:https://stackoverflow.com/questions/7152607/git-force-push-current-working-directory

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!