I'm trying to assign the last commit message inside a git repository to a variable in a windows batch script and then export the variable. From a lot of questions from StackOverflow, it seems that the command should be:
for /f "Tokens=2" %a in ('git log -1 --pretty=%B') do #set commit_message=%a
export %commit_message%
But it's giving the following error.
fatal: ambiguous argument '%B': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
In Linux it is quite straight forward. Only export commit_message=$(git log -1 --pretty=%B).
It looks like you can't parse the git command directly. This worked on my site:
#echo off
git log -1 --pretty=%%B > %temp%\git.txt
for /f "Tokens=*" %%a in (%temp%\git.txt) do #set commit_message=%%a
echo %commit_message%
::export %commit_message%
Note the doubled '%'. I'm not sure about that export command. I've never seen this. Maybe setx is what you need?
Related
I'm very new to batch scripting.
To elaborate on my question, there's a specific file that's found in many different remote git branches, each csv file being different in its contents across the branches, but similar in naming convention. I am trying to write a batch file that loops through each remote git branch and copies this file to a local directory.
Thankfully, each remote branch follows the same naming convention: a 3-digit-ID, an underscore, and the word update (e.g. 018_update). The source directory has the following naming format: a 3-digit-ID, a space, and a text-based name with spaces (ex: \018 To Shreds - You Say).
I've gotten as far as being able to get the branch names into a list, and then looping through each one, but now I'm stuck. One issue I'm wondering how to navigate is whether I'll be able to use a wildcard on the %%a to extract the 3-digit-ID from the remote branch name and use it to locate the directory (and filename) that also both contain the 3-digits in there.
Here's what I've written so far:
FOR /F "tokens=*" %%a IN (
'git branch -r --list "*???_update*" '
) DO (
git checkout %%a
)
)
Assuming this is the right direction to go, I feel that all that's left would be to find a way to get the 3-digit-ID from the remote branch name (i.e. %%a) and use it to make a wildcard and locate the file I want to copy/paste out of there.
Thank you in advance for anyone able to help me tackle this!
This demonstrates how to parse strings of the form <origin>/<###_name*> into two variables %%a and %%b, then set _id equal to the three digit prefix of the branch name. If your branch names look more like <origin>/*###_name*, then we'll have a little more work to do, and I can help you with that later on.
#setlocal EnableExtensions
#for /F "tokens=1,* delims=/" %%a in ('git branch -r --list *???_upate*') do #call :DoIt "%%a" "%%b"
#exit /b
:DoIt
#REM Ignoring %1, corresponding to %%a, because it's the name of the remote.
#set "_b=%~2"
#set "_id=%_b:~0,3%"
#echo _id
#REM Use _id to find your directory and file name here.
#exit /b 0
I have a git command to get the latest SHA of the current repo as follows:
git log --pretty=format:"%H" -n 1
I have a windows batch script I'd like to use this in as follows:
SET CURRENT_SHA=???
But I'm at a loss as to how to get the output from that call to git into the variable so that I can make use of it.
Edit
I've tried the following (which seems to be the general advice I've read here and elsewhere):
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "tokens=* USEBACKQ" %%i IN (`git log --pretty=format:"%H" -n 1`) DO (SET CURRENT_SHA=%%i)
ECHO Current Sha: %CURRENT_SHA%
..but I get:
fatal: failed to stat 'format:i) ECHO Current Sha: 48bce83e800b96607afb2a387c4fcd7b0b0f037e
So presumably there's a problem with the quotes?
I don't have a Windows system handy to test, but I think something along these lines:
FOR /F %i IN (`git log --pretty=format:"%%H" -n 1`) DO SET CURRENT_SHA=%i
Note that the "%H" needs to be escaped, but to use this line in a batch file you also need to double escape everything. You may also need to escape the double-quotes with ^. I think this ought to work:
SETLOCAL ENABLEDELAYEDEXPANSION
for /f "tokens=* USEBACKQ" %%a in (`git log --pretty^=format:"%%H" -n 1`) do (SET CURRENT_SHA=%%a)
ECHO Current Sha: %CURRENT_SHA%
But really, if you want to do shell programming in Windows just use Powershell and then you can do:
$CURRENT_SHA=git log --pretty=format:"%H" -n 1
I want to checkout the latest git tag on Windows.
I use the following command on Linux:
git checkout `git describe --tags --abbrev=0 origin/master`
Whats the equivalent for this command on Windows?
I tried using for & set to expand the backticked command into a variable for usage on the git checkout.
I started out with:
for /f %a in ('git describe') do (echo %a).
It returns v1.0.18-131-g792d5a2. This works, but contains a bit too much information. I just need v1.0.18. That's why i'm trying to use --abbrev=<n> to suppress the long format and only show the closest tag.
When i added the arguments:
for /f %a in ('git describe --tags --abbrev=0 origin/master') do (echo %a)
it fails with: fatal: Not a valid object name 0. Not sure why...
Here is what i got so far:
checkout-latest-tag.bat
#echo off
for /f "usebackq delims=" %%a in ('git describe --tags --abbrev=0 origin/master') do (
set LATEST_TAG=%%a
)
echo The latest tag is: %LATEST_TAG%
git checkout %LATEST_TAG%
It would be nice, if you could come up with a one-liner.
Use ^ to escape the offending =.
for /f %%a in ('git describe --tags --abbrev^=0 origin/master') do git checkout %%a
I'm using this git command to create an archive of the files modified within a specific commit:
git archive -o update.zip HEAD $(git diff --name-only COMMITID^)
where COMMITID is the id of the commit I'm looking to archive. This works fine from the command line but I would like to run it from a batch file. Here are the contents of the batch file I'm using:
git archive -o update.zip HEAD $(git diff --name-only %1^^)
where %1 is the commit id being passed in via SourceTree. The problem I'm having is that this command when run from a batch file returns the following error:
error: unknown option `name-only'
I'm guessing there may be some character escaping issues going but I'm unable to find what is specifically breaking.
How would I write that git command so that it will work from a batch file?
UPDATE
I tried removing the --name-only option and received the following error when trying the batch script via SourceTree:
fatal: path not found: $(git
Hopefully that helps narrow down what may be going on.
FURTHER UPDATE
Turns out my syntax was wrong for grabbing only the modified files from a specific commit but using msandiford's answer I came up with this batch file script that works perfectly:
setlocal enabledelayedexpansion
set output=
for /f "delims=" %%a in ('git diff-tree --no-commit-id --name-only -r %1^^') do ( set output=!output! "%%a" )
git archive -o update.zip HEAD %output%
endlocal
Assuming you need a windows batch file, and not a bash script, here is a minimal batch file that may do what you want:
setlocal enabledelayedexpansion
set output=
for /f "delims=" %%a in ('git diff --name-only %1^^') do ( set output=!output! "%%a" )
git archive -o update.zip HEAD %output%
endlocal
It works by collecting all lines of the output of the git diff ... command into an environment variable, and then using this to perform the git archive ... operation.
Documentation for the Windows for command is here, including the /f switch. Documentation for the setlocal command is here.
In a batch file, I am trying to fetch the output of a command and save it to a variable.
The goal of my command is to count the number of folders in a certain folder.
I can't use the trick provided in this accepted answer because I would have to do cd path\to\my\folder to get to the current directory. Unfortunately, I can't do this command because path\to\my\folder is in fact a UNC path (\\path\to\my\folder), and cd \\some\UNC\path is not supported by the windows cmd.
I am aware of this answer but I don't want to use a temporary file.
So I tried to do the following:
To obtain the number of folders, I use:
dir \\path\to\my\folder | find /c "<REP>"
This works fine and returning me a number as I would expect.
To retrieve the output of this command in a batch variable, I tried:
FOR /F "TOKENS=*" %%i IN ('\\path\to\my\folder | find /c "<REP>"') DO
SET value = %%i
But without success, the error message being...
| was unexpected.
...when I execute the batch file and...
%%i was unexpected.
when I try to execute the command directly in a command window. I tried to escape the quotes around the <REP> string (...find /c ""<REP>""') DO...), got me the same error.
Am I on the right path to retrieve the output in a variable? What should I do to resolve the error message?
Or maybe there is a simpler way to set a command output in a variable?
You can use the answer you first mentioned. You don't have to cd there, but you can use pushd which will allocate a temporary drive letter for UNC paths which will be released when you do a popd.
So in essence:
pushd \\server\path
set count=0
for /d %%x in (*) do set /a count+=1
popd