Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy file and its entire history

Tags:

git

Myself and another developer are developing an API accessed by other code. As we change the behaviours of the API to better suit our needs, we release additional versions of the API without deprecating the old versions so that extant applications using the API will not have to update immediately. For example:

$ cat 0.5.php
<?php
$username = $_POST['name'];
?>

$ cat 0.6.php
<?php
$username = $_POST['username'];
?>

When we start a new version, typically we will cp version N-1.php to N.php and code from there. However, if we do this with Git, then we lose the entire blame, diff, and other histories from the file for comparison and reverting. How can I 'forge' this history of the old file into the new file such that blame, log, diff, and such commands "just work" without presenting to them additional flags or arguments such as --follow?

like image 443
dotancohen Avatar asked Nov 30 '22 01:11

dotancohen


1 Answers

You want to use the -C flag. That will detect copies as well as renames, so it can follow the history. diff, blame, and log accept this flag.

Like @madara-uchiha said though: you should look at using tags, and maybe generating your git-x.y files from them instead. You can use something like the following to fetch the contants of a file at a given tag:

git show v0.6:git.php > git-0.6.php

Where v0.6 is the tag you're interested in.

Update:

Here's a small script to do it. This first one assumes your tags are of the form x.y or x.y.z:

#!/bin/bash
versions=$(git tag -l | egrep -o '^[0-9]+\.[0-9]+(\.[0-9]+)?$')
for version in $versions
do
    git show $version:git.php > git-$version.php
done

If you're tags are of the form vX.Y or vX.Y.Z and you want git-x.y.php or git-x.y.z.php as the filename, this works:

#!/bin/bash
versions=$(git tag -l | egrep -o '^v[0-9]+\.[0-9]+(\.[0-9]+)?$')
for version in $versions
do
    git show $version:git.php > git-${version/#v/}.php
done

Run this script as part of your release process, and it will generate all the versions for you. Also, it's pretty easy to drop the git- from the name. For example, > git-$version.php becomes > $version.php.

like image 182
John Szakmeister Avatar answered Dec 09 '22 10:12

John Szakmeister