19

In TortoiseGit and TortoiseSVN it is possible to export all changed files between two revisions, including the directory structure, to an external folder.

Is there a way to do so in Atlassian SourceTree (for Windows)?

BJ Myers
  • 6,617
  • 6
  • 34
  • 50
Ludwig
  • 3,580
  • 2
  • 20
  • 24

5 Answers5

27

Try this:

git archive --output=test_zip.zip HEAD $(git diff --diff-filter=ACMRTUXB --name-only hash1 hash2)

Just replace the hash 1 and hash 2 in the example with the desired commits hash and name the zip file where you want your change to be zipped.

It works for me

Martin Tonev
  • 747
  • 12
  • 21
  • Tqvm, is there any way without clone the project we run your command? I mean in serverside trigger this command and just receive the diff as a copy of project? – Amir Apr 10 '20 at 08:35
  • 1
    You just run the command on the server where the code is. If I understand you correctly – Martin Tonev Apr 12 '20 at 14:19
  • If you want the actual changes between both hashes, `git archive --output=test_zip.zip hash2 $(git diff --diff-filter=ACMRTUXB --name-only hash1 hash2)` should be used (note HEAD being replaced with hash2). Otherwise it will take all files changed between hash1 and hash2, but at the state of HEAD. This is probably not what you want. – 1N4001 Jun 10 '21 at 18:12
  • This won't work if any of files that were there before are no longer there. – zumalifeguard Sep 22 '21 at 02:42
  • 1
    Could you please explain this part of the command `...HEAD $(git...)`? This is in Linux I guess, so how the argument in `$(...)` will be treated? And, what is the PowerShell equivalent? – tarekahf Jan 27 '22 at 14:48
  • I did the following using PowerShell: ```$filelist = @(git diff --diff-filter=ACMRTUXB --name-only hash1 hash2); $files = filelist -join " "; git archive --output=test_zip.zip hash2 $files``` but I am getting error `fatal: pathspec 'file1 file2 file2 ...' did not match any files.`. It seems that the single quote `'` is substituted with the command, so how to fix this problem? – tarekahf Jan 27 '22 at 15:37
3

From within sourcetree:

  • Choose the first commit to start from
  • Hold the shift key
  • Click on the last commit you want to export
  • Right click with the mouse: and choose create patch
  • Set the name of the file to save and you patch is ready

enter image description here


Using CLI:

Open terminal (Icon on the sourcetree icon bar)

Then type:

git diff <sha-1>..HEAD > my_all_commits.diff

It will generate a diff file with all the changes in the given range.


How to generate single patch per commit

git format-patch SHA-1..SHA-1.
This commit will create set of patches per commit with all the changes in the commit. You can then choose to use them all or only to pick those you want to apply tot he second repo.

Good Luck.

Community
  • 1
  • 1
CodeWizard
  • 128,036
  • 21
  • 144
  • 167
  • 6
    Thanks, but this is a .diff, not an export with each changed file existing physically in the same directory structure as there is in the current working directory. – Ludwig May 27 '15 at 13:04
  • Works great, thanks. Creating a patch creates an ASCII path.dif files showing the difference. It also works for getting the difference between the last commit and the current code base. – boardtc Aug 16 '21 at 13:31
2

Here's a solution using 7zip with a Custom Action (Tools > Options > Custom Actions > Add):

Menu caption: > dist.zip

[ ] Open in a separate window
[ ] Show Full Output
[X] Run command silently

Script to run: X:\Your\path\to\7-Zip\7z.exe

Parameters: a $REPO\dist.zip $FILE

(Restart SourceTree after creation for the changes to take effect!)

This action works from the context menu for Unstaged Files and changed files in commits from the Log / History (even with multiple files / multiple commits selected) and will add those files to a "dist.zip" in the repo root. Just note that the file will not be deleted before adding files, so if you want to start from scratch, remember to delete the zip file first.

This has made it so much easier to update live systems with just the files that have changed, in projects where there's no build system involved. I wonder how I was able to live and work for so long without it. :-)

Constantin Groß
  • 10,719
  • 4
  • 24
  • 50
  • If you are using Sourcetree, then Custom Actions can be found in Tool > Options > Custom Actions. – user558720 Jan 31 '19 at 20:45
  • Also, if you hate having to find and delete the file every time like I do, then create a batch file, pass the $FILE parameters to it. Then within the batch file, you can delete the zip file then run 7-zip with the $FILE parameter. – user558720 Jan 31 '19 at 21:42
  • This is great! Can I also add unmodified files to this zip to compare the changes later? – rsp May 26 '21 at 08:38
  • @user8252073 if you also want to add unmodified files, couldn't you just zip up the whole directory? – Constantin Groß May 26 '21 at 08:55
0

Here's how I did it, using a custom action + a bash script. Please note this solution is for Unix, but you should be able to replicate this into a Windows .bat script.

The script

I'm going to save this as: archive-commit.sh

#!/bin/sh
HASH1=${1}
HOWMANYCOMMITS=${2:-1}
HASH2=$(git rev-parse $HASH1~$HOWMANYCOMMITS)
DATE="$(date "+%m_%d_%Y_%H%M")"
FILENAME="deploy-$DATE.zip" # Change this to wherever you want to save the file
git archive -o $FILENAME $HASH2 $(git diff --diff-filter=ACMRTUXB --name-only $HASH1 $HASH2)

When calling for example:

./archive-commit.sh 17f6ca1993018761f7b936d46d2d600d4ee5ef85

It will create a zip of that commit compared to its precedent commit.

The script will also take a last numeric argument, let's say:

./archive-commit.sh 17f6ca1993018761f7b936d46d2d600d4ee5ef85 3

It will create a .zip of this commit + the 2 previous ones (so the total 3).

The custom action in SourceTree

Now to integrate this into SourceTree you can create your custom actions like this (change the script target to where you've saved the script):

enter image description here

I have to create multiple actions, because right now SourceTree isn't able to get the two hashes if you select multiple commits AFAIK.

The Result

Now you'll have a convenient way to export zips when right-clicking over a commit directly in SourceTree.

enter image description here

Edu Wass
  • 1,969
  • 1
  • 21
  • 22
-1

I did this code for custom action on windwos .bat

single commit (Search on google) [question]:Create archive of modified files in GIT via batch file

setlocal enabledelayedexpansion
set output=
for /f %%G in ('git diff-tree --no-commit-id --name-only -r %1^^') do ( set output=!output! "%%G" )
git archive -o update.zip %1 %output%
endlocal

Between to commits (Variation of the top one)

setlocal enabledelayedexpansion
set output=
for /f %%G in ('git diff-tree --no-commit-id --name-only -r %2^^ %1') do ( set output=!output! "%%G" )
git archive -o update.zip %1 %output%
endlocal

You have to set by parameter the $SHA

Community
  • 1
  • 1