How to change the git directory delimiter? - windows

When working inside a windows command prompt, all of my paths indicate director separators with a backslash \, when using GIT commands, all of the paths are instead using forwardslash /. How do I change GIT's output to mirror my command line output?
Example inconsistent directory indicators;
D:\git\demo>git status --s
A test/subdir/foo.txt

How do I change GIT's output to mirror my command line output?
First, all git commands are executed in a git bash sub-shell, which explains why you see '/'.
A '\' is an escape character for a bash session, which is why it is not used in any bash command output.
You would need to use a git wrapper (a git.pat set in your PATH) in order to replace any / by \.
git.bat:
C:\prgs\git\latest\bin\git.exe %*|C:\prgs\git\latest\usr\bin\sed.exe -e 's:/:\\\\:'
Make sure git.bat is set before git.exe in your %PATH%: type where git to check the order in which git(s) are discovered.
And replace C:\prgs\git\latest by the path your Git is installed.
By specifying the full path for git.exe and for sed.exe, you are sure to use the right executable.

Since what you're looking for seems to be not specifically "how do I make Git use \ in file paths" but rather "how do I make Git generate file paths with \", you can pipe the output through sed (which is packaged in Git Bash) like so:
$ git status --s | sed 's/\//\\/g'
M dir\file.py
?? dir\input001.txt
?? dir\output001.txt
and to avoid typing sed every single time you can configure a Git alias to do it for you:
[alias]
ws = "!ws() { : git status ; git status --short $# | sed 's/\\//\\\\/g' ; } && ws"
which will let you do this:
$ git ws
M dir\file.py
?? dir\input001.txt
?? dir\output001.txt

Related

Unexpected question mark in Windows/bash

I'm trying to automatically "archive" some local branches on Windows using the MinGW Bash on Windows.
I copy and pasted the content of git branch on a txt file (branches_to_be_archived.txt) and then I wrote:
A script to archive a single branch
#!/bin/bash
BRANCH_NAME=$1
echo "Branch name is $BRANCH_NAME"
git tag archive/$BRANCH_NAME $BRANCH_NAME
git branch -D $BRANCH_NAME
A script to archive every branch from a file
#!/bin/bash
FILE=./branches_to_be_archived.txt
LINES=$(cat $FILE)
for LINE in $LINES
do
./archive_branch.sh.txt $LINE
done
I inserted some echo prints and they are ok but executing git commands will raise an error like this:
fatal: Failed to resolve '[actual name of the branch]?' as a valid ref.
With a trailing ? that is not shown anywhere.
Any way to avoid having this question mark at the end?
Indeed, it was a endline characters issue (Win CRLF and Linux LF).
I solved by using Notepad++ and setting EOL -> Linux (LF) but I think that dos2unix for branches list file works just fine

Output of a git command read through shell script is adding special characters when passed again to another git command

I have a requirement to delete branches in git repository of a developer who recently left the organization. So I used git for-each-ref to list all the branches then used grep to filter results by developer name (test_developer in the following script). I used shell read and extracted branch into a variable mybr and used git push origin --delete to delete the branch. Please find the code snippet below:
git for-each-ref --format='%(align:1,left)%(color:yellow)%(authorname)%(end) %(color:reset)%(refname:strip=3)' --sort=authorname refs/remotes | grep test_developer | while read line;do mystr=(${line}); mybr=${mystr[1]}; git push origin --delete "$mybr"; done
Issue is am getting output as "fatal: remote part of refspec is not a valid name in :?[mbugfix/CRIP-2475". Here bugfix/CRIP-2475 is the branch name. And I wonder what are those extra characters :?[m that got appended before the branch name.
If I do echo $mybr before git delete I get the value properly printed as "bugfix/CRIP-2475". And if I pass this value manually to git delete, it is working fine. But when it is being passed as a variable, am getting the above error. I suspect there are some special characters being prepended, may be a ctrlM character or something that echo is not printing to the screen.
Is there anyway to remove those extra characters?
Yes you can remove by using Bash sub-string replacement
${str/#find/replace} for replace pre-fix characters
${str/%find/replace} for replace post-fix characters
git for-each-ref --format='%(align:1,left)%(color:yellow)%(authorname)%(end) %(color:reset)%(refname:strip=3)' --sort=authorname refs/remotes | grep test_developer | while read line;do mystr=(${line}); mybr=${mystr[1]}; git push origin --delete "${mybr/#?[m/}"; done
These "magical" symbols are, of course, colors. You shoudn' use colors in pipes:
git for-each-ref --format='%(align:1,left)%(authorname)%(end) %(refname:strip=3)' --sort=authorname refs/remotes | …

Capistrano/Ruby execute is adding a semicolon after a variable

As part of a Capistrano Ruby task that deploys to a server, I'd like it to output the Git message and commit of the code it just deployed.
With this:
git_message = `git log -1 HEAD --pretty=format:%s`
git_commit = `git rev-parse HEAD`
git_commit = "https://example.com/myorg/myrepo/commit/" + git_commit
execute "echo \"Deployed \\\"#{git_message}\\\": #{git_commit}\" | a_command_that_posts_to_slack"
It's outputting something like this:
Deployed "Merge branch 'feature/some-feature' into develop": https://example.com/myorg/myrepo/commit/0fdfa09fbfe012649fb0a998aa2e99cb5fd7c8b3;
Note that semicolon at the very end of the commit hash. I've confirmed using puts that git_commit doesn't end with a semicolon, and git_message doesn't have one, and doesn't have one after it either.
What's adding the semicolon and how can I remove it?
It is because you have newlines in your command, which Capistrano is translating into semicolons, thinking you want to execute multiple commands (one per line).
Backticks in Ruby capture the entire stdout of the process, including trailing newlines. Use chomp to remove them.
git_message = `git log -1 HEAD --pretty=format:%s`.chomp
git_commit = `git rev-parse HEAD`.chomp
git_commit = "https://example.com/myorg/myrepo/commit/" + git_commit
execute "echo \"Deployed \\\"#{git_message}\\\": #{git_commit}\" | a_command_that_posts_to_slack"
Perhaps its executing : as the Bash shell builtin and so its attempting to terminate that command with a semi-colon? Try removing the :. I also worry about inserting double quotes as a commit message containing double quotes might cause you some headache.
Reference on the Bash builtin : What is the purpose of the : (colon) GNU Bash builtin?

What is the syntax for specifying Windows paths in .gitconfig?

I'm trying to use the include.path config described here, but I can't seem to find the correct path syntax on Windows.
My current .gitconfig:
[include]
path = 'D:\Scott\Shared\config\common.gitconfig'
But git complains: fatal: bad config file line 2 in C:\Users\Scott/.gitconfig
What's the proper way to escape paths for Windows? Note: I'm using git from Powershell and not git bash.
Ok, figured this out. The trick is:
Surround in double-quotes
Convert backslashes to forward slashes.
Begin with drive letter + colon for absolute paths
So the correct version of the above is:
[include]
path = "D:/Scott/Shared/config/common.gitconfig"
Based on output of pwd in git bash, I would speculate it is probably
/d/Scott/Shared/config/common.gitconfig

How to print what a bash script is actually running?

I am trying to make a bash script which will:
Add all changes to git
Commit with a message I pass to the bash script
Push it to the repo
I am trying to do this with:
m=\"$*\"
git add -A
echo git commit -m $m
git push
However, I am getting errors saying error: pathspec 'Q2,' did not match any file(s) known to git. for everything word I pass to the script.
How can I see what bash it actually doing? When I put echo in front of the offending line (which I presume is the commit) I get a correctly form command. If I put it in to the terminal, I runs find.
To see what bash is doing, add -xv options to the shebang line:
#!/bin/bash -xv
The problem is probably the quoting. m=\"$*\" does not do what you want. $m is still split into several words if it contains whitespace, just the first word starts with a doublequote and the last word ends in a doublequote.
Rather, change the offending line to
git commit -m "$m"

Resources