While Centralized Version Control Systems (VCSs) are looking at the sunset, Distributed Version Control Systems (DVCSs) are still enjoying the morning sun. Subversion and GIT are two of the most widely used, libre, and powerful implementations of these concepts. But of course, powerful is defined in relative terms, and by definition DVCSs are more powerful than VCSs.

It's not that Subversion or its relatives are bad products, it's just that their proposed methodology is deprecated. So, it's time to import from __future__. This is why in these series of articles, I'll try to show you how to migrate completely from Subversion to GIT for you to enjoy all this power.

To fully accomplish the migration, you must succeed at the following steps (provided you already got here willing to migrate and learn).

  1. Understand the conceptual differences between VCSs and DVCSs, and between Subversion and GIT.
  2. Move your code from a Subversion repository to a pure GIT repository.
  3. Learn how to achieve the same results you were achieving with Subversion using GIT, and in most cases: improve them.
  4. Never stop learning.

Let's start right away with the first step, I'll try to be as objective as I can. Something to keep in mind is that since VCSs and DVCSs are so different, not trying to match the new concepts with the old ones will definitely make understanding them easier.

Repositories

The greatest difference between VCSs and DVCSs is where are the repositories kept: VCSs have a single main repository keeping the whole history. Every time someone checkouts from this repository, only the latest changes are provided, and the main repository will still be the only repository in existence. On the other hand, DVCSs know nothing about main repositories, but instead, it treats every single repository the same way. That's right, DVCSs allow the existence of multiple repositories per project: every time someone wants to get the code from a DVCSs repository, not only the latest changes are provided, but also, the entire history of commits, branches, tags, etc (depending on the implementation, but this is true for GIT at least). That's why you clone a DVCS repository instead of checking out from it. Crazy as it could sound to you, this is main reason why DVSCs are so powerful.

By having the whole history in a repository, tasks such as reviewing the repository log, checking the changes introduced by a previous commit, and even those tasks involving writing new data such as committing or branch merging don't need remote interaction, you could just disable your network connection and it would work. You'll only need some kind of connectivity with the rest of the world from time to time, once you decide you want to share your improvements with someone else or vice versa. Also, since everything happens locally, actions on DVCSs repositories tend to be faster than VCSs (Except in GIT, where they are extremely faster). Oh, and just in case you are wondering: No, keeping the entire history of a repository doesn't make it larger than two or three VCS checkouts, that's due to GIT's object model and its packing heuristics.

A repository can be cloned multiple times, and each of this clones can be cloned again and again. However, no matter if it is the first repository ever created or the result of cloning and cloning and cloning again, all the repositories have the same privileges: repository A can share changes with repository B, and repository C can get those changes directly from B together with some other changes from D and send them back to A without asking anyone else, effectively creating a decentralized network where you don't need to rely on anyone else and everyone can play together nicely. You know, that low coupling, high cohesion thing.

Sharing repositories is particularly easy with GIT, you can both send and receive data through network using SSH, HTTP, HTTPS, or GIT's own transfer protocol; or locally, using system paths or just copying around the directory where the repository is located. Also, you can use authentication methods provided by this protocols if you need it. This pretty much covers all scenarios.

Commits

In DVCSs (just like in VCSs), committing means introducing a group of changes to the repository contents. Later we will be able to refer to this very state of the repository (or any previous state) with an unique identifier (called revision id in Subversion, or commit id in GIT). Each commit (or revision, or version) represents the state of the entire repository at some time in history. However, there are subtle differences on how Subversion and GIT store these commits.

When you commit to a Subversion repository the change set between the current working tree and the parent commit (The commit you are applying changes on top of) and some metadata are saved somewhere and given an unique identifier. This is quite an interesting approach that fits quite well the linear development model Subversion and other VCSs have. However, it's the linear development model itself which, as of today, doesn't quite fit real world needs.

A non-linear development model is usually used with GIT, and it's well served by snapshot based commits holding all the information about how did the entire repository looked at certain point on history (a tree in GIT lingo), along with some extra data like its author name, etc. No deltas against previous commits are ever stored. This makes tasks involving more than one parent commit like merging branches, or reapplying the same changes again on top of a different commit more efficient --and actually, effective.

Committing in a Centralized VCS involves sending our changes to a remote repository. However, in GIT and other DVCSs, we only deal directly with local repositories, that's it, our committed changes are kept local until you decide they are worth sharing. This has some additional benefits like: you are free to create and work on multiple branches locally without polluting some "central repository", and: haven't you ever wished about getting your history done right since the very first time you commit? Well, GIT allows you to change history to achieve that.

Tags, Branches & Heads

While in Subversion (and probably others) branches and tags are just an idea, in GIT (and probably others, too), they are first class citizens. For example, if you want to create a branch in Subversion, for example, you would usually copy your project's trunk folder (or the folder you want to branch from) in the repository to a folder named (by convention) branches, and that's all about it. Subversion does not understand about what you are trying to do: it just tracks directory contents. The same is true for tags (even if tagged content isn't supposed to evolve), you just name your folder tags instead. That's all Subversion knows about branches and tags: nothing. No wonder why branching and merging between branches is seen as serious shit in Subversion.

Please notice that branches have nothing to do with tags, the only reason why I'm putting them together here is because they are treated the same by Subversion, even when they shouldn't be. Chances are you have probably seen some misuse of tags or branches, so the purpose of each one and what roles they play in your Everyday GIT must be explained.

Tags are probably easier to understand than branches, so let's start by them. In GIT, a tag is used to add some metadata like a "friendly name" to a commit. They are usually used to mark some commit as a new release of your software, so you can later refer to that specific revision using it's tag name (i.e, v1.2) instead of using it's SHA1 id in most GIT commands. They also provide some nice features like addding your PGP signature to it to make it unique among all other repos.

Ideas are constantly evolving, and together with them: code. Branches allow a developer to go along with the flow of different ideas at the same time, and merge them whenever they materialize. No, seriously. You use branches because you need to be able to accomplish your current task without worrying too much about what's the other developer next to you doing, and of course, since you are a good citizen, you don't want to distract others neither.

You usually start a branch when you want to do some stuff like refactoring some pieces of your code, or adding some big feature, or just reorganizing your files: some serious shit if you know what I mean. At least, that's how I've seen branches used in Subversion, and the reason for this is that both branching and merging are expensive, time consuming and error prone operations. However, in GIT, these operations are really cheap, effective and efficient, and due to that, you'll usually find yourself branching your code for anything you know it would take more than one commit to accomplish: it helps you to keep your mind organized while making your commit history as beautiful as it should be.

In GIT, a commit can be referenced by something called head, which is just a pointer to a commit with a fancy name. Every branch has a related head attached which references the last commit on the history of that branch, and, since every commit has references to its parent commits, the whole history of a branch can be reached from the branch head. Most of the time when working with GIT, you will find yourself treating branches just as commits, because essentially, that's what they are under the hood. However, if you picture yourself a branch as the human-friendly concept of: all the commits that are only reachable from some branch head, that will be OK too: GIT will understand what you mean.

And the last topic in this section is merging, which differs from the linear development model Subversion has where diffs between the branches to be merged are involved, since in GIT, merging branches simply means creating a new commit with two or more parents which all happen to be branch heads. Merging is what makes GIT shine. But of course, you already knew that.

http://farm4.static.flickr.com/3646/3456495261_11267ed337_o.gif

History of a GIT repository deliberately showing a lot of branching and merging. Every blue dot represents a commit: the leftmost being the oldest commit and the rightmost being the newest. Consecutive lines of a same color represent a branch. You won't ever find a history as complex as this in real life, though.

Where to go from here

Well, now that you know the basics. You can either wait till the second part of these series (shame on you), or you can start right now experimenting with GIT so that you'll be ready to play with your converted Subversion repository once it cames out from the oven. Most of the links you will find in this very article are for you to follow them and learn something new.

The last thing to mention (and probably the most important one), is GIT community. It's amazing how much work, documentation, and love you can find around GIT. So go STFW, use the mailing list or join the IRC because you have no excuses anymore.

Posted by k0001 under Programming. Created on Apr 19, 2009 21:51 Last modified on Jun 7, 2010 20:14

Language: en Comments: 3 Pingbacks: 0 Tags: free-software, git, scm, subversion

Hoy voy a explicar como dar los primeros pasos con Python y GTK+. Ésto surge a raíz de la escasez de un tutorial de pygtk en español, y con la esperanza de que a alguien le pueda servir. Cabe destacar que no soy un experto en PyGTK ni nada de eso, es mas, estoy aprendiendo mientras escribo esta entrada. Así que, por favor haganme saber sobre cualquier error que haya.

Antes que nada, cabe destacar que para crear nuestra interfaz de usuario (GUI), utilizaremos una herramienta llamada Glade. Lo que hace esta herramienta, es crearnos un archivo XML donde estará almacenada toda la información necesaria respecto a la disposición de los elementos en nuestra pantalla, así como también las señales que emiten (mas sobre esto luego) y ciertas propiedades que especificaran el funcionamiento de nuestra interfaz. Luego, desde nuestro código en Python, cargamos este archivo XML, hacemos todas las modificaciones necesarias (como mostrar datos, conectar señales, etc.) y ya estamos listos para presentar nuestra interfaz.

Vamos a necesitar tener instaladas los siguientes paquetes:

  • Python (>= 2.4)
  • Python GTK (>= 2.10)
  • Python Glade (>= 2.10)
  • Glade (>= 3)

En Ubuntu, podremos instalarlos con un simple:

$ sudo aptitude install python-glade2 glade-3

Si, con eso será suficiente, ya que los otros paquetes son dependencias de este. Si usan otra distribución de linux, busquen en su gestor de paquetes por algún nombre similar. Si usan el sistema de Redmond, les voy a hacer un favor y invitándolos a hacer click aquí, y luego de haber recibido e instalado su CD prosigan con el tutorial (hablo enserio!).

Ya todo preparado, procedemos a abrir Glade 3:

http://farm3.static.flickr.com/2397/2471595695_aba3705ea1.jpg

Ahora vamos a crear nuestro Hola Mundo: En el panel de la izquierda, seleccionamos. Toplevels > Window, luego en el panel Properties a la derecha, dentro del tab General, ponemos en Window Title, Hola Mundo, en Name ponemos winMain y dentro del tab Common, ponemos YES en Visible. Por último, guardamos el archivo como hola.glade.

Ya tenemos lista nuestra interfaz, ahora procedemos al codigo Python para utilizarla. Para esto, creamos un archivo llamado hola.py con el siguiente contenido:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import gtk
import gtk.glade

class HolaMundoGTK(object):
    def __init__(self):
        # cargamos el archivo glade
        self.w_tree = gtk.glade.XML('hola.glade')
        self.winMain = self.w_tree.get_widget('winMain')
        self.winMain.connect('destroy', gtk.main_quit)

if __name__ == '__main__':
    app = HolaMundoGTK()
    gtk.main()

Bien, como verán eso es bastante simple, pero hay mucho para aprender en estas lineas. Primero, importamos los módulos necesarios para toda aplicación que utilize las librerías PyGTK y Glade.

Luego, definimos una clase que representará nuestra aplicación. En el método __init__ de esta clase, cargamos nuestro archivo XML, y lo asignamos al atributo w_tree. Este atriubto -- llamado así por Widget Tree -- es, como su nombre en ingles lo indica, un árbol de widgets. Que es un widget? Un widget es cada uno de los componentes que forman nuestra GUI: por ejemplo, en la siguiente linea, solicitamos el widget llamado winMain a nuestro árbol de widgets, y lo almacenamos como el atributo window. Aquellos grandes observadores, habrán notado que winMain es el nombre por defecto que tenia nuestra ventana cuando la creamos en Glade. Luego, conectamos el evento llamado destroy emitido por el widget self.window con la función gtk.main_quit, en otras palabras, solicitamos que cuando intentemos cerrar la ventana mediante el botón X o similar, terminemos con la aplicación GTK por completo.

Por último creamos una instancia de la aplicación. Con esto logramos crear nuestra interfaz, pero no seremos capaces de verla hasta que GTK entre en su Loop principal.

GTK, al igual que muchas otros GUI Toolkits trabaja con un sistema de eventos o señales. Volviendo al caso del evento llamado destroy, esto significa que, por ejemplo: cuando hacemos click en el boton X para cerrar la aplicación, no llamamos directamente a nuestra función gtk.main_quit, sino, que conectamos esta función a la señal destroy como signal handler. Entonces, la próxima vez que se emita esta señal, se ejecutaran todos los signal handlers conectados a la misma. El encargado de que estas señales sean emitidas, es el loop principal de GTK, el cual ejecutamos cuando llamamos a gtk.main. A partir de ese momento, la aplicación se bloqueará hasta que solicitemos salir del loop.

Ya con estos conceptos incorporados, nos sera mas fácil el viaje a través de PyGTK. Ejecutamos nuestro programa normalmente:

$ python hola.py

Y si hemos seguido las instrucciones correctamente, obtendríamos algo así:

http://farm4.static.flickr.com/3136/2472586894_c0d4b74c47_o.png

Ahora vamos a hacer algo mas interesante, pero antes, necesitamos saber como funciona la disposición de widgets en GTK. En GTK, algunos widgets son contenedores, es decir, son capaces de contener a otros widgets dentro de si mismos, los dos contenedores mas comunes (y los que utilizaremos en este momento) son HBox y VBox.

Volvamos a Glade, seleccionemos Horizontal Box en el panel de la izquierda, luego hacemos click sobre nuestro widget winMain (es decir, el cuadrado con rayitas que vemos en el centro de la ventana), y seleccionamos 2 items en vez de los 3 que nos propone por defecto. Nos debería quedar algo así:

http://farm3.static.flickr.com/2224/2471880157_23d33f12d8.jpg

Bien, como verán, a simple vista tenemos dos "huecos" donde albergar nuestros widgets. La acción de colocar un widget dentro de otro widget se llama packing , y entre otras cosas, cuando queremos hacer packing, podemos seleccionar la posición o "hueco" donde queremos hacerlo. Procederemos ahora a colocar un Vertical box con 2 items en el espacio de la derecha y un Text Entry con nombre (Name) eNombre en la izquierda. Nos deberá quedar algo como esto:

http://farm4.static.flickr.com/3111/2472189957_70a2a68e23_o.png

Ahora agregaremos dos Buttons (botones), en la parte superior derecha de nuestra ventana: al primero, mediante el panel de propiedades a la derecha en el tab General, le daremos como nombre (Name): btnSaludar, y como etiqueta (Label): Saludar. Al segundo, le ponemos como nombre: btnLimpiar y como etiqueta: Limpiar. Deberíamos tener algo así:

http://farm4.static.flickr.com/3060/2472203295_ac903c4794.jpg

Ahora guardamos, y procedemos a ejecutar nuevamente el programa. Como verán, ya podemos tener una idea de lo que será nuestra interfaz en tiempo de ejecución. Pero por ahora, lo único "útil" que podemos hacer con este programa, es cerrarlo.

http://farm3.static.flickr.com/2115/2473050298_4bf17b6d16_o.png

Nuestra aplicación será muy simple, queremos que cuando presionemos en el botón Saludar, una ventana emergente "salude" a la persona cuyo nombre estará escrito en el campo de texto que hemos agregado, y si presionamos Limpiar, el contenido de este campo de texto deberá ser borrado.

Comenzaremos por el botón Limpiar, antes que nada recordemos, el nombre de nuestro botón es btnLimpiar, y el de nuestro campo de texto: eNombre.

Volvamos a Glade, seleccionemos nuestro botón Limpiar, y luego en el panel de la derecha, en el tab Signals agregamos una nueva señal llamada on_btnLimpiar_clicked en el evento clicked del objeto GtkButton como se muestra a continuación.

http://farm3.static.flickr.com/2261/2473127168_20e806a93d_o.png

Ahora en nuestro código Python debemos conectar a esta señal, un signal handler que se encargue de borrar el texto de eNombre. Modifiquemos nuestro método __init__ para que luzca de esta manera:

1
2
3
4
5
6
7
8
def __init__(self):
    # cargamos el archivo glade
    self.w_tree = gtk.glade.XML('hola.glade')
    self.winMain = self.w_tree.get_widget('winMain')
    self.eNombre = self.w_tree.get_widget('eNombre')
    self.w_tree.signal_autoconnect({
        'on_winMain_destroy': gtk.main_quit,
        'on_btnLimpiar_clicked': self.btnLimpiar_clicked })

Primeramente, del mismo modo que antes hemos hecho con winMain, asignamos al attributo eNombre nuestro widget llamado eNombre. Luego, mediante self.w_tree.signal_autoconnect hemos conectado la señal on_btnLimpiar_clicked con el signal handler self.btnLimpiar_clicked detallado a continuación:

1
2
def btnLimpiar_clicked(self, widget):
    self.eNombre.set_text('')

No tiene tanto secreto este signal handler, simplemente recibimos como argumento el widget sobre el cual se ejecuto el evento que disparó la señal, y luego hacemos nuestro trabajo: en este caso, para "limpiar" el contenido de nuestro campo de texto, la solución es asignarle un string vacío como contenido mediante el método set_text de nuestro objeto self.eNombre, instancia de la clase gtk.Entry. Para mas información sobre esto, ver la Referencia de PyGTK.

También hemos aprovechado y reemplazado el previo método para conectarse con gtk.main_quit por uno mas "bonito", pero para que esto funcione, necesitamos -- desde Glade -- configurar la emisión de la señal on_winMain_destroy para el evento destroy del objeto GtkObject en nuestro widget llamado winMain:

http://farm3.static.flickr.com/2267/2473257312_b208b1567c_o.png

Hecho esto, procederemos a ejecutar nuestro programa y... voila! Funciona! Solo resta trabajar con el boton Saludar. Primero, agregamos como ya lo hemos hecho previamente la señal on_btnSaludar_clicked al evento clicked del objeto GtkButton en nuestro widget llamado btnSaludar, y luego, conectamos desde Python esta señal con el signal handler btnSaludar_clicked (método de nuestra clase HolaMundoGTK) detallado a continuación:

1
2
3
4
5
6
def btnSaludar_clicked(self, widget):
    msg = 'Hola %s, bienvenido a PyGTK!' % self.eNombre.get_text()
    dlg = gtk.MessageDialog(self.winMain, buttons=gtk.BUTTONS_CLOSE,
            message_format=msg)
    dlg.run()
    dlg.destroy()

En este signal handler, obtenemos el valor actual de nuestro campo de texto self.eNombre y generamos un mensaje que luego será mostrado en nuestra ventana de dialogo (MessageDialog) dlg, luego, ejecutamos el loop de este widget, que funciona de la misma manera que el Loop Principal de GTK -- es decir, se ejecutará hasta que se solicite salir de el mediante algún evento. Y luego, destruimos (dlg.destroy()) nuestro MessageDialog. Para mas información sobre esto, ver la Referencia de PyGTK.

Ya podemos ejecutar y probar nuestra primera aplicación en PyGTK.

http://farm3.static.flickr.com/2323/2472489051_d4b6634b4c_o.png

Por ultimo, podemos modificar varios detalles de la apariencia y packing de nuestros widgets mediante el panel de propiedades en Glade. Por ejemplo, aquí cambiamos el tipo de los botones a Stock, agregamos un ícono para la aplicación, y modificamos el packing de nuestro campo de texto para alinearlo en la parte superior:

http://farm3.static.flickr.com/2275/2473334808_6be3bec1c8_o.png

Aquí el código completo de nuestro archivo hola.py para nuestra primera aplicación en PyGTK:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env python
import gtk
import gtk.glade

class HolaMundoGTK(object):
    def __init__(self):
        # cargamos el archivo glade
        self.w_tree = gtk.glade.XML('hola.glade')
        self.winMain = self.w_tree.get_widget('winMain')
        self.eNombre = self.w_tree.get_widget('eNombre')
        self.w_tree.signal_autoconnect({
            'on_winMain_destroy': gtk.main_quit,
            'on_btnLimpiar_clicked': self.btnLimpiar_clicked,
            'on_btnSaludar_clicked': self.btnSaludar_clicked })

    def btnLimpiar_clicked(self, widget):
        self.eNombre.set_text('')

    def btnSaludar_clicked(self, widget):
        msg = 'Hola %s, bienvenido a PyGTK!' % self.eNombre.get_text()
        dlg = gtk.MessageDialog(self.winMain, buttons=gtk.BUTTONS_CLOSE,
                message_format=msg)
        dlg.run()
        dlg.destroy()


if __name__ == '__main__':
    app = HolaMundoGTK()
    gtk.main()

Y aquí el contenido de nuestro archivo hola.glade:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.2 on Wed May  7 05:06:57 2008 -->
<glade-interface>
  <widget class="GtkWindow" id="winMain">
    <property name="visible">True</property>
    <property name="title" translatable="yes">Hola Mundo</property>
    <property name="icon_name">evolution</property>
    <signal name="destroy" handler="on_winMain_destroy"/>
    <child>
      <widget class="GtkHBox" id="hbox1">
        <property name="visible">True</property>
        <child>
          <widget class="GtkVBox" id="vbox2">
            <property name="visible">True</property>
            <child>
              <widget class="GtkEntry" id="eNombre">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="activates_default">True</property>
              </widget>
              <packing>
                <property name="expand">False</property>
                <property name="padding">3</property>
              </packing>
            </child>
            <child>
              <placeholder/>
            </child>
          </widget>
          <packing>
            <property name="padding">3</property>
          </packing>
        </child>
        <child>
          <widget class="GtkVBox" id="vbox1">
            <property name="visible">True</property>
            <property name="spacing">2</property>
            <child>
              <widget class="GtkButton" id="btnSaludar">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="label" translatable="yes">gtk-ok</property>
                <property name="use_stock">True</property>
                <property name="response_id">0</property>
                <signal name="clicked" handler="on_btnSaludar_clicked"/>
              </widget>
              <packing>
                <property name="expand">False</property>
                <property name="fill">False</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="btnLimpiar">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="label" translatable="yes">gtk-clear</property>
                <property name="use_stock">True</property>
                <property name="response_id">0</property>
                <signal name="clicked" handler="on_btnLimpiar_clicked"/>
              </widget>
              <packing>
                <property name="expand">False</property>
                <property name="fill">False</property>
                <property name="position">1</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
      </widget>
    </child>
  </widget>
</glade-interface>

Y con esto termina nuestro primer tutorial, gracias a Cristian Boujon por la inspiración, y a esta persona por haber escrito un tutorial similar a este (pero en inglés) con el cual aprendí.

Posted by k0001 under Programming. Created on May 6, 2008 18:25 Last modified on Apr 19, 2009 21:46

Language: en Comments: 5 Pingbacks: 1 Tags: free-software, gtk, python

I've been a Gentoo user for the last ~4 months, before that, I was an Ubuntu user, before that, I was a Gentoo user, and before that, I was an Ubuntu user... and the same story loops at least 2 more times. Why? you may ask. The answer is simple: they are (imho) two of the best linux distributions out there you can drop in your personal computer, and I just can't pick one without missing the other. And so it came to pass, when I decided it was time for a change, that Ubuntu had settled as my main working environment for the upcoming months.

First, let me introduce Gentoo, so that you can understand a bit better my point of view: Gentoo, is a geek-oriented Linux distribution. What is that supposed to mean? It means great knowledge is assumed from the user, who also happens to want more control over the entire system and, of course, must additionally enjoy Gentoo requiring this facts. Here are some tips about Gentoo:

  • You install it manually, i.e. downloading files, copying and extracting them, setting up some system wide parameters, compiling every piece of code you will need, requiring some specific functionalities from specific packages, optimizing them for a desired hardware, etc.
  • Most of the tasks mentioned above, are accomplished by Gentoo's package manager: Portage. This little tool, basically calculates all the dependencies needed to install some given package with a given version and a given functionality, then downloads, extracts, compiles, installs and configures them all. Yes, its pretty cool.
  • Gentoo is a fast moving target. Even though you can find versions as 2006.1 or 2007.1, that does not mean you will be able to say: "I am using Gentoo 2007.0" because that is not entirely true. Portage lets us choose which version of a package we want to install, and we could even have two different versions of the same package installed at the same time, but this completely breaks with the whole idea of "distribution versioning", since you and me, we could both have, say, Gentoo 2007.0 installed, but I could be using KDE 3 while you are using KDE 4. So, in other words, which Gentoo version you are using is up to which packages you have installed (and how those packages are supposed to work).
  • Gentoo's documentation is way better and larger than any other distro's. You can take a look here at the official docs or wiki, but that would be just the tip of the iceberg.
  • Everything you will ever need to do, you will be able to (and must) do it from the command line (call it, terminal, shell, console, tty, whatever).
  • In theory, since you compile everything optimized for your hardware, your system should be faster. In practise, this is barely perceptible (at least for me).

Of course, I really like all that. But then, there is Ubuntu.

Ubuntu is a breeze, you simply put the live cd in your drive, 2 or 3 clicks, and you get a great desktop environment set up in your computer, including office solutions, internet browser, instant messaging, VoIP client, multimedia players, photo manager, image editor, mail client, cd/dvd burning application, bit torrent client and even some games! Ubuntu comes with great hardware support, and it even makes installing those bad and ugly proprietary drivers for your crappy video and wireless card plain easy -- not that this is a good thing, it is bad, but it is their fault! (read nVidia, ATi, Broadcom, etc).

So, there I was, with my new shiny Ubuntu, completely fascinated, because this very version (8.04 Hardy Heron) is what I would call a Perfect desktop environment. It is stable, secure and modern, as its foundation is the best operating system out there. It makes using it a great experience, since all the pieces fit perfectly, it has an excellent community which provides excelent support, and the best of all -- as well as the only reason why this facts are true -- is that Ubuntu is software libre.

Ubuntu just works, most of the software you will ever need are already in the official repositories. That means you just have to type the name of the application you are looking for, hit "OK" and in a couple of minutes it will be ready to be used. Wait... you don't even need to know the name! Just type what you are looking for (i.e. "chat client") and you will be offered a set of choices to install.

If you have digital camera, thumb drive, mobile phone or bluetooth, chances are you will be plugging it and it will just work -- no need for installing drivers or spyware provided by your hardware vendor. Forget antiviruses! there is no such thing as a virus, worm or malware here.

Keeping the system up-to-date is really easy, you just need to acknowledge by clicking a button when you are prompted for this. Updating your system will bring new security fixes or features to the installed software.

Working together with other linuxless computers is also easy, you can share files and printers with them, work remotely via VNC or SSH, and you can even run another operating system inside Ubuntu.

There is no valid excuse to not trying this, and even if you think there is, you'll see there are a lot of choices around, and at least one of them will lead you to a solution. Just try it, you wont regret it.

Wait, this was supposed to be a Gentoo vs Ubuntu thing! Nevermind, I enjoyed it.

Posted by k0001 under Linux. Created on May 4, 2008 23:51 Last modified on May 7, 2008 06:24

Language: en Comments: 0 Pingbacks: 0 Tags: free-software, gentoo, linux, ubuntu

Hace unos días, el 26 de Abril de 2008, se celebro el Festival Latinoamericano de Instalación de Software Libre (FLISOL) 2008 en varias ciudades de América Latina, entre todas estas localidades, también estaba Concepción del Uruguay, el pueblo de donde vengo yo.

http://farm4.static.flickr.com/3261/2450715265_55400d9cf1_o.png

El evento tuvo lugar en la Universidad Tecnológica Nacional: Facultad Regional Concepción del Uruguay (UTN FRCU), y la verdad, fue una maravilla! Eramos entre 10 y 15 voluntarios para la instalación del software, y aproximadamente unas 10 compus fueron llevadas para la limpieza.

Instalamos en la mayoría de las PCs Kubuntu 7.10 sumado a otras aplicaciones destacadas aplicaciones libres como Firefox y VLC. También uno de los responsables del evento, Gabriel Arellano, dio una charla introductoria bastante completa a estos nuevos usuarios que consistía en: primero, una descripción del entorno de trabajo, donde explicaba como "moverse" dentro KDE, y luego, una segunda parte donde mostraba ejemplos prácticos de como realizar tareas cotidianas en este nuevo y mejor sistema, como por ejemplo: copiar archivos, mirar películas, grabar CDs, y cosas por el estilo. Sinceramente, me pareció una charla fantástica.

Creo que la mayoría de los beneficiarios quedaron conformes con el nuevo entorno, a pesar de haber demorado en algunos casos muchas horas para dejar el sistema a punto (leasé: nvidia, ati, atheros). Por mi parte, quede muy satisfecho por el solo hecho de saber que existen --y en mi ciudad!-- usuarios con deseos de sentir la verdadera libertad. Escuchar de la boca de Mariela, una de las personas que había llevado su PC: "Vista es una porquería, borrameló!", fue una experiencia nueva y totalmente enriquecedora.

También la gente de la revista USERS estuvo ahí recopilando datos sobre el evento, y entre otras cosas nos hicieron un reportaje a Claudio y a mi que pronto estará disponible en su web. Por lo pronto, han puesto algunas fotos del evento en su blog.

Gracias a todos los que participaron del evento, tanto a los install boys como a quienes dejaron en nuestras manos a sus computadoras y a la prensa por asistir. Y felicidades, porque este cambio realmente es algo digno de festejar! Espero que podamos repetirlo el año próximo!

Posted by k0001 under Free Software. Created on Apr 29, 2008 04:17 Last modified on Mar 11, 2009 22:56

Language: es Comments: 0 Pingbacks: 0 Tags: free-software, kubuntu, linux, ubuntu

Hi everyone, my name is Renzo Carbonara and today I'm starting this thing. If I can do it, I'll keep posting something from time to time, but I can't promise it, since I really lack that commitment with blogging.

Why am I doing this? Well, beacouse this will be me playground as stated by the title of this site (in case you are not that smart, I am talking about kspg = k0001's playground). Playground what? you might be wondering... The main motivation is at least finish one personal project from all those I've started in the past, and this one, being Django powered will let me play a bit with this web thingie.

So, please enjoy the ride... (if any).

Note: as of now, this is definitely not a blog. Hell! it is lacking a comment system!

Posted by k0001 under Life. Created on Apr 29, 2008 02:57 Last modified on Apr 29, 2008 03:17

Language: en Comments: 0 Pingbacks: 0