Create archive of modified files in GIT via batch file - windows

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.

Related

Batch File to Loop Through Remote Git Branches and Copy a Similar CSV File in Each Branch to a Local Directory

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

Batch Script: Export last git commit message to a variable

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?

Batch adds additional \ in cp path

I wrote a batch script, which is branching my project for svn and want to create docs with sphinx which I then copy into the branched path.
The part where I do this is:
ECHO ##### Creating Docs Branch %VERSION%
cd %~dp0\trunk\Python\MyPackage\docs
call make html
cp -r _build\html %~dp0\branches\%VERSION%\Python\docs\MyPackage
svn add %~dp0\branches\%VERSION%\Python\docs\MyPackage
svn commit %~dp0\branches\%VERSION%\Python\docs\MyPackage -m "Added Docs Branch %VERSION%"
This fails with cp: cannot mkdir "D:/00_Workspace/MyProject/MyPackage//branches/1.1.0/Python/docs/MyPackage": Path could not be found
Apparently there is a second / added between MyPackage and branches
Why does this happen?
Here is the full version of the batch
#echo off
set "VERSION=%1"
set "COMMON_VERSION=%2"
if "%VERSION%"=="" set /p VERSION=Enter the version number you want to create the branch for?:
if "%COMMON_VERSION%"=="" set /p COMMON_VERSION=Enter the version number of the common python toolchain you want to use?:
set PACKAGE_NAME=%~dp0
ECHO ##### Updating SVN Repository
svn update
ECHO ##### Creating requirements.txt
cd trunk
call python create_requirements_txt.py %VERSION% %COMMON_VERSION%
svn add requirements.txt
svn commit requirements.txt -m "Updated requirements.txt to version %VERSION%"
cd %~dp0
ECHO ##### Creating Branch for version %VERSION%
for /f "delims=" %%i in ('svn info ^| FINDSTR /R /C:"Relative URL"') do set URL=%%i
set "URL=%URL:*: =%"
for /f "delims=" %%i in ('svn info ^| FINDSTR /R /C:"Repository Root"') do set ROOT=%%i
set "ROOT=%ROOT:*: =%"
set "DEST_URL=%ROOT%%URL:*\trunk=%/branches/%VERSION%"
set "SRC_URL=%ROOT%%URL%/trunk"
ECHO ##### Package: %PACKAGE_NAME%
ECHO ##### Source: %SRC_URL%
ECHO ##### Destination: %DEST_URL%
call svn copy %SRC_URL% %DEST_URL% -m "Branch %PACKAGE_NAME% Version %VERSION%"
ECHO ##### Succesfully created branch %VERSION%
call svn update
ECHO ##### Creating Docs Branch %VERSION%
cd %~dp0\trunk\Python\MyPackage\docs
call make html
cp -r _build\html %~dp0\branches\%VERSION%\Python\docs\MyPackage
svn add %~dp0\branches\%VERSION%\Python\docs\MyPackage
svn commit %~dp0\branches\%VERSION%\Python\docs\MyPackage -m "Added Docs Branch %VERSION%"
pause
exit /b 0
:SVN_ERROR
ECHO ##### SVN Error: Either Source Repo (%SRC_URL%) does not exist or the Tag (%DEST_URL%) already exists!
pause
exit /b 1
As #elzooilogico said
%~dp0 contains drive letter plus path from where script is run ended with backslash. change svn add %~dp0\branches\%VERSION%\Python\docs\MyPackage with svn add %~dp0branches\%VERSION%\Python\docs\MyPackage and all similar paths.
that should work.

How do I get the output from a call to GIT into a variable in a batch script?

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

How to get the latest git tag on Windows?

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

Resources