git: deleting remote tracked branches

Since I’m always DuckDuckGo-ing for these information, I’ll set a note here for future reference and for all of you, fellow readers.

Situation: one (or more) remote-tracked git branches got deleted (either locally or remote). You are in either one of the two cases following:

  • you have deleted the local branch and you want to delete that branch in the remote too. What you want is:

git push <remote> :<deleted_branch>

  • someone (you or other allowed members on the remote) has deleted a remote branch. To delete all stale remote-tracked branches for a given remote:

git remote prune <remote>

git tip: multiple identities

If you are using git version control for personal and work repositories, it is tricky to change your email address (in ~/.gitconfig) to properly use the correct email before committing to a repo (this is what I do, depending on the nature of the repo: personal repo -> personal email, work repo -> work email).

Before this post, I was using some articulated methods to change my email address depending on the repo, but none of these methods was really portable (or officially documented).

Starting from version 2.8.0, you can use “multiple identities” when committing; to achieve this, you must remove your personal details from the config with:

git config --global --unset-all user.name

git config --global --unset-all user.email

and set a new option:

git config --global user.useConfigOnly true

Now, everytime you try to commit, git complains to instruct it with your personal details:

% git commit

*** Please tell me who you are.

Run

git config --global user.email "you@example.com" git config --global user.name "Your Name"

to set your account's default identity. Omit --global to set the identity only in this repository.

fatal: no name was given and auto-detection is disabled

The only drawback of this approach is that you have to set these details on every repository. Do you know any better ideas?

git-flow: il modello di git workflow che utilizzo

Dopo aver letto l’interessante presentazione “How GitHub uses GitHub to build GitHub“, ho deciso di dare un’occhiata al modello di workflow chiamato git-flow [che si basa, ovviamente, sull’utilizzo di git].
In sintesi:

  • Ci sono due branch sempre presenti: master e develop:
    • master contiene tutti i commit per cui il repo è deployabile in produzione [production ready].
    • develop contiene il codice di integrazione. Va da sé che una volta che il codice di integrazione è pronto, viene fatto un merge verso master.
  • Ci sono alcuni branch che vengono creati/distrutti all’occorrenza: feature, release e hotfix:
    • feature è un branch di develop che contiene, appunto, alcune features“locali” al brach di sviluppo di cui verrà fatto il merge verso develop
    • release: una volta che il branch develop ha abbastanza features per una release, si crea un branch di develop per prepararsi ad un ciclo di rilascio. Nessuna nuova feature può essere introdotta a partire da questo branch. Una volta pronto, il branch release viene merge-ato al branch master [e successivamente al branch develop].
    • hotfix contiene, come dice il nome, delle fix urgenti che hanno origine nel branch di produzione, e di cui verrà fatto il merge nella prossima release di produzione [e che saranno riflesse, di conseguenza, anche in develop].

Può sembrare complicato: ecco un grafico che spiega in forma grafica quello che ho illustrato a parole:

Se volete saperne di più, sul sito di dell’ideatore è presente una descrizione più dettagliata di git flow.
Bonus: su GitHub è presente un’estensione per utilizzare git-flow direttamente da git.

Esistono anche altri modelli di workflow per git, ma a mio avviso, git-flow rimane il più indicato [per i miei progetti].

zsh: perché non utilizzo bash

Su tutte le macchine Linux e OSX che amministro non uso come shell di default la bash; uso invece zsh, perché:

  • zsh si offre di completare anche le opzioni e i parametri dei programmi più usati;
  • zsh fa spelling correction dei comandi digitati, chiedendo interattivamente se volete correggere il comando;
  • zsh offre una customizzazione più spinta della bash (vedremo tra poco il mio prompt);
  • zsh condivide la history tra più sessioni attive contemporaneamente;
  • zsh è già installata, di default, su OSX (ed è nei repo di Ubuntu, percui basta un aptitude install zsh).

Se questi vantaggi non dovrebbero bastare, ecco il mio prompt:

Ho scritto un tema ad-hoc, che funziona grazie a oh-my-zsh (un framework di customizzazione per zsh, che consiglio vivamente!). Cos’ha di speciale il mio prompt rispetto ad una semplice bash?

  • Colorazione diversa del prompt se siamo root
  • Colorazione del prompt in base all’esito positivo o negativo dell’ultimo comando utilizzato
  • Visualizzazione dello stato del repo git della directory attuale: branch + status (modifiche unstaged?)

Ho caricato su github i due temi che ho creato per oh-my-zsh: michelebologna.zsh-theme è quello mostrato in questi screenshot. Ovviamente, prima dovete installare oh-my-zsh. Feedback benvenuti!

gitignore: un filtro per escludere i file da non versionare in un repository git

Prima di fare un push su un repository git è importante avere configurato il gitignore, ovvero specificare quali files non devono essere versionati in un repository git. A titolo di esempio: i file .pyc, o più in generale i prodotti della compilazione di un qualsiasi file di sorgente; versionare questi files, infatti, non ha senso.

Per fare in modo che git eviti di versionare certi tipi di files, creiamo un file .gitignore dentro la nostra $HOME, ed  il gioco è fatto. Se volete partire da un esempio già realizzato, includo qui il mio gitignore.

michele@delta:~ % cat ~/.gitignore
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so

# Packages #
############
# it’s better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# Logs and databases #
######################
*.log
*.sql
*.sqlite

# OS generated files #
######################
.DS_Store*
ehthumbs.db
Icon?
Thumbs.db