Apresentação sobre JQuery

Posted by Alberto Leal on December 30th, 2010

Slides da apresentação sobre jquery que fiz aqui na IBM:

GIT: Quebrando um commit e cancelando algumas alterações

Posted by Alberto Leal on May 23rd, 2009

Dando sequência aos posts sobre GIT, aí vai mais uma dica: Como quebrar um commit e cancelar algumas alterações.

Assim como os posts anteriores, esse post foi inspirado em um problema que o meu time enfrentou semana passada.

Cenário: Foi feito o push de um commit contendo várias alterações no código. Porém, após ter sido feito o code review foi detectado que algumas mudanças não seriam mais necessárias, e/ou deveriam ser implementadas de outra forma. Claro que seria possível ir no código fonte e ir apagando todas as alterações que foram feitas. Mas, será que essa “limpeza” sairia às mil maravilhas? Será que o código voltaria a ficar da mesma forma que antes das alterações terem sido feitas? Acho difícil!

Elaborei um pequeno exemplo, apenas, para tentar ilustrar o cenário acima.

Temos os seguintes commits em nosso Projeto:

picture-22

picture-23

Repare que foi criado um branch para resolver um defeito, no nosso caso, foi adicionar um novo campo, País. Mas por algum motivo o registro de idade foi alterado acidentalmente.

No caso acima, é fácil ir ao arquivo e desfazer as alteração incorreta no campo “idade” antes de fazer o rebase/merge, eu sei. Mas, tente imaginar códigos reais, complexos, onde voltar ao código fonte e desfazer as alterações não seria a melhor solução =)

Uma solução para trazer todas as alterações e escolher o que vai ser efetivado para o merge/rebase é trazer o commit de volta para o stage do git para trabalhar nas alterações. Para isso, vamos utilizar o comando git format-patch para recuperar os commits. Em seguida, criaremos um novo branch para trabalharmos nas modificações e finalmente fazer o rebase com o branch master:

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
Alberto:ProjectX Alberto$ git branch
* Defect123
  master
Alberto:ProjectX Alberto$ git status
# On branch master
nothing to commit (working directory clean)
 
Alberto:ProjectX Alberto$ git log
commit ea4f2953c305b0453fd20f27b3043ebf96d541df
Author: Alberto Leal <albertonb@gmail.com>
Date:   Sat May 23 15:42:16 2009 -0300
 
    Adding new fields
 
commit 656236111360762d92f9efacb05e27b5cd067a04
Author: Alberto Leal <albertonb@gmail.com>
Date:   Sat May 23 15:41:35 2009 -0300
 
    Some new changes
 
commit 131519b37c1d1415e962d6fd23d4058c93438870
Author: Alberto Leal <albertonb@gmail.com>
Date:   Sat May 23 15:40:40 2009 -0300
 
    Initial Commit
Alberto:ProjectX Alberto$ git format-patch master
0001-Some-new-changes.patch
0002-Adding-new-fields.patch

Repare que os patches foram gerados  a partir do Defect123 em relação ao branch master, ou seja, somente as diferenças entre eles.

Para escolher quais as modificações vão entrar para fazer o merge/rebase com o master, é necessário que se crie um novo branch a partir do master - limpo, sem as modicações de Defect123 e use o comando git apply para aplicar os patches no stage.  Agora que os patches com os últimos commits já foram gerados, chegou a hora de jogá-los novamente no stage:

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
Alberto:ProjectX Alberto$ git checkout master
Switched to branch "master"
Alberto:ProjectX Alberto$ git checkout -b Defect123_Changes
Switched to a new branch "Defect123_Changes"
Alberto:ProjectX Alberto$ git apply 0001-Some-new-changes.patch
Alberto:ProjectX Alberto$ git apply 0002-Adding-new-fields.patch
Alberto:ProjectX Alberto$ git log
commit 131519b37c1d1415e962d6fd23d4058c93438870
Author: Alberto Leal &lt;albertonb@gmail.com&gt;
Date:   Sat May 23 15:40:40 2009 -0300
 
    Initial Commit
Alberto:ProjectX Alberto$ git status
# On branch Defect123_Changes
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#
#       modified:   config.txt
#
# Untracked files:
#   (use "git add &lt;file&gt;..." to include in what will be committed)
#
#       0001-Some-new-changes.patch
#       0002-Adding-new-fields.patch
no changes added to commit (use "git add" and/or "git commit -a")

Veja que o arquivo config.txt foi alterado. Agora, vamos adicionar as alterações para serem comitadas, mas para isso vamos utilizar o comando git add -p (similar ao add interativo):

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
Alberto:ProjectX Alberto$ git add -p config.txt
diff --git a/config.txt b/config.txt
index ac82771..b36405c 100644
--- a/config.txt
+++ b/config.txt
@@ -1,6 +1,8 @@
 Nome: Alberto Leal
-email: albertonb@gmail.com
-idade: 24
+Email: albertonb@gmail.com
+Idade: 2423434
 Empresa: IBM
+Telefone: 12-1234-5678
+País: Brasil
 Sexo: Masculino
 Estado civil: solteiro
Stage this hunk [y/n/a/d/s/?]? s
Split into 2 hunks.
@@ -1,4 +1,4 @@
 Nome: Alberto Leal
-email: albertonb@gmail.com
-idade: 24
+Email: albertonb@gmail.com
+Idade: 2423434
 Empresa: IBM
Stage this hunk [y/n/a/d/j/J/?]? n
@@ -4,3 +4,5 @@
 Empresa: IBM
+Telefone: 12-1234-5678
+País: Brasil
 Sexo: Masculino
 Estado civil: solteiro
Stage this hunk [y/n/a/d/K/?]? y

Utilizando o comando acima, podemos quebrar as alterações feitas no arquivo utilizando a opção “s” (split). Após, você informa se deseja adicionar os fragmentos ao stage, utilizando as opções “y”- yes e “n”- no. Todos os fragmentos que você desejar adicionar no stage para comitá-lo, utilize a opção “y”. No pequeno exemplo acima, apenas foi mantido no commit a adição dos novos campos: Telefone e País. A alteração equivocada no campo “idade”foi eliminada do commit. Só nos resta efetivar as alterações comitando as mundanças:

1
2
3
4
5
6
7
8
9
10
11
12
13
Alberto:ProjectX Alberto$ git commit -m 'Cutting branch'
Created commit 9e365a2: Cutting branch
 1 files changed, 2 insertions(+), 0 deletions(-)
Alberto:ProjectX Alberto$ git checkout config.txt
Alberto:ProjectX Alberto$ cat config.txt
Nome: Alberto Leal
email: albertonb@gmail.com
idade: 24
Empresa: IBM
Telefone: 12-1234-5678
País: Brasil
Sexo: Masculino
Estado civil: solteiro

Cuidado para não adicionar o arquivo novamente ao stage (git add config.txt). As alterações que você fez já estão lá, prontas para serem comitadass. Se você se esquecer e adicionar o arquivo novamente ao stage, você perderá todas as mudanças que você fez no add interativo. É aconselhável que, logo após o comando git commit, você execute git checkout <file>, como mostrado acima. Desse jeito, você pegará o arquivo que está no repositório atualizado.

picture-24

Agora, só nos resta fazer o rebase com o branch principal:

1
2
3
4
5
Alberto:ProjectX Alberto$ git checkout master
Switched to branch "master"
Alberto:ProjectX Alberto$ git rebase Defect123_Changes
First, rewinding head to replay your work on top of it...
Fast-forwarded master to Defect123_Changes.

picture-25

É isso pessoal! Espero que a técnica apresentada nesse post lhe seja útil algum dia, assim como foi para mim.

Abraços!

Conversão implícita e explícita de Numéricos

Posted by Alberto Leal on December 4th, 2008

Falei sobre conversão implícita/explícita quando estamos trabalhando com String. Agora, chegou a vez de falar um pouco sobre conversões com classes numéricas.

A mesma confusão que encontramos quando falamos sobre os métodos to_s e to_str, encontramos quando nos deparamos com to_i, to_int, to_f, to_flt. Vamos valer da mesma regra que foi apresentada para a classe String: Conversão explícita é para os métodos curtos e implícita para os métodos longos.

Assim como o método to_str, muitas classes não definem os métodos implícitos to_int e to_flt.

Vamos ver um exemplo:

class MeuNumero
  def to_i
    5
  end

  def to_int
    10
  end
end

meu_numero = MeuNumero.new
puts meu_numero.to_i

 

O código acima imprime “5″, visto que chamamos o método explicitamente. Agora, quando o meu método de conversão implícita é executado? Vejamos outro exemplo:

meu_numero = MeuNumero.new
array_meu_numero = Array.new(meu_numero)

 
Ao executarmos o código acima, constatamos que foi criado um array com 10 posições. Isso porque quando passamos o nosso objeto (meu_numero) ele foi implicitamente convertido para um valor numérico para ser passado como parâmetro para a criação de um Array.


Copyright © 2007 Alberto Leal. All rights reserved.