Git pre-commit hook not adding file on Windows - windows

I have a pre-commit hook that's running a mysqldump to keep track of MySQL.
I'm trying to add that dump to the commit, but for some reasons it won't.
The code:
#!/bin/sh
rm -f database.sql
exec "C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqldump.exe" --skip-comments -u root --password=password my-database > database.sql
git add database.sql
The file is created, but not added to the commit.
Running TortoiseGit on Windows 7.

I don't know if it will help you, but here a step by step guide, how it works on my windows 10 machine with xampplite.
go to your project git
go to "hooks\"
create file "pre-commit" (without file ending)
go to file properties and give full access to windows user
open pre-commit and paste:
#!/bin/sh
"C:\xampplite\mysql\bin\mysqldump.exe" -u dbuser -ppassword
database_name > database_name.sql
git add database_name.sql exit 0
(-u username -ppassword databasename > file.sql)
file will be stored in project root. between -p and password is NO space.
Now, before every commit a mysql dump will be done and added to the commit.

Related

Prevent git from overwriting file owner upon git pull

I've seen a handful of similar questions on here, but none of the solutions given seem to be working... wondering if they're outdated, or this case is somehow different...so I wanted to open up a new thread to talk about it.
I've run into a frustrating problem where, every time I perform and git pull, it changes the owner to the pull-er's user. What happens then is that the site shows the following error:
Warning: file_get_contents(/var/www/html/wp-content/themes/<my-theme>/resources/views/<changed-file>): failed to open stream: Permission denied in /var/www/html/wp-includes/class-wp-theme.php on line 1207
which can only be fixed by running chown www-data on the changed file.
This will become an issue when more people begin to work on the site, or when important files are change (default template/header/footer..), and the site goes blank until chown is run.
Site details
Laravel, wordpress, ubuntu 18, armor hosting
Git repo stored in custom theme
I've tried a few solutions, but none seem to work, (perhaps because they're implemented incorrectly..)
Solutions I've tried
1: set filemode to false - I set filemode to false, locally and globally, on my local machine and the server in question. I've tried changing the case to "fileMode" too.
2: implement post-update hook - I added a post update hook to automatically update the file permissions/ownership. Here's the script (note that the git repo is in the custom theme):
#!/bin/sh
# default owner user
OWNER="www-data:www-data"
# changed file permission
PERMISSION="664"
# web repository directory
REPO_DIR="/var/www/html/wp-content/themes/quorum-theme"
# remote repository
REMOTE_REPO="origin"
# public branch of the remote repository
REMOTE_REPO_BRANCH="master"
cd $REPO_DIR || exit
unset GIT_DIR
files="$(git diff-tree -r --name-only --no-commit-id HEAD#{1} HEAD)"
git merge FETCH_HEAD
for file in $files
do
sudo chown $OWNER $file
sudo chmod $PERMISSION $file
done
exec git-update-server-info
Let me know if there is anything else worth trying, or if you notice an issue with my code...
All the best,
Jill
You are pretty close to the correct solution.
You need to enable the following hooks:
post-merge, called after a successful git pull
post-checkout, called after a successful git checkout
If you are sure to only use git pull, the post-merge hook is enough.
Enabling both hooks guarantee you the hook is always called at not extra cost.
The content of the hook should be like:
#!/bin/sh
# default owner user
OWNER="www-data:www-data"
# web repository directory
REPO_DIR="/var/www/html/wp-content/themes/quorum-theme"
echo
echo "---"
echo "--- Resetting ownership to ${OWNER} on ${REPO_DIR}"
sudo chown -R $OWNER $REPO_DIR
echo "--- Done"
echo "---"
The script will reset the ownership to OWNER of all files and directory inside REPO_DIR.
I have copied the values from your post, eventually change it to your needs.
To enable the hook you should:
create a file named post-merge with the script above
move it inside the directory .git/hook/ of your repo
give it the executable permission with chmod +x post-merge
Repeat eventually these steps for the post-checkout hook, that needs to be equal to the post-merge hook.
Pay attention to perform a sudo git pull if your user is not root. All the files and directories in the target directory are owned by www-data, you need to perform the git pull command with a superuser privilege or the command will fail.
From the looks of your question, it looks like you are using git pull to deploy in production.
git is not a deployment tool. If you want to deploy your code, I would invite you to write a deployment script.
The first version of your script could be :
# deploy.sh
# cd to the appropriate directory :
cd /var/www/mysite
# change to the correct user before pulling :
sudo -u www-data git pull
An updated version would be to stop depending on git pull.
Ideally : you want to be able to identify the versions of your code that can be deployed to productions, and not depend on the fact that "git pull will work without triggering merge conflicts".
Here is the outline of a generic workflow you can follow :
When you want to deploy to production :
produce some artifact that packs your code from an identified commit : for php code this can be a simple .tar.gz
# set a clearly identifiable tag on target commit
git tag v-x.y.z
# create a tar.gz archive that stores the files :
# look at 'git help archive'
git archive -o ../myapp-x.y.z.tgz v-x.y.z
push that artifact your production server
scp myapp-x.y.z.tgz production-server:
run your deployment script, without calling git anymore :
# deploy.sh :
# usage : ./deploy.sh myapp-x.y.z.tgz
archive="$1"
# extract the archive to a fresh folder :
mkdir /var/www/mysite.new
tar -C /var/www/mysite.new -xzf "$archive"
chown -R www-data: /var/www/mysite.new
# replace old folder with new folder :
mv /var/www/mysite /var/www/mysite.old
mv /var/www/mysite.new /var/www/mysite
Some extra actions you will generally want to manage around your deployment :
backup your database before deploying
hanlde config parameters (copy your production config file ? setup the environment ? ...)
apply migration actions
restart apache or nginx
...
You probably want to version that deploy.sh script along with your project.
My approach works for me.
First, add a file named post-merge to /path/to/your_project/.git/hooks/
cd /path/to/your_project/.git/hooks/
touch post-merge
Then, change it's ownership to same as <your_project> folder(this is the same as nginx and php-fpm runner), in my case, I use www:www
sudo chown www:www post-merge
Then change it's file mode to 775(then it can be executed)
sudo chmod 775 post-merge
Then put the snippet below to post-merge. To understand the snippet, see here(actually that's me).
#!/bin/sh
# default owner user
OWNER="www:www"
# changed file permission
PERMISSION="664"
# web repository directory
REPO_DIR="/www/wwwroot/your_project/"
# remote repository
REMOTE_REPO="origin"
# public branch of the remote repository
REMOTE_REPO_BRANCH="master"
cd $REPO_DIR || exit
unset GIT_DIR
files="$(git diff-tree -r --name-only --no-commit-id HEAD#{1} HEAD)"
for file in $files
do
sudo chown $OWNER $file
sudo chmod $PERMISSION $file
done
exec git-update-server-info
Everything is done, now, go back to your_project folder
cd /path/to/your_project/
run git pull under your_project folder, remember you must run as root or sudo(I remember sudo)
sudo git pull
Now check the new file that pulled from remote repository, see if its ownership has been changed to www:www(if it was as expected, the ownership of the new pulled file should be changed to www:www).
This approach is much better than sudo chown -R www:www /www/wwwroot/your_project/, because it only change the new file's ownership, not all of then! Say I just pulled 2 new file, if you change the whole folder's ownership, it's costs more time and server resources(cpu usage, memory usage...), that's totally unnecessary.

How to sync file sytem of OMV (OpenMediaVault) with Owncloud database

I am running debian with OMV (Openmediavault) and Owncloud setup. I would like to sync the filesystem tree with the database of Owncloud. Because OMV can alter the files without Owncloud updating the database. I was thinking about a bash script.
When I Create delete or move a file it needs to be registered in the database of Owncloud.
This is a little script I created for this purpose.
You will need the Inotify package.
#!/bin/sh
DATADIR="/sharedfolders/Owncloud"
inotifywait -m -r -q -e moved_to,create,delete --format '%w%f' "$DATADIR" |
while read INOTIFYFILE ; do # wait until change is made in the data dir
SCANFILE="${INOTIFYFILE##$DATADIR}" # converting Inotify output to something the owncloud --path option understands
sudo -u www-data php /var/www/owncloud/occ files:scan --path="$SCANFILE" #remove -q to enable logging & scans detected file
done

Using cygwin ssh-agent is running but git is still prompting for passphrase

I'm using cygwin as my terminal on Windows 7. I have found several suggestions to run ssh-agent in cygwin so I don't have to enter my password every time I run a git fetch/pull/push. I added the following to my .bash_profile and restarted my cygwin session:
SSH_ENV="$HOME/.ssh/environment"
function start_agent {
echo "Initialising new SSH agent..."
/usr/bin/ssh-agent -s | sed 's/^echo/#echo/' > "${SSH_ENV}"
echo succeeded
chmod 600 "${SSH_ENV}"
. "${SSH_ENV}" > /dev/null
/usr/bin/ssh-add;
}
# Source SSH settings, if applicable
if [ -f "${SSH_ENV}" ]; then
. "${SSH_ENV}" > /dev/null
#ps ${SSH_AGENT_PID} doesn't work under cywgin
ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi
It looks as if the ssh-agent and ssh-add are run successfully, but I am still prompted for my password.
Initialising new SSH agent...
succeeded
Enter passphrase for /cygdrive/c/Users/<username>/.ssh/id_rsa:
Identity added: /cygdrive/c/Users/<username>/.ssh/id_rsa (/cygdrive/c/Users/<username>/.ssh/id_rsa)
$ ssh-add -l
2048 <fingerprint> /cygdrive/c/Users/<username>/.ssh/id_rsa (RSA)
$ git fetch --all
Fetching origin
Enter passphrase for key '/c/Users/<username>/.ssh/id_rsa':
I am in fact using SSH and not HTTPS for my git connection (redacted private info):
$ git remote -v
origin ssh://git#XXX/XXX.git (fetch)
origin ssh://git#XXX/XXX.git (push)
The closest problem I've found for this issue is the following question:
ssh-agent doesn't work / save me from typing passphrase for git
However, I didn't rename my ssh under /git/bin.
Any suggestions on how to diagnose this issue? Thanks!
Here is an easier solution to this than the one above:
Launch Services (can be found by typing Services in the search
box on the Taskbar)
Edit the settings of the "OpenSSH Authentication Agent"
Set the Startup type to Automatic and Start the Service
Launch the Edit the System Environment Variables (type Environment
in the search box on the Taskbar)
Add GIT_SSH variable with the value set to
"C:\Windows\System32\OpenSSH\ssh.exe"
Now when an SSH key is added, you will not need to continue to type the passphrase in a Windows command prompt or in a Cygwin Bash shell.
The problem is still remain. Seems it is related to the different paths and hasn't been fixed yet.
You may consider to use expect as an alternatif to ssh-agent for login with passphrase interaction.
In Linux it use to be installed like this:
$ sudo apt-get update
$ apt-get install --assume-yes --no-install-recommends apt-utils expect
In cygwin you may find it under Tcl:
Here is a simple step on how to use it.
Create a file, lets locate it and name ~/.expect_push
#!/usr/bin/expect -f
spawn git push origin master
expect "Username for 'https://github.com':"
send "<username>\n";
expect "Password for 'https://<username>#github.com':"
send "<password>\n";
interact
Change the above <username> and <password> to your login id with following notes:
Modify the contents follow precisely to your git login interaction.
If your <password> contain the char $ put it as \$ otherwise the authentication will be failed.
For example if your password mypa$$word then put <password> as mypa\$\$word.
Create another file ~/.git_push
#!/usr/bin/bash
git remote set-url origin git#github.com:<username>/<repo>.git
git add .
git commit -m "my test commit using expect"
expect ~/.ssh/.expect_push
Make them executable and create symlink in /bin
$ chmod +x ~/.expect_push
$ chmod +x ~/.git_push
$ cd /bin
$ ln -s ~/.git_push push
Then you can push to the remote without need to fill in username and password or passphrase
$ cd /path/to/your/git/folder
$ push

Providing password using a variable to become a sudo user in Jenkins

I have a jenkins job, which has its own set of build servers. The process which i follow is building applications on the jenkins build server and then I use "send files or execute commands over ssh" to copy my build and deploy the same using a shell script.
As a part of the deployment commands, I have quite a few steps to be done, like mkdir, tar -xzvf etc.I want to execute these deployment steps with a specific user "K". But when i type the sudo su - k command, the jenkins job fails because i am unable to feed the password to it.
#!/bin/bash
sudo su - K << \EOF
cd /DIR1/DIR2;
cp ~/MY_APP.war .
mkdir DIR 3
tar -xzvf MY_APP.war
EOF
To handle that, I used a PASSWORD parameter and made the build as parameterized, so that i can use the same PASSWORD in the shell script.
I have tried to use Expect, but looks like commands like cd, tar -xzvf are not working inside it and even if they work they will not be executed with the K as a user since the terminal may expire(please correct if wrong).
export $PASSWORD
/usr/bin/expect << EOD
spawn sudo su - k
expect "password for K"
send -- "$PASSWORD"
cd /DIR1/DIR2;
cp ~/MY_APP.war .
mkdir DIR 3
tar -xzvf MY_APP.war
EOD
Note: I do not have the root access to the servers and hence cannot tweak the host key files. Is there a work around for this problem?
Even if you get it working, having passwords in scripts or on the command line probably is not ideal from a security standpoint. Two things I would suggest :
1) Use a public SSH key owned by the user on your initiating system as an authorized key on the remote system to allow logging as the intended user on the remote system without a password. You should have all you need to do that (no root access required, only to the users you already use on each system).
2) Set-up the "sudoers" file on the remote system so that the user you log in as is allowed to perform the commands you need as the required user. You would need the system administrator help for that.
Like so:
SUDO_PASSWORD=TheSudoPassword
...
ssh kilroy#somehost "echo $SUDO_PASSWORD | sudo -S some_root_command"
Later
How can i use this in the 1st snippet?
Write a file:
deploy.sh
#!/bin/sh
cd /DIR1/DIR2
cp ~/MY_APP.war .
mkdir DIR 3
tar -xzvf MY_APP.war
Then:
chmod +x deploy.sh
scp deploy.sh kilroy#somehost:~
ssh kilroy#somehost "echo $SUDO_PASSWORD | sudo -S ./deploy.sh"

MySQLDump from executable on Windows 7

I tried to dump a mysql database with calling a wsh jscript file, but it doesn't work.
I have this code, called with git shell, and it works perfectly:
# If something fails, exit with status other than 0
set -e
# select dump directory
cd "$(git rev-parse --show-toplevel)"
# first, remove our original schema
rm -f "WebShop\DataBase\backup.sql"
# generate a new schema
exec "C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqldump.exe" --skip-comments -u root --password=root webshopdb |sed 's$),($),\n($g' > "WebShop\DataBase\backup.sql"
I tried almost the same code in WSH, but it returns only with the header of the dump file, and doesn't creates the file. I do not have a clue what is working wrong, or how to debug the code... :S
var shellObj = WScript.CreateObject('WScript.Shell');
var exec = shellObj.Exec(
'"C:\\Program Files\\MySQL\\MySQL Server 5.5\\bin\\mysqldump.exe"'+
" --skip-comments -u root --password=root webshopdb |sed 's$),($),\\n($g' > " +
'"D:\\creation\\software developer\\projects\\webshop-refactoring-project\\document root\\WebShop\\DataBase\\backup.sql"'
);
WScript.Echo(exec.StdOut.ReadAll());
I tried with bat files and cmd files too, but they cannot handle the space in the pathes.
Can anybody help?
(For me it would be enough to make somehow an executable from the git code, or make the wsh work... The perfect solution would be if I could call the dump from netbeans, but in life nothing is so ideal... :D )
I made it with file association.
I created a git.bat file:
if not exist %1 exit
set bash=C:\Program Files (x86)\Git\bin\bash.exe
"%bash%" --login -i -c "exec "%1""
And associated it to .hook files.
After that I created a test dump.hook file:
#!/bin/sh
cd "D:/creation/software developer/projects/webshop-refactoring-project/document root/WebShop";
cd "$(git rev-parse --show-toplevel)"
rm -f "WebShop/DataBase/backup.sql"
exec "C:/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump.exe" --skip-comments -u root --password=root webshopdb |sed 's$),($),\n($g' > "WebShop/DataBase/backup.sql"
exit
And it works perfectly.
After 3 days I got it! Woohoo! :D
note: *Windows command prompt usually has problems with whitespace and special characters in the path name, so it is much easier to use the emulated linux of git, than try to fix it. It is possible to source the .hook file into a pre-commit git hook too, so it can automatically dump the database schema by every commit... (maybe the git add not working by those files, I haven't found an auto dump and commit solution yet: git pre-commit + mysqldump: cannot find path, not existing command) *

Resources