Programming

How to restore a branch deleted too quickly in Git?

Having still not the automatic reflexes for applying a successful Git branching model, I cleaned up my working repository a little too fast by deleting a hot-fix branch after merging it into the master branch.

$ git branch -d hotfix-2014062501 
Deleted branch hotfix-2014062501 (was 742134c).

When I came back to the development branch I was working on before the emergency, I realised that I just forgot to merge the hot-fix into it.

As often with Git, a simple solution exists. We only need the sha1 of that branch last commit, which was conveniently displayed in the output of the deletion command above, and execute this one-liner:

$ git branch hotfix-2014062501 742134c

The branch should now be back as if nothing happened:

$ git branch -v
[...]
hotfix-2014062501        742134c some helpful comment

Source

Git refusing to delete a remote branch because it is set as current

I wanted to do some clean-up on a remote repository, which contained a lot of obsolete branches. But one of them returned the following error:

$ git push origin :alpha
remote: error: By default, deleting the current branch is denied, because the next
remote: error: 'git clone' won't result in any file checked out, causing confusion.
remote: error: 
remote: error: You can set 'receive.denyDeleteCurrent' configuration variable to
remote: error: 'warn' or 'ignore' in the remote repository to allow deleting the
remote: error: current branch, with or without a warning message.
remote: error: 
remote: error: To squelch this message, you can set it to 'refuse'.
remote: error: refusing to delete the current branch: refs/heads/alpha
To remote_repository_uri.git
 ! [remote rejected] alpha (deletion of the current branch prohibited)
error: failed to push some refs to 'remote_repository_uri.git'

As this verbose message explains, I was trying to delete the branch named "alpha", which was set as the current branch on the remote repository.

It was an old branch untouched for several months and I don't know how it has been set to be the current branch instead of master. Since the remote is a bare repository, I could not execute the usual git checkout master command. The solution is to move HEAD, which is a symbolic link pointing to the current branch. To make that link point to the master branch, execute the following command on the remote server:

$ git symbolic-ref HEAD refs/heads/master

We can verify where HEAD is pointing to with the same git symbolic-ref command:

$ git symbolic-ref HEAD
refs/heads/master

Source

git-symbolic-ref Manual Page

Git: show all branches on a remote repository

The command below displays all the branches on the remote repository called "origin", including those that are not tracked locally. It also displays local branches configured to be pulled or pushed and their current state.

$ git remote show origin
* remote origin
  Fetch URL: my_repository_uri.git
  Push  URL: my_repository_uri.git
  HEAD branch: master
  Remote branches:
    development                     tracked
    master                          tracked
    [...]
  Local branches configured for 'git pull':
    development         merges with remote development
    master              merges with remote master
    [...]
  Local refs configured for 'git push':
    development pushes to development (up to date)
    master      pushes to master      (local out of date)
    [...]

Source

To list only the branches that are tracked locally, use:

$ git branch -r
origin/development
origin/master
[...]

Execute a specific version of PHP on OVH shared server from command line

The first step is to find the right executable. For example, the default PHP executable is still in version 5.3.16:

$ php -v
[...]
PHP 5.3.16 (cgi-fcgi) (built: Aug 27 2012 17:36:50)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

Other versions are available and we have to specify them explicitly, as we do for Apache through an .htaccess file. My scripts need at least PHP 5.4 and, to use it in CLI, we need the following executable:

$ php.ORIG.5_4 -v
Fatal error:  Directive 'allow_call_time_pass_reference' is no longer available in PHP in Unknown on line 0

OK, we found it but it crashes right away because of the default configuration. To make it work properly, we need to add a flew flags:

$ php.ORIG.5_4 -d allow_call_time_pass_reference=0 -d magic_quotes_gpc=0 -d register_globals=0 /path/to/script.php

Apache: enable HTTPS

To enable HTTP Secure (HTTPS) on Apache, we first enable the modules called mod_ssl and mod_socache_shmcb in the main Apache configuration file, located at /etc/httpd/conf/httpd.conf:

LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule ssl_module modules/mod_ssl.so

We include SSL own configuration file:

# Secure (SSL/TLS) connections
Include conf/extra/httpd-ssl.conf

In this file, we also set a document root (or keep the default path depending on where we put our web application) and a server name. We use the default 443 port.

DocumentRoot "/srv/http/secure_application"
ServerName localhost:443

We can also edit the path to our certificate files but I kept mines at the default location:

SSLCertificateFile "/etc/httpd/conf/server.crt"
[...]
SSLCertificateKeyFile "/etc/httpd/conf/server.key"

Finally we need to get or generate our certificate. I have created a self-signed one for my development environment but it is not recommended on live servers. As written above, I kept the default path so in this example we are going to create our certificate in that folder. We start by generating our key:

$ cd /etc/httpd/conf/
$ sudo openssl genrsa -out server.key 4096
Generating RSA private key, 4096 bit long modulus [...]

This is our private key so we need to restrict permissions to make sure no one else can read it:

$ sudo chmod 600 server.key

Then we need to generate the Certificate Signing Requests (CSR). We are prompted for a few informations which can be left blank but the important one is Common Name, which must be the domain of our site like www.drkdidel.be or *.drkdidel.be. But for our development environment, we just write localhost.

$ sudo openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated into your certificate request.
[...]
Common Name (e.g. server FQDN or YOUR name) []:localhost

Finally we generate our certificate and restart Apache:

$ sudo openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
$ sudo systemctl restart httpd.service

Now we can browse to https://localhost/ and make the browser display a worrying alert:

Warning message displayed by Firefox

This is caused by our self-signed certificate which has no security value (if you see this on a live website, you should follow the advice of "Getting out of here!"). In Firefox, we can click on "I Understand the Risks" then on the "Add Exception..." button. This will display a pop-up window where we can tell Firefox to not bother us again when accessing our server. Check "Permanently store this exception" then click "Confirm Security Exception" which will close the pop-up and reload the page:

Pop-up window "Add Security Exception"