Git Hook under Windows - windows

I have the following code to checkout in a working directory in the hook post-receive:
#!/bin/sh
git --work-tree=d:/websites/__gitweb --git-dir=d:/_gitrepo.git/ checkout -f
Unfortunately it doesn't seem to work. However, the command does work when I enter just this in the windows command line (cms):
git --work-tree=d:/websites/__gitweb --git-dir=d:/_gitrepo.git/ checkout -f
I have checked the permissions and the executing attributes but nothing.
UPDATE:
I think I'm getting closer. Now I know what the problem is but I don't know why is this happening. The hook is actually being triggered but I receive this message:
remote: Starting copy from repository to work tree...
remote: fatal: Not a git repository: 'd:/_gitrepo.git/'
remote: Finished.
I have tried to change the path of d: to the whole network path but it still doesn't work. If I go to the remote repository and I do a git log, the changes are there and if I run the hook with sh, it works.
Why is it saying that it is not a git repository when clearly it is?

I finally got it working!
This is really weird. I had to type a pwd to see where actually is the batch being located and it showed the hook location on the server. However, in the next line I added a hostname and it showed me my local hostname.
Then I add the whole path just like:
#!/bin/sh
echo "Starting copy from repository to work tree..."
pwd
hostname
git --work-tree=//remotehost/d$/Webseiten/__gitweb --git-dir=//remotehost/d$/_gitr
epo.git checkout -f
echo "Finished."
I hope this solution works for someone

For a shell script (and those hook scripts will be executed as shell, even in Windows, through the msys layer of msysgit), you could use a different sort of path:
#!/bin/sh
git --work-tree=/d/websites/__gitweb --git-dir=/d/_gitrepo.git/ checkout -f
See also other possibilities with "Posix path conversion in MinGW"

Related

Issues with git hooks permissions on Windows

I have a bare git repository running on a Windows machine, and I am trying to have it run a post-receive hook. I have the following in the hooks/post-receive file
cmd //c "activate <some-env> && do-something"
which works nicely if it is run manually from Git Bash. However, it doesn't run after a commit is pushed.
The file's permissions, as obtained from Git Bash by doing ls -lh, are 644. This may be the issue, but chmod +x <file> has no effect. Neither does git update-index --chmod=+x <file>, as suggested elsewhere - this results in fatal: this operation must be run in a work tree (I guess this is not meant for a bare repository). The permisions in the sample hooks are well set, but if I do echo <my-command> > some-hook.sample the execute permissions are lost. This is also the case if I modify the file using e.g. Notepad++.
How does one change the execute permissions in this case?
Thanks!

Git for Windows "No tags file" Response from "git diff" Command

Git version: 2.14.2.2
Whenever I run git diff on a repository I am greeted with the response No tags file. I have tried running the command on multiple repositories, multiple consoles (Cmd, PowerShell, MINGW64, Visual Studio Command Prompt) and all have the same response.
Strangely, the git log command also fails. Many other commands work, however, such as git status, git pull, etc. It seems to be only log and diff.
I have uninstalled Git entirely and reinstalled. Restarted my system. Tried referencing the git.exe directly (which yields the exact same response). Nothing is working and I have not seen this error anywhere else. I compared my user configs with those of a colleague and they are identical.
Some portion of the command executes properly, because if I supply two commit hashes, and I intentionally break one, the response I receive is:
It seems like another program may be hijacking the git diff command. I believe this because I'm not sure "No tags file" is even a possible Git response. Not sure what else it would be.
To make things even more confusing- my ultimate goal is to run the git diff within the context of an msbuild and it DOES EXECUTE CORRECTLY. Now, I could be satisfied with this, but I need to modify the diff command slightly, and running a full build each time is not productive, nor easy to troubleshoot. There is a task within the build script that runs an Exec command and it has no issues performing the diff. I'm also able to execute a Diff Against Current within SourceTree, which to the best of my knowledge, runs a git diff behind the scenes.
Any help would be very much appreciated.
:: Edits ::
Various commands:
git diff HEAD~1 HEAD
git diff master~1 master
git diff <commit-hash-1> <commit-hash-2>
git log HEAD~1..HEAD
git log master~1..master
git log <commit-hash-1>..<commit-hash-2>
Output:
Every one of the commands above returns the same No tags file response, in all of my repos.
Cat Head:
cd .git
cat HEAD
ls -R refs
Output:
New Repo:
mkdir testrepo
cd testrepo
git init
echo "file1" > file1.txt
git add .
git commit -m "initial commit of file1.txt"
echo "Hi there!" > file2.txt
git add .
git commit -m "added file2.txt"
git log
git diff HEAD~1 HEAD
Output:
git config -e:
git config --global -e:
::Edits 2::
I uninstalled all of my diffing/source control tools (SourceTree, Git, SVN, WinMerge, KDiff). Installed the portable version of Git. Opened CMD to a repo, put in full path to the git.exe portable and it still returned the No tags file response.
I also reviewed all of my path variables for: git, vim, ming, mintty and anything else that seemed suspect, but didn't find any.
I have restarted after performing all steps, and yet the problem persists.
::Edits 3::
I have a different user on my laptop, switched to that user and the git diff works properly, so clearly there is something with my main user that is conflicting. Will continue to look into my User directory for issues.
Here are the steps I'd take in this situation:
Try the following and check the response:
git diff HEAD~1 HEAD
git diff master~1 master
git diff <commit-hash-1> <commit-hash-2>
Try the same with log:
git log HEAD~1..HEAD
git log master~1..master
git log <commit-hash-1>..<commit-hash-2>
I'm actually guessing that your refs are messed up, which means that the direct hashes might work, but the HEAD and/or master one may not.
Look into the .git/refs folder
From the main repo folder:
cd .git
cat HEAD
ls -R refs
Hopefully, HEAD is pointing to a branch, and if master is checked out, cat HEAD output should look like:
ref: refs/heads/master
Then, the ls -R refs, should show a heads folder, with files for each of your local branches (i.e. master and possibly others). You also likely have refs/remotes and refs/tags directories.
If any of these things are radically different or missing, that could be your issue...
Since you have reinstalled git, create a brand new repo and try the same commands:
mkdir testrepo
cd testrepo
git init
echo "file1" > file1.txt
git add .
git commit -m "initial commit of file1.txt"
echo "Hi there!" > file2.txt
git add .
git commit -m "added file2.txt"
git log
git diff HEAD~1 HEAD
If this last one works, then git is likely working okay, but some tool you have is messing things up.
Post your config from git config -e and git config --global -e - maybe we can see something?
When googling for the "No tags file" message, the first results I get all talk about vi.
I do not understand why git would try to execute vi when running git diff or git log, could it be that your system is configured to use vi as a pager ?
# some possible places which could influence that :
echo $PAGER
echo $GIT_PAGER
git config --get core.pager
When digging in the documentation for less, I found that less can use a ctags file, to spot "the file that contains this tag".
So you can also look at the list of variables that influence the behavior of less :
# from bash :
# env will list all the defined environment variables
env
# the ones that impact 'less' should contain "LESS" in their names :
env | grep LESS

Git pre-commit hook is not running on Windows

I'm just starting to look into Git hooks, but I can't seem to get them to run.
I set up a local repository, so there is now a '.git' directory in my project folder. I have added a '.cmd' file into the C:/path/to/my/project/.git/hooks directory named 'pre-commit.cmd'. Here is the contents of this file:
echo "HOOK RUNNING"
echo. 2>C:/path/to/my/project/.git/hooks/EmptyFile.txt
This should echo the text "HOOK RUNNING" and create an empty text file in that directory. However, if I commit changes through my IDE (NetBeans) or use Git Bash to commit, neither of them seem to run my pre-commit hook, as no file is created.
My understanding is that all you have to do to get a hook to run is add an executable with the name of the hook (as I have done). Am I doing something wrong?
Note: This is on a Windows 7 PC.
Name your hook pre-commit (without any file extension).
And add #!/bin/sh on the first line or #!/bin/bash.
You probably don't have the permissions to run the pre-commit file
Run in your terminal:
chmod +x .git/hooks/pre-commit
Thanks to #vaughan for giving the idea
TL;DR
Git hooks work on Git for Windows by default assuming the Git hook script is simple.
Background of Git and Windows
Please Note: Git was made for shell interpretation; thus, using Git hooks on a Windows command prompt or Windows-made PowerShell will inherently have its flaws, and complete interoperability is not to be expected.
Using Git hooks on Windows is possible, but it has many drawbacks.
Git for Windows uses a shell emulator that makes Bash and shell commands possible. This means that when a Git hook is activated by Git, the Windows version will run the command using the shell emulator. Which in turn, will convert those shell commands to commands that the Windows operating system can understand. Meaning, simple shell scripts will work right off the bat. For example, the Git hook pre-commit that ships with an initialization of a Git repository can be run without any modification.
Example of default behavior
Initialize a Git repository with the command git init
Navigate to the Git hooks directory with the command cd .git\hooks
This directory holds all the Git hook scripts. Create a file named pre-commit. Note:
The name of the file is important
Replace the contents with the following shell script
#!/bin/sh
echo "Hello, World!"
Navigate back to your root directory of the project and create a file named test.txt using the command echo "something" > text.txt
Stage the file to commit using the command git add test.txt
Commit the change and watch the pre-commit hook activate using the command git commit -m "test commit"
Verify the output to look like the following
git commit -m "test commit"
Hello, World!
[master f00ccea] test commit
Example of bad behavior
When using a very advanced shell script to do things in Git hooks, Windows shell interpretation doesn't always stack up. For example, when using the Husky Git hook plugin for NPM, along with the Prettier formatter, the commands do not map 1-1. Meaning that your pre-commit Git hook will fail on Windows.
Answering user1578653's question
A Git hook is an executable script; however, you are using a command prompt script (.cmd) and not a shell script (.sh). If you would like this behavior you described on a Windows operating system then create the file named pre-commit and place it in the .git\hooks directory (relative to the project you are working on). Then place the following content in that file.
.git\hooks\pre-commit
#!/bin/sh
echo "HOOK RUNNING"
thisCausesError 2> .git/hooks/EmptyFile.txt
You will notice that the Git hook works and outputs the words HOOK RUNNING to the console, and the thisCauseError will print an error message to standard error that will be printed to the file EmptyFile.txt.
In my case, I had set core.hooksPath to the wrong directory.
Resetting it with git config --global core.hooksPath '~/.githooks' solved the issue :)
You can verify your hooks path using git config --get core.hooksPath
For me, I tried to run a .bat file.
I discovered that backslashes need to be escaped:
For example:
#!/bin/bash
C:\\somefolder\\somefile.bat
For me, none of the previous solutions worked. I moved the pre-commit file from hooks to some other location, effectively deleting the file from hooks.
That worked for me :D
In my case, where I did npm install and accidentally deleted the .git folder, npm install pre-commit --save worked.
If it helps anyone:
I was getting the following error:
error: cannot spawn .git/hooks/pre-commit: No error
It turned out that in my pre-commit file I did not have 'newline' character after last exit command:
#!/bin/sh
# From gist at https://gist.github.com/chadmaughan/5889802
# Stash any unstaged changes
git stash -q --keep-index
# Run the tests with the Gradle wrapper
./gradlew test --daemon
# Store the last exit code in a variable
RESULT=$?
# Unstash the unstashed changes
git stash pop -q
# Return the './gradlew test' exit code
exit $RESULT
# << must have a newline after the above command >>
I was running a Gradle project on Windows and Gradle commands in the Cmder shell and cmd.
I tried solutions suggested in other answers and it didn't help to fix this problem:
cannot spawn .git/hooks/pre-commit: No such file or directory
The solution, which worked for me, was to rename the file .git/pre-commit.sample to .git/pre-commit and insert the script for formatting changed files with Prettier. The file with the name 'pre-commit' which I have created manually must have had some problems (encoding or end-line symbols remains unclear).

Update file with Git on Windows

I recent installed Git and I'm trying to update a file using this command:
(On windows 7)
git add Probe.txt
But it says "fatal: pathspec 'probe' did not match any files"
I'm in the directory which the file is. In fact, if I try git status I get "modified: Probe.txt".
How should I update my file?
try git add . which will add everything. Not sure why the specific filename isn't working, but this definitely should.
Looks like you're actually entering a space after "Probe" for some reason, observe:
~% cd /tmp
/tmp% mkdir foo
/tmp% cd foo
foo% git init
Initialized empty Git repository in /tmp/foo/.git/
foo% git add probe .txt
fatal: pathspec 'probe' did not match any files
foo%
I'm not on Windows at the moment but I think you can get the idea.
If you're pretty sure it's not the case, please re-try your command after setting
set GIT_TRACE=1
and update your question by the output of git add Probe.txt so we could guess further.

Git with SSH on Windows

I've went through the excellent guide provided by Tim Davis which is about configuring Git to work with SSH under Windows in order to produce a Git Server in order to have a main place for my DVCS.
I am in the process of creating a clone for my project. I’ve went through all the steps till this point, but I keep getting this from TortoiseGit:
git.exe clone -v “ssh://Administrator#127.0.0.1:22/SSH/Home/administrator/myapp.git” “E:\GitTest\myapp”
bash: Administrator#127.0.0.1: command not found
Initialized empty Git repository in E:/GitTest/myapp/.git/
fatal: The remote end hung up unexpectedly
Success
and nothing gets cloned.
BTW: The TortoisePLink comes up just before this message appears and asks me: “login as:” ( I thought that this info is given in the command, i.e: Administrator#blahblah.
My home variable is set to the correct place:
From a Git Bash shell:
echo $HOME
/c/SSH/home/Administrator
I’ve also tried using Putty’s plink instead of TortoisePLink (in both Git’s and TortoiseGit’s installation). This time the error was narrowed down to:
git.exe clone -v “ssh://Administrator#127.0.0.1:22/c:/SSH/Home/administrator/myapp.git” “E:\GitTest\myapp”
Initialized empty Git repository in E:/GitTest/myapp/.git/
fatal: The remote end hung up unexpectedly
I fought with this problem for a few hours before stumbling on the obvious answer. The problem I had was I was using different ssh implementations between when I generated my keys and when I used git.
I used ssh-keygen from the command prompt to generate my keys and but when I tried "git clone ssh://..." I got the same results as you, a prompt for the password and the message "fatal: The remote end hung up unexpectedly".
Determine which ssh windows is using by executing the Windows "where" command.
C:\where ssh
C:\Program Files (x86)\Git\bin\ssh.exe
The second line tells you which exact program will be executed.
Next you need to determine which ssh that git is using. Find this by:
C:\set GIT_SSH
GIT_SSH=C:\Program Files\TortoiseSVN\bin\TortoisePlink.exe
And now you see the problem.
To correct this simply execute:
C:\set GIT_SSH=C:\Program Files (x86)\Git\bin\ssh.exe
To check if changes are applied:
C:\set GIT_SSH
GIT_SSH=C:\Program Files (x86)\Git\bin\ssh.exe
Now git will be able to use the keys that you generated earlier.
This fix is so far only for the current window. To fix it completely you need to change your environment variable.
Open Windows explorer
Right-click Computer and select Properties
Click Advanced System Settings link on the left
Click the Environment Variables... button
In the system variables section select the GIT_SSH variable and press the Edit... button
Update the variable value.
Press OK to close all windows
Now any future command windows you open will have the correct settings.
Since this keeps coming up in search results for making git and github work with SSH on Windows (and because I didn't need anything from the guides above), I'm adding the following, simple solution.
(Microsoft says they are working on adding SSH to Visual Studio, and GitHub for Windows still doesn't support SSH...)
1. I installed "git for Windows" (which includes ssh and a bash shell)
https://git-scm.com/download/win
2. From the included bash shell (which, for me, was installed at: C:\Program Files\Git\git-bash.exe)
cd to the root level of where you want your repo saved (something like: C:\code\github\), and
Type:
eval $(ssh-agent -s) && ssh-add "C:\Users\YOURNAMEHERE\.ssh\github_rsa"
3. Type: (the SSH link from the repo)
git clone git#github.com:RepoName/Project.git
you are using a smart quote “ instead of " here:
git.exe clone -v “ssh://
^^^
Make sure you use the plain-old-double-quote.
I've found my ssh.exe in C:/Program Files/Git/usr/bin directory.
If Git for windows is installed, run Git Bash shell:
bash
You can run ssh from within Bash shell (Bash is aware of the path of ssh)
To know the exact path of ssh, run "where" command in Bash shell:
$ where ssh
you get:
c:\Program Files\Git\usr\bin\ssh.exe
I was trying to solve my issue with some of the answers above and for some reason it didn't work. I did switch to use the git extensions and this are the steps I did follow.
I went to Tools -> Settings -> SSH -> Other ssh client
Set this value to C:\Program Files\Git\usr\bin\ssh.exe
Apply
I guess that this steps are just the same explained above. The only difference is that I used the Git Extensions User Interface instead of the terminal. Hope this help.
When I typed where ssh it showed me multipe ssh.exe
user#pc MINGW64 /c/dev/
$ where ssh
C:\Users\user\AppData\Local\Programs\Git\usr\bin\ssh.exe
C:\Windows\System32\OpenSSH\ssh.exe
Deleting / moving these exe helped:
# copy from
# C:\Users\user\AppData\Local\Programs\Git\usr\bin
# to something like
# C:\Users\user\AppData\Local\Programs\Git\usr\bin\backup-ssh
ssh-agent.exe
ssh.exe
ssh-add.exe
This solved the issue for me.

Resources