Tools Blog Learn Quizzes Smile API Log In / Sign Up
Tools Blog Learn Quizzes Smile API Log In / Sign Up
« Return to the tutorials list
We have updated our privacy policy to let you know that we use cookies to personalise content and ads. We also use cookies to analyse our traffic and we share information about your use of our site and application with our advertising and analytics partners. By using this website or our application you agree to our use of cookies. Learn more about the way this website uses cookies or remove this message.

Create a tar ball of your recent github commits with PHP

Difficulty: 35 / 50 Tweet

In this tutorial I will show you how to use the "git log" command to create a list of files that have been modified in the last X number of git commits and pack them into a tar ball. This can be very useful for cases when you want to send code updates to a client but you don't have access to their server and they don't want to pull the changes from Github.

  • Step1: Create a file called createpackage.php and place it in the root folder of you project.
  • Step2: To generate an array with the list of files to be packed, run the "git log --name-only --max-count=1" through PHP's built in exec() function. This will generate a list of modified files from the last commit. Of course you can increase the --max-count parameter to get even more commits listed. Then, filter out the "commit details" - you should end up with an array that only contains file names.
          
            <?php
            $res = array();
    
            //get details from last commit
            exec("git log --name-only --max-count=1", $res);
    
            //keep only files names not commit details
            foreach($res as $k=>$string)
            {
              if(!is_file($string))
                unset($res[$k]);
            }
    
            //recount the array
            array_values($res);
            ?>
          
        
  • Step 3: Create a folder where you store these packages (we will refer to this as ALL_PACKAGES throughout this post) if you haven't already created one and also create a directory for this specific package (we will refer to this as PACKAGE_001 throughout this post). I use a timestamp to differentiate between packages but one can even use the commit hash or anything else that makes it easy to find and unique.
          
            <?php
            //specify the folder where packages are
            $packagesfolder = "ALL_PACKAGES";
    
            //create the package folder
            $folder = "PACKAGE_001"; //You would probably want do this instead: "package.".date("m.d.Y.h.i", time());
    
            if(!is_dir($packagesfolder))
              mkdir($packagesfolder);
    
            if(!is_dir($packagesfolder.'/'.$folder))
              mkdir($packagesfolder.'/'.$folder);
            ?>
          
        
  • Step 4: Copy each file to the package folder and use the --parents parameter to recreate the same folder structure leading to the copied file ( Example: if you modified: PROJECT_FOLDER/config/file.php you will get PACKAGE_001/config/file.php ).
          
            <?php
            //copy the files to the package folder and keep the entire folder structure 
            //(eg: if a file is in ... subfolder/sub-sub-folder/file.php ... it will be copied to packagefolder/subfolder/sub-sub-folder/file.php )
            foreach($res as $file)
              exec('cp --parents '.$file.' '.$packagesfolder.'/'.$folder.'/' );
    
            //navigate to the packagefolder and then archive
            chdir($packagesfolder.'/'.$folder);
            exec( 'tar -cf '.$folder.'.tar *' );
            ?>
          
        
  • Step 5: Move the archive in the root packages folder (ALL_PACKAGES) and optionally delete the "PACKAGE_001" folder.
          
            <?php
            exec( 'mv '.$folder.'.tar ../' );
            chdir( '..' );
            exec('rm -rf '.$folder.'/');
            ?>
          
        

Hopefully some of you will find this code useful. If this is the case you can download the entire code from its Github repository.

comments powered by Disqus