[Android] Accessing your application files from Android Studio

While learning to play with SQLite databases in Android, I wanted to check the .db file generated by my code in the emulator. I was unable to find it directly with the built-in Files application because it doesn't let us see system folders.

The built-in Files app

Fortunately, Android Studio 3+ comes with the Device File Explorer, which allows us to browse system files and access the root data folder. To open it, go to View > Tool Windows > Device File Explorer. My application data was stored in /data/data/.

How to display the Device File Explorer

How to see the data stored in sqlite in android studio using genymotion as emulator

[Git] List the files which have been modified between two commits/tags

I needed to know the exact list of files that had been modified between my last two tags:

git diff --name-only v2.0.0 v2.0.1

You can replace the tags by commits:

git diff --name-only SHA1 SHA2
git diff --name-only HEAD~10 HEAD~5


Merge two versions of a file with git-checkout

I have slightly different i3 configuration files between my desktop and laptop computers. In this case, the laptop keyboard is missing a Play/Pause multimedia key. This is where the two files differ: the laptop has a different key binding for running the music player.

Having recently added new key bindings to the desktop configuration, I wanted to merge those new lines into the laptop configuration file, without overwriting its specific lines. After trials and errors and thanks to precious clues found on the Internet, I found the patch flag of git-checkout. From the branch specific to my laptop configuration, I ran:

$ git checkout -p master .config/i3/config

This displays an output similar to git-diff, based on the local file .config/i3/config and the one in the branch 'master'. For each conflicts, Git asks:

Apply this hunk to index and worktree [y,n,q,a,d,/,j,J,g,e,?]?

I answered 'n'o to preserve the part specific to the laptop, and 'y'es for the new key bindings I wanted to copy.

Output of $ git checkout -p

Nuke (remove all traces) of a file in Git history

First note: if you are not alone on the project, consult with your colleagues before doing this. Because we are about to rewrite history and other contributors will be forced to manually rewrite their history too.

Second note: if what you want to remove is sensitive material (e.g. passwords), consider everything compromised. Unless you are 100% sure that absolutely no one has had any access to your repository. And you are not, are you? Even with your super-secure unbreakable security measures... No, you are not.

Okay, you have been warned.

Let's say we want to remove all traces of a file named "hardcoded_passphrase.txt". We need the sha1 of the commit where this file first appeared. If you don't know, just use the first commit. In this example, the sha1 is bb9c2d4:

$ git filter-branch --index-filter 'git update-index --remove path/to/hardcoded_passphrase.txt' bb9c2d4..HEAD
$ git push --force --verbose --dry-run
$ git push --force


Install PHP CodeSniffer with PEAR

This article should be useful for other tools than CodeSniffer. To put some context, I installed PEAR some time ago for PHPUnit, before I read that PHPUnit had moved away from PEAR and can now be installed using Composer or a simple PHAR (PHp ARchive) file. I had troubles with the default PEAR configuration and the various steps to add the right folders in the system $PATH, PHP configuration, ... and my stubbornness to have everything exactly where I want and behave exactly the way I want!

On my Arch Linux system, PEAR install its packages by default in /usr/bin. I prefer to put them in /usr/share/pear/bin to be more restrictive on what folders I include in my PHP configuration and avoid including the whole /usr/bin in the open_basedir directive. As a reminder, PEAR is installed on Arch Linux with

$ yaourt -S php-pear

and should be available on most distributions through their respective package manager.

First, if, like me, you make 20 mistakes before doing something right, this is the command for uninstalling a package:

$ sudo pear uninstall <packagename></packagename>

To change the PEAR executables directory globally:

$ sudo pear config-set bin_dir /usr/share/pear/bin/

Don't use sudo if you want to apply the changes locally. In this case, it should create, I think automatically, a hidden file named .pearrc in your home directory.

We can check PEAR configuration with

$ sudo pear config-show

Output of $ pear config-show

We can now install CodeSniffer:

$ sudo pear install PHP_CodeSniffer

and adapt our PATH to find its executable by adding the following in our ~/.bashrc: PATH=/usr/share/pear/bin:$PATH.

We reload our config and check if the CodeSniffer executable is found in the right place:

$ . ~/.bashrc
$ whereis phpcs

Output of $ whereis phpcs

I use the open_basedir directive to add a bit of security. Of course, I don't remember that kind of details but PHP reminds me:

Error thrown by phpcs with open_basedir restriction

We fix this by editing /etc/php/php.ini or wherever your PHP configuration file is by adding the PEAR folder: open_basedir = /srv/http/:/tmp/:/usr/share/pear/.

We can now start refactoring...

$ phpcs path/to/file.php|js|css or $ phpcs path/to/folder

Example of output from phpcs

The following command:

$ phpcs -sp --encoding=utf-8 --standard=PSR2 --tab-width=4 --ignore={External/,Tests/coverage/} -v .

  • shows sniff codes, e.g.: (PSR2.Namespaces.UseDeclaration.SpaceAfterLastUse)
  • shows progress
  • specifies that the encoding of the files is utf-8
  • only uses the PSR-2 standard
  • specifies the number of spaces I use as tab
  • ignores the sub folders External and Tests/coverage
  • prints one level of verbosity
  • and processes the current folder.