6

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
hereswhatidid
  • 738
  • 9
  • 21
  • If you put an `echo` in front of your `git archive` command in your batch file, does it show you what you would expect it to? – Mark Feb 08 '14 at 00:20
  • Yes, it appears to be formatted correctly in the echo output. – hereswhatidid Feb 08 '14 at 00:46
  • Make sure there are no strange characters in your command. It has happened to me that I had "invisible" control caracters in commands... – vonbrand Feb 08 '14 at 01:23
  • I went through and verified no bad characters. – hereswhatidid Feb 09 '14 at 03:38
  • Is this a Windows `.bat` file, or a cygwin bash script? I don't think you can use `$(foo)` to get the output of a command in a Windows `.bat` file - you need to use the bizarre and obscure `for /f "delims=" %%a in ('git diff --name-only %1^^') do set output=%%a`, and then use `%output%` in the subsequent command. You should probably quote it as `"%output%"` too. – clstrfsck Feb 09 '14 at 23:36
  • It is a Windows batch file. Could you post an answer that uses that syntax? – hereswhatidid Feb 10 '14 at 00:07

1 Answers1

10

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.

clstrfsck
  • 14,715
  • 4
  • 44
  • 59
  • what could I do, if I have a larger set of files and I receive the error "The input line is too long. The syntax of the command is incorrect." ? – Biroka May 04 '21 at 12:26