2016-11-29

Ignoring the files after they are commited to git

Lets say you are developing a java application. You always add some features and improve some features, do some bug fixes. So source files are generally very critical to your project. Everytime you develop some features, you compile your code and generate a .jar file or .war file. They are used only required to execute the application or the project. Also, they can be easily regenerated by re-compiling your source code. So these files can be simple kept un-revisioned. Meaning these binary files like .jar files or .war files and their changes can be left untracked.

Creators of git have really thought about this seriously. The solution that they have provide is .gitignore files.

Using .gitignore files

.gitignore files are amazing ways to inform git Don't track changes in these files or folders. .gitignore files are placed generally inside your project main folder with the filename .gitignore . Filename starts with a dot. Also they can be inside other subfolders too. Meaning you can have multiple .gitignore files in project folder structure. gitignore files have one folder or file that needs to be ignored per line.

Sample .gitignore file

#This is a comment
app-data/workspace/*

# To ignore any files that has .o or .a as extension files anywhere
# in the any of the subfolder.
*.[oa]

cache/*
bin/*

# Ignore config main-local.php which is used in the local folder only
config/main-local.php

You can use # to make a particular line as a comment, Empty lines are also allowed. Generally they make .gitignore file quite readable.

Important Note

As per the documentation:

A gitignore file specifies intentionally untracked files that Git should ignore. Files already tracked by Git are not affected; see the NOTES below for details.

Which means, if you add .gitignore file after some period of time after your commencement of the project. It will still indicate the changes as untracked. This was a pain point in one of the project that I was working on.

The idea was to have separate database config specific to my project 1. one for the localhost / dev environment 2. one for QA Environment 3. one for PRODUCTION

lets see

<?php
/******************************* config.php ******************************/
//DEV
$db_host = 'localhost';
$db_name = 'mywebapp';
$db_user = 'ravi';
$db_pass = '*****************';

//QA - with relatively a long password
// $db_host = 'localhost';
// $db_name = 'mywebapp-qa';
// $db_user = 'ravi';
// $db_pass = '**************************';

//PROD - with very safe long password
// $db_host = 'localhost';
// $db_name = 'mywebapp-prod';
// $db_user = 'ravi';
// $db_pass = '*************************************';
?>

Its very obvious that it doesn't need a commit again and again. As its pointless. So its worthy candidate for .gitignore file. Also this will not have impact with my co-developer's database configuration. He can have his own password for the development purpose.

So, I added this to gitignore. but it was in the middle of the project. So git keep saying, in the list of uncommitted files. Bit of research in git documentation i found a wonderful solution

Solution: git rm --cached

How does this work

Generally git rm <filename> marks the file for deletion. This file would be removed/deleted in the next commit.

git rm --cached <filename> would mark the file in the staging area or git index. Git tracks list of files present in the index. So removing the filename from index will tell the git not to track further.

and the .gitignore will ignore the file in the work tree.

Note on this side-effect.

Lets say you are colloaborating this project with your team. So you would certainly push this code to bitbucket / github. When your team member pull this changes something seemingly bad would happen.

It would delete the file in his local folder, Don't get panic. This is fair because you marked that particular file for deletion, and you deleted in your commit. When someone takes that commit or changeset, It would delete in their working tree.

So, How to metigate this ? Simple,

Collaborators needs to backup the file.

backup the config.php before the pull.

When the collaborators backup config.php before the git pull origin master. Once the git pull is done, then they can use that backup file and move with the development.