Está en la página 1de 20

0

Inicio
VersionandoconGityGithubParte2
EnviadoporJStitchelMar,12/07/201110:42.
oCmoIntroducirsealSoftwareLibresiendoProgramador
Estaeslaparte2deunaseriedepostsqueestoyrealizandoparahablartantodeversionadoresengeneral(ydeGityelservicioGitHubenparticular)
comodelhechodequeparaparticiparenunproyectodesoftware(decualquierndole,peroenespeciallosdesoftwarelibre)uncontroleficienteperoa
lavezsencillodelasversionesdelcdigoesimportantsimo.
Enlaparte1introduzcolosconceptosdeversionadores,esquematizoelprocesoqueengeneralsesigueparautilizarunsistemaas,hablodelahistoriadelos
versionadoresyterminodiferenciandolosversionadorescentralizadosdelosdistribuidos.
EnestapartehablardeGit,unsistemadecontroldeversionesdistribuidobastantepopular.
SiyaconocessobreGityteinteresapasardirectamentealapartedeGitHub,puedesiralaparte3.
Git
Estepostseconcentraenintroducirelsistemadecontroldeversiones(versioncontrolsystem,VCS)Git.
ParaexplicarGitysusconceptoscomoVCS,utilizolainterfazmscomndelsistema:lalneadecomandos.Porello,estepostestplagadodecomandosdela
manodelosconceptosexplicados.
Mi recomendacin para entender Git es entender los conceptos con los comandos asociados, y despus si as se desea, buscar alguna interfaz diferente ms
acorde a los gustos personales. Al final de este artculo coloco unos links con algunas interfaces alternativas para Git. Lo que s debe quedar claro es que este
postesunameraintroduccinaGit,nopretendeserunaguaexhaustivadelsistema.Laideaesdarloaconocer,promoversuuso,hacernotarsuimportanciaen
proyectosdesoftwarelibre,ydejarlacartaabiertaparaqueelinteresadoinvestiguemsyseinformedetodoslosdetallesqueaqunosemencionan.
Para facilitar la lectura de este artculo y que a su vez pueda servir como una pequea referencia introductoria a Git, coloco aqu ligas internas a las distintas
seccionesdelmismo,amaneradendice:
BrevehistoriadeGit
ElmodoGit
Generandounrepositorio
1InicializandoundirectoriocomorepositorioGit
2CopiandounrepositorioGit
Usandoelrepositoriolocal
gitadd
gitstatus
gitdiff
gitcommit
BranchesyMerges
gitbranch/checkout
gitmerge
Conflictos
gitlog
gittag
Interactuandoconunrepositorioremoto
gitremote
128020c
Login Register
Pgina personal de JStitch
Buscarenestesitio: Buscar
COLECCIONES PORTAFOLIOS LINKS
gitfetchmerge/pull
gitpush
gitrequestpull
Conclusin
InterfacesparaGit
Parasaberms...
BrevehistoriadeGit
GitsurgicomounVCSdelamanodeLinusTorvalds,elcreadordelkernelLinux,paraadministrarprecisamenteelcdigodesuproyectoestrella.
Inicialmente el kernel de Linux era administrado con BitKeeper, un VCS de cdigo cerrado que, paradjicamente para muchos, permita administrar uno de los
productos estelares en el ambiente del software libre. Como es propio de l, Torvalds no ceda a presiones basadas en preferencias y filosofas y continu con
BitKeeper hasta que este proyecto lanz restricciones que no permitan un uso libre de los proyectos hosteados con ellos. As pues como buen hacker, Linus
TorvaldscomenzaescribirGitparallenarelhuecodejadoporBitKeeperdeunVCSdistribuido,eleganteperosobretodoeficienteparausarconLinux.Sitoda
estaancdotaesonounaleccinsobrefilosofadelusodesoftwarelibre,quedeacriteriodellector.
Desdesulanzamiento,el6deabrildel2005,GitsehaconvertidoenunodelosprincipalesVCSdistribuidos,sobretodo(peronoexclusivamente)enelmundodel
softwarelibre.Algunosdelosproyectosque,adadehoy,utilizanGitcomoVCSson:
elkerneldeLinux
elproyectoAndroid
elCMSDrupal
elentornodeescritorioGnome
ellenguajedeprogramacinPerl
elmanejadordeventanasOpenbox
Wine,losserviciosdecompatibilidadLinuxWindows
lascoreutilsdelproyectoGNU
X.Org,elservidorgrficoparaentornosUnix
Qt,elframeworkdeaplicacionesgrficas
Samba,laimplementacinlibredelprotocoloSMBparacompartirarchivosconsistemasWindows
yunlargoetctera...
ElmodoGit
Muy al contrario de como se maneja un VCS tradicional (como Subversion), Git maneja los repositorios, y los conceptos mismos de un VCS de una manera
particular.
MientrasqueparaSubversion,elcontroldeversionessehacearchivoporarchivo,sobrecadadirectorioqueintegraunproyecto,paraGitelcontroldeversiones
sehacesobrelosdistintos'snapshots'quesetomendetodoelproyecto.
LadiferenciaradicaenqueparasistemascomoSubversion,cadaversindelproyectoincluyelaversindecadaunodelosarchivosdelmismo.Mientrastanto
para Git, cada versin del proyecto incluye solamente un manifiesto con las diferencias de cada archivo, es decir de cmo se ve el proyecto en su totalidad en
determinadomomento.EntendiendoGitas,serfciladaptarseasumododefuncionamiento,einclusosalirdeusarunVCScentralizadoycomenzarausarla
genialideaquerepresentanlosVCSdistribuidos.
Demaneramuygeneral,elsiguienteesquemailustracadapartedelprocesoqueseusaparaversionarconGit:
ProcesodeversionadoconGit
Generandounrepositorio
ElprimerpasoparautilizarGitestenerunrepositorio.ElrepositorioGitserepresentaporundirectorioespecialllamado.gityqueresideeneldirectoriorazdel
proyecto mismo. A diferencia de SVN, Git slo genera un nico directorio para todo el repositorio, en donde almacena toda la informacin del mismo (versiones,
historial,etc.)siserecuerdaSVN,stealmacenaundirectorio.svndentrodecadasubdirectoriodelproyectoversionado,almacenandoenelmismoesamisma
informacin(conotroformato)paracadadirectorioyporlotantocadaarchivodelproyecto.
HaydosmanerasdegenerarunrepositorioparatrabajarconGitsobreunproyecto:
1InicializandoundirectoriocomorepositorioGit
Suponiendoquesetieneundirectorioenelqueresideelproyectoaversionar,elcomando
gitinit
creaelrepositorioGitparaelproyectodado.Estageneracindelrepositorioescompletamentelocalalamquinayeldirectoriodonderesideelproyecto.Ninguna
operacinserealizcomunicndoseconalgnservidorninadaporelestilo.
$cdproyecto
$gitinit
InitializedemptyGitrepositoryin/path_to_proyecto/proyecto/.git/
2CopiandounrepositorioGit
Ahora supongamos que deseamos colaborar en algn proyecto (o simplemente queremos obtener su cdigo fuente para compilarlo y usarlo, o para mirarlo y
admirarlo:).Paraesto,loprimeroquehayquehaceresobtenerelcdigofuente.SilosadministradoresdelproyectosonlistosyutilizanGitparaelmismo,loque
debemoshacerescopiaroclonarelrepositorioorigendelproyectoparaastenerlocomounrepositoriocompletamentelocalsobreelcualpodertrabajar.
LosrepositoriosgittienenunaURL,yconellaseutilizaelcomando
gitclone[url]
paraclonarelrepositoriodeorigenremotoaunrepositoriocompletamentelocalsobreelcualpodertrabajar.Porejemplo:
$gitclonegit://github.com/jstitch/masterm.git
Cloningintomasterm...
remote:Countingobjects:36,done.
remote:Compressingobjects:100%(35/35),done.
remote:Total36(delta14),reused0(delta0)
Receivingobjects:100%(36/36),49.14KiB,done.
Resolvingdeltas:100%(14/14),done.
clonarelrepositoriodelproyectoqueresideengit://github.com/jstitch/masterm.gitaldirectoriomastermlocal:
$cdmasterm
$ls
BUGScurstextlib.hINSTALLlanguages.hMakefilemasterm.hTODO
cursors.hHISTORYintl/LICENSEmasterm.cREADMEutils.h
Siseobservaelcontenidodelosarchivosocultosdeestedirectorio,sepodrverqueefectivamentesetieneunrepositorioGitenl:
$lsa
./BUGScurstextlib.hHISTORYintl/LICENSEmasterm.cREADMEutils.h
../cursors.h.git/INSTALLlanguages.hMakefilemasterm.hTODO
Independientemente del mtodo utilizado, antes de comenzar a trabajar, y si no se ha hecho an, es necesario indicarle a Git los datos que utilizar el sistema
para saber qu usuario ser el responsable de los cambios hechos (de otra manera no tendra sentido el usar un VCS, sin tener a quin echarle la culpa darle
graciasporloscambioshechosalcdigo).Estoselograconlossiguientescomandos:
$gitconfigglobaluser.name'Tunombre'
$gitconfigglobaluser.emailtu@dominio.com
Usandoelrepositoriolocal
El funcionamiento bsico de Git consiste en trabajo local, trabajo local y trabajo local: modificando archivos, generando branches, haciendo merges con ellos,
agregando los archivos con cambios que se deseen versionar, versionndolos y as sucesivamente. Solamente cuando ya se tiene un conjunto de cdigo y
cambios hechos y probados se procede a mandarlos al repositorio origen desde el cul se clon (o a solicitar que se integren los cambios hechos al mismo en
casodenotenerlospermisosadecuados).
Enresumen,seutilizagitaddparaagregarloscambiosalosarchivosquesedeseaqueGittomeencuentaparalasiguienteversindelcdigo,gitstatus y
gitdiffparaobservarloscambiospuntualesqueserealizarnparalasiguienteversinygitcommitparaalmacenardichaversinenelhistorialdelrepositorio.
Este es el flujo principal que se sigue al trabajar con Git, y hay que destacar que todo se hace de manera local, sin interaccin con repositorios remotos:
recurdesequeseesttrabajandosobreunrepositoriolocalyqueprecisamentesteeselsentidodelosVCSdistribuidos.
gitadd
Inicialmente ningn cambio a ningn archivo sobre el que trabajemos, sea recin creado o sea modificado (aunque anteriormente ya hubieran sido versionados
cambios al mismo) es considerado por Git para versionar. Es necesario hacer un gitadd para que Git sepa en particular qu archivos con cambios sern
versionados.
Estoproporcionauncontrolmuyfinodelprocesodeversionado.EnsistemascomoSVNsiunarchivoesconsideradoparaversionar,loesdesdequeesagregado
alrepositorioyhastasiempre.Sideseamosmodificarestearchivoancuandoesamodificacinnotenganadaqueverconlasmodificacionesaotrosarchivos,el
procesodecommitsellevardeunasolavezatodoslosarchivosversionados.EnGitsinembargotenemoslaopcindeelegirpuntualmentequarchivoscon
cambiossevanaversionar.
As,sihacemosunamodificacinqueseaunacorreccindeunbugenvariosarchivos,yalavezmodificamosotrosarchivosparacorregirerroresdetipografaen
ladocumentacin,Gitnospermiteversionarcadaunadeestasmodificacionesporseparado,permitiendoidentificarmsfcilmentequarchivoscambiaroncomo
partedequmodificacin,sinconfundirconotrosarchivosrelacionadosaotrasmodificaciones.
Porejemplo:
$touchnew_file
$echo"">>README
$gitstatuss
MREADME
??new_file
Hasta aqu se puede observar que, tanto al agregar un nuevo archivo, como al editar un archivo ya existente en el repositorio, Git sabe que ambos archivos no
seranversionadosenelprximocommit.Loquessabeesqueelarchivoqueyahabasidoversionadoahorafuemodificado,peronoporelloloversionarde
nuevoyelarchivonuevonosabenadadelhastaahora.Ahora:
$gitaddREADMEnew_file
$gitstatuss
MREADME
Anew_file
Yahoras,luegodegitadd,Gitsabequeambosarchivosdebenserversionados(unoporhabersidomodificadoyotroporhabersidoaadido).Sislounode
los archivos debe ser versionado, entonces gitadd slo recibira ese archivo como argumento. Luego se versionara con gitcommit y el otro archivo an
quedarapendientedeversionar...
gitstatus
Hastaahoraparademostrargitaddseustambingitstatussinexplicarcmofunciona.
Bsicamente, gitstatus permite conocer la manera en que Git ve los archivos del proyecto con respecto al repositorio. La opcin s usada en los ejemplos
anterioresdanunstatusresumido.Sinestabanderalasalidaseramasomenosas:
#Onbranchmasterm_lang
#Changestobecommitted:
#(use"gitresetHEAD..."tounstage)
#
#modified:README
#newfile:new_file
Sisepusoatencin,enlasalidaconlabanderas, el status aparece con dos columnas. La primera indica los cambios que har Git en la siguiente versin del
cdigo.LasegundacolumnaindicacambiosqueGitreconocecomotalesperoquenoversionar:
$echo"">>new_file
$gitstatuss
MREADME
AMnew_file
Comosepuedeveraqu,luegodeunamodificacinalarchivonew_file,Gitsabequehaymodificaciones,perocomofueronhechasluegodegitadd,Gitnolas
tomarencuentaparalasiguienteversin.Observemoslasalidanoresumidadelstatus:
$gitstatus
#Onbranchmasterm_lang
#Changestobecommitted:
#(use"gitresetHEAD..."tounstage)
#
#modified:README
#newfile:new_file
#
#Changesnotstagedforcommit:
#(use"gitadd..."toupdatewhatwillbecommitted)
#(use"gitcheckout..."todiscardchangesinworkingdirectory)
#
#modified:new_file
#
Esdecir,enlasiguienteversinaparecernloscambiosalarchivoREADMEylaaparicindelnuevoarchivonew_file,perolamodificacinhechaaesteltimono
aparecer.
gitdiff
Otraoperacinmuycomnaltrabajarconarchivosversionadosesladeobservaryanalizarloscambioshechos,ascomolasdiferenciasentrelanuevaversiny
laquesetieneenunaversinanterior.
Gitutilizadiffparaestomismo,comopuedeverseenelsiguienteejemplo:
$echo"holamundo">>new_file
$gitdiff
diffgita/new_fileb/new_file
indexe69de29..775af59100644
a/new_file
+++b/new_file
@@0,0+1,2@@
+
+holamundo
EstasalidaindicaqueGitdetectacambiosquenohansidomarcadosparaversionarseenelarchivonew_file(unalneanuevadelejemploanterior,yunmensaje
delpresenteejemplo).
SisedesearaverlasdiferenciasqueGitdetectatomandoencuentaloscambiosenlosarchivosqueyafueronmarcadosparaversionar,aunqueannohayasido
versionados,seutilizaelparmetrocached:
$gitdiffcached
diffgita/READMEb/README
index058947a..082cf26100644
a/README
+++b/README
@@70,3+70,4@@account)

Mexicocity
23/january/2009
+
diffgita/new_fileb/new_file
newfilemode100644
index0000000..e69de29
Como puede observarse, aqu se muestran los cambios en el archivo README que ya haban sido marcados para versionar anteriormente (una lnea nueva del
primerejemplo).Tambinsemuestraelnicocambiohechoanew_filequeyahabasidomarcadoparaversionar:lacreacindelarchivonadams.
Por ltimo, si lo que se desea es ver todos los cambios, tanto de lo marcado para verionar como lo que no, se le pasa a gitdiff como parmetro la versin
contralacualsequierecompararelcdigoactual.ElnombreHEADserefiereajustamentelaltimaversinquetienealmacenadaelrepositorio:
$gitdiffHEAD
diffgita/READMEb/README
index058947a..082cf26100644
a/README
+++b/README
@@70,3+70,4@@account)

Mexicocity
23/january/2009
+
diffgita/new_fileb/new_file
newfilemode100644
index0000000..775af59
/dev/null
+++b/new_file
@@0,0+1,2@@
+
+holamundo
Quecomopuedeobservarse,incluyeloscambiostantoaREADME(previamentemarcadosparaversionar)comolosdenew_file(algunosyamarcadosyotrosan
nomarcadosparaversionar).
gitcommit
Finalmente,unavezhechosloscambiosdeseados,aadidosnuevosarchivos,eliminadosotros,yaadidosdichoscambiosespecficosparaserversionadospor
Git (ignorando por ahora los otros cambios que no deseamos versionar todava), se realiza el commit al repositorio (recurdese: es local, no hay necesidad de
conexinalaredtodava!):
$gitcommitm"miscambiosalREADMEycreandonew_file"
Comosepuedeobservar,elcomandonecesitadeunmensajedescriptivo,ydehechoGitlanzaerrorsinoseagregamensaje.
Ahora:
$gitstatuss
Mnew_file
QuenosmuestraquesloquedauncambiodetectadoporGit:aquelquenohemosmarcadoparaversionaran.
BranchesyMerges
Para los provenientes de VCS centralizados como SVN, muy probablemente el nombre 'Branch' ya dibujo en su mente la idea de una pesadilla dantesca... La
realidadesqueelmanejodebranchesenversionadorescentralizadossueleconvertirseenunamolestiamsqueenunaherramientatil.Tanesasquemuchos
proyectos renuncian a su uso y se dedican nicamente a versionar sobre un rbol principal de cdigo, dejando de lado una de las ventajas esenciales que
proporcionaunversionador.
Perolabuenanoticiaesqueenlosversionadoresdistribuidos,yenGitenparticular,elmanejodebrancheses,dichollanamente,maravilloso.
UnamaneradeentenderlosbranchesenGites,ademsdeolvidandoloaprendidoenversionadorescentralizados,verloscomocontextosenlosquesetrabaja
unaversinespecficadelcdigo.
Digamosquebajamoselcdigofuentedeunsoftwarequeutilizamosmuchoydetectamosunbug.ElmodoGitdeafrontarlosera,luegodeclonarelrepositorio,
crearunbranchyahtrabajarlacorreccindelbug.Siademsresultaquetenemosunapropuestademejoraalsoftware,locorrectodesdeelpuntodevistadel
modoGitdetrabajarloseracrearotrobranchapartirdeloriginal(omaestro)yahtrabajarloscambios.Finalmentecuandoelbugestcorregido,seintegran(va
merge) con el branch maestro. Y cuando nuestros cambios estn hechos y probados tambin, se hace lo mismo desde aquel otro branch al maestro de nuevo.
As,alfinal,setieneuncdigolimpio,probado,bienversionado.Todograciasalusodebranches.
En resumen, se crean branches con gitbranch, se hace cambio de contextos con gitcheckout y se mezclan branches con gitmerge. Otra caracterstica
notable del manejo de branches de Git es que los branches creados no se crean aparte en subdirectorios dedicados a lo mismo, como en SVN. Ms bien, el
directorio .git contiene toda la informacin (en forma de snapshots o diferencias entre cada archivo y sus branches), y as en un slo directorio de trabajo del
proyecto, al cambiar de contexto, todo el cdigo del mismo directorio pasa a ese nuevo estado. Se puede cambiar entre contextos libremente y sin prdida de
informacin,ysinelestorbodeundirectoriodedicadoacadabranchdelproyecto.
gitbranchygitcheckout
Comoyaseinsinumsarriba.AlcrearunnuevorepositorioenGit,pordefectosetieneunnicobranch,elinicialoprincipaldelproyecto.Selellamamaster por
default.Elcomandogitbranchlistatodoslosbranchesexistentesactualmenteenunproyecto.Siguiendoconelejemplodeunrepositorioclonadopreviamente
desdeotroproyecto:
$gitbranch
*masterm_lang
Elasteriscomuestraculeselbranchactual(ocontextoactual)enelqueseencuentraelproyecto.Comopuedeverse,altratarsedeunproyectoclonadodesde
otrorepositorio,elbranchpordefaultnosellamamaster,peroelpuntoesquesetratadelbranchprincipaldelproyecto.
Paracrearunnuevobranch,seutilizaelcomandogitbranch[nombre_del_branch]:
$gitbranchtesting
$gitbranch
*masterm_lang
testing
Como se puede observar, ya existe un nuevo branch en el proyecto (testing). Este branch est hecho a partir del cdigo en su ltimo estado: tanto los ltimos
commitscomolosarchivosconcambiosquehanynohansidoaadidosparaversionar.
Yparapasaraesenuevocontextoytrabajarsobrel,seutilizagitcheckout[nombre_del_branch]:
$gitcheckouttesting
$gitbranch
masterm_lang
*testing
Y,comopuedeobservarse,ahoraestestingelcontextoactualsobreelquesetrabajarenelproyecto.
Si hacemos algunos cambios en un archivo, y luego regresamos al contexto original (masterm_lang), como no se le indic a Git que los cambios se iran a
versionarenesecontexto,loscambiospasantransparentesentrecontextos:
$echo"holaREADME">>README
$gitcheckoutmasterm_lang
MREADME
Mnew_file
Switchedtobranch'masterm_lang'
Yourbranchisaheadof'origin/masterm_lang'by1commit.
$gitstatuss
MREADME
Mnew_file
Locualindicaqueloscambiosquenosehanmarcadoparaversionar(recurdesequenew_fileantienecambiossinmarcar)pasanentrecontextosdemanera
transparente.
Siahoramarcamosalgncambioparaversionarenunodeloscontextos...:
$gitaddnew_file
$gitstatuss
MREADME
Mnew_file
$gitcheckouttesting
MREADME
Mnew_file
Switchedtobranch'testing'
$gitstatuss
MREADME
Mnew_file
Comosepuedeobservar,aqutambinloscambiosmarcadosparaversionarpasantransparentesentrecontextos.Gitnopuedesabersilamarcaagregadapara
versionaresparaunouotrocontexto,yslosabrinformacinmsconcretahastahaceruncommit:
$gitcommitm"agregotextoanew_file,comoprueba"
[testing6870e92]agregotextoanew_file,comoprueba
1fileschanged,2insertions(+),0deletions()
Yahoras,loscambioshechosanew_filequedanenelbranchtesting,noenlaramaprincipal:
$catnew_file

holamundo
$gitcheckoutmasterm_lang
MREADME
Switchedtobranch'masterm_lang'
Yourbranchisaheadof'origin/masterm_lang'by1commit.
$catnew_file

Enelbranchmasterm_langnoexisteelcambiodelanuevalneayeltexto"holamundo".Peroenelbranchtestingsqueexistenestoscambiospuesahsehizo
elcommit.
gitmerge
Supongamos que ahora deseamos que el cambio en testingquedereflejadotambinenmasterm_lang. Lo que debe hacerse es un merge, una operacin que la
mayoradelasvecesGitpuedehacerporsupropiacuenta.
$gitbranch
*masterm_lang
testing
$gitmergetesting
Updating6601551..6870e92
Fastforward
new_file|2++
1fileschanged,2insertions(+),0deletions()
$catnew_file

holamundo
Conflictos
Peroqupasarasiotrousuariohubierahechocambiosanew_filesobremasterm_langantesquenosotroshubiramoshechoelcommit?EntoncesGitgenerara
lo que se conoce como un conflicto, que no es otra cosa sino la forma en que Git indica que no sabe como hacer el merge por s solo y necesita de la ayuda
externadelosusuarios.Losconflictosnoocurrensiempre,inclusoaunquemuchosusuarioshagancambiosalmismoarchivomuchasveces.Bsicamentesilos
cambiossehacensobrelneasdiferentesdeldichoarchivo,Gitsabrhacerelmergesinproblemas.Escuandosehacencambiosqueinmiscuyenlneasiguales
enelarchivocuandoGitpuedeverseenproblemas...Vemosloconunejemplo,recordandoqueanhayuncambiosinversionarenREADME:
$gitcheckouttesting
MREADME
Switchedtobranch'testing'
$gitaddREADME
$gitcommitm"agregocambioaREADMEdeprueba,esperandogenerarconflictoenmaster"
[testing6d32c82]agregocambioaREADMEdeprueba,esperandogenerarconflictoenmaster
1fileschanged,1insertions(+),0deletions()
Hastaaquversionamoselcambioalbranchtesting...
$gitcheckoutmasterm_lang
Switchedtobranch'masterm_lang'
Yourbranchisaheadof'origin/masterm_lang'by2commits.
$echo"helloREADME">>README
$gitaddREADME
$gitcommitm"agregocambioaREADMEesperandogenerarconflictocuandohagamerge"
[masterm_langaa7cca6]agregocambioaREADMEesperandogenerarconflictocuandohagamerge
1fileschanged,1insertions(+),0deletions()
Ahora regresamos a masterm_lang y ah hicimos un cambio diferente sobre el mismo archivo, en la misma lnea (la ltima) que el cambio que se version en
testing.Todoesoantesdelmerge.Yahoraaverquepasa:
$gitmergetesting
AutomergingREADME
CONFLICT(content):MergeconflictinREADME
Automaticmergefailedfixconflictsandthencommittheresult.
$gitstatuss
UUREADME
$tailREADME
Mexicocity
23/january/2009

<<<<<<<HEAD
helloREADM
=======
holaREADME
>>>>>>>testing
Qu sucedi?? Pues que Git no supo qu hacer y gener un conflicto al hacer el merge. Este conflicto queda marcado para Git (segn el resultado de git
statuss,ytambindentrodelmismoarchivoREADME,comopuedeverseporlosmarcadoresqueseagregaronautomticamentealarchivoenloslugaresen
dondeocurrielconflicto.
Ypararesolverelconflicto,senecesitalaintervencinhumana.Normalmenteaquesdondelosdesarrolladoresresponsablesdeloscambiosqueocasionaronel
conflictosebatenendueloponendeacuerdoparadecidircmoresolverelconflicto.Alfinal,unodelosdesarrolladoresdebereditarelarchivoconconflicto,dejar
el cambio adecuado y retirar las marcas de conflicto (<<<< y >>>>) que coloc Git. Esto lo puede hacer editando manualmente el archivo o con alguna
herramientaderesolucindeconflictos,invocandogitmergetool.
YesaeslaformaenquesetrabajaconlosbranchesenGit.Conotrosversionadoresesposiblelograrestemismotipodeprocesoyorganizacin,perorequiere
deadministracinextraporpartedelusuario,cosaalaquemuchosproyectosnoestnacostumbrados.Obviamente,paralograrsacarleprovechoalosbranches,
hayquetambinorganizarseunpoco.Estelinkpuedesertilparaquienbusquealgunaguaprctica(eningls).
gitlog
UnsistemaquemanejataneficientementetantainformacincomoGitnoseranadatilsinopermitieratambinmostrardemaneraordenadadichainformacinal
usuario,deformaquelpuedasaberconexactitudalgnpedazoquelesearealmentetil.Paraesoexistegitlog.
EstecomandotieneenrealidadmuchosusosymuchasformasdiferentesdegeneraryreportarlainformacinconquecuentaGit,porloqueveremossolamente
algunosejemplosquepodransertiles:
$gitlog
commit8ca28c3c01257ec70816dee2d9a4f9338395ab04
Merge:5d2d17e2f77f01
Author:JavierNovoaC
Date:FriJul1510:38:1220110500
Mergeluegodeconflicto
commit5d2d17e1773c417c89692db8e4eb7af46c442e13
Author:JavierNovoaC
Date:FriJul1510:36:0720110500
agregocambioaREADMEesperandogenerarconflictocuandohagamerge
commit2f77f0110cc5138db58050ced9247beb51b8532d
Author:JavierNovoaC
Date:FriJul1510:35:3720110500
agregocambioaREADMEdeprueba,esperandogenerarconflictoenmaster
commit97bc9fbc9aa2e030c7981edafc9565f5a122f555
Author:JavierNovoaC
Date:FriJul1510:34:4420110500
agregotextoanew_file,comoprueba
commit4882d44687aa668fc4115f596552e431e5a6e9d1
Author:JavierNovoaC
Date:FriJul1510:32:3320110500
miscambiosalREADMEycreandonew_file
commit23c4c4e0b77ac69599ef2a751c61786165bc561a
Author:JavierNovoaC
Date:MonMar1417:14:3620110600
removedbianryfile
Estaeslasalidapordefaultdegitlog.Muestraenbloquescadaunodeloscommitsquesehanhechodentrodelbranchactual(siestuviramosenotrobranch
y no se hubieran hecho los merge correspondientes, podra verse otra informacin tambin, aunque ambos branches coincidiran en su log desde el inicio de la
existenciadelbranchpadredesdeelquesegenerelactualhastaelmomentoenquesecreelbranchnuevo).
Se puede observar que se da informacin como una clave distinta para identificar cada commit hecho, los datos del responsable de tal commit, la descripcin
dada en su momento. E incluso cuando se trata de merge, se identifican los commit inmiscuidos. Este identificador de los commit se puede usar como
parmetroacomandoscomogitdiffparacompararelestadoactualdelproyectocontalocualversindelrepositorio(enlugardelHEAD)
$gitlogoneline
8ca28c3Mergeluegodeconflicto
5d2d17eagregocambioaREADMEesperandogenerarconflictocuandohagamerge
2f77f01agregocambioaREADMEdeprueba,esperandogenerarconflictoenmaster
97bc9fbagregotextoanew_file,comoprueba
4882d44miscambiosalREADMEycreandonew_file
23c4c4eremovedbianryfile
Con el parmetro oneline se muestra solamente el identificador corto del commit y la descripcin del mismo, para un resumen breve. Ntese aqu la
importancia de buenas descripciones en los commit: es la informacin de la evolucin del sistema lo que se est describiendo, no hay que tomarse a la ligera
escribirbuenasdescripciones...
$gitlogonelinegraph
*8ca28c3Mergeluegodeconflicto
|\
|*2f77f01agregocambioaREADMEdeprueba,esperandogenerarconflictoenmaster
*|5d2d17eagregocambioaREADMEesperandogenerarconflictocuandohagamerge
|/
*97bc9fbagregotextoanew_file,comoprueba
*4882d44miscambiosalREADMEycreandonew_file
*23c4c4eremovedbianryfile
Con el parmetro graph se puede ver incluso de manera visual cmo han evolucionado los branches y los posibles merge hechos entre ellos. Una opcin
utilsima...
gittag
Paraterminarconesteasuntodelosbranches,vamosamencionarlostags.Casicualquierversionadorpermitemanejaresteconcepto(unosmsfcilmenteque
otros).Laideadetrsdeuntagestenerunaespeciedefotografafijadelproyectoenciertomomento.Deesaforma,cuandosequieratenerelcdigodelproyecto
justocomosetuvoenelmomentodetomarla'fotografa',simplementeunovaaltagylorecupera.
Estoessumamentetilcuando,porejemplo,setieneelproyectoenunestadolistoparaliberaraunentornodeproduccin.Anseplaneanmejoras,seplanea
mantenimiento, pero en ese estado justamente se decide tener la, digamos, versin 1.1.2 del software. Entonces se genera un tag del momento del proyecto
deseado, se le etiqueta como 'versin 1.1.2' y listo! Git tiene la informacin que nosotros podemos usar cuando deseemos, por ejemplo regresamos el cdigo al
estadodeesetagyluegoempaquetamosocompilamosoloquefueranecesario...
$gittagav1.1.2
$gitlogonelinedecorategraph
*8ca28c3(HEAD,tag:v1.1.2,masterm_lang)Mergeluegodeconflicto
|\
|*2f77f01(testing)agregocambioaREADMEdeprueba,esperandogenerarconflictoenmaster
*|5d2d17eagregocambioaREADMEesperandogenerarconflictocuandohagamerge
|/
*97bc9fbagregotextoanew_file,comoprueba
*4882d44miscambiosalREADMEycreandonew_file
*23c4c4e(origin/masterm_lang,origin/HEAD)removedbianryfile
Comosepuedeobservar,alusarelparmetrodecoratedegitlog (que muestra ms informacin sobre los branches), tambin se muestra ahora el tag que
acabamosdegenerarparaelHEADdelrepositorio.Obviamente,tambinsepuededartagaalgunaversindiferentealHEAD,paralocualalcomandogittag
simplementeseleagregaraelidentificadordelcommitalquedeseemosponerleeltag:
$gittagav1.1.2beta97bc9fb
$gitlogonelinedecorategraph
*8ca28c3(HEAD,tag:v1.1.2,masterm_lang)Mergeluegodeconflicto
|\
|*2f77f01(testing)agregocambioaREADMEdeprueba,esperandogenerarconflictoenmaster
*|5d2d17eagregocambioaREADMEesperandogenerarconflictocuandohagamerge
|/
*97bc9fb(tag:v1.1.2beta)agregotextoanew_file,comoprueba
*4882d44miscambiosalREADMEycreandonew_file
*23c4c4e(origin/masterm_lang,origin/HEAD)removedbianryfile
Parapasarelcdigodeuntagaotro,sepuedeusarelmismocomandogitcheckout,peroenlugardeusarelnombredeunbranchcomoparmetro,seusael
nombredadoaltag(tambinsepuedeusarelidentificadordeuncommitcualquiera).Solamentehayquetenercuidado,siellugaralquenosmovemosnoesun
branchespecfico,Gitentraaunestadoenelquelacopiadetrabajoactualnoestenningnbranch,yesnecesariomoversedeahparacontinuartrabajando.
Porltimo,elparmetrolinformardetodoslostagsquetengacreadoselrepositorio:
$gittagl
v1.1.2
v1.1.2beta
Interactuandoconunrepositorioremoto
Comohastaahorasehapodidoconstatar,Gitnoutilizaservidorescentralesconlosrepositorios,alamaneradeSVNyotrosVCS.UnVCSdistribuidocomoGit
bsicamente genera un nuevo 'servidor' Git por cada clonacin de un repositorio Git que se haga, no hay ninguna diferencia entre el servidor y el cliente, ambos
sonelmismoyutilizanelmismoformatoparalainformacinquealmacenan.
UnavezquesetieneunrepositorioGitsobreelqueversionaralgnproyecto,selepuedeindicaraGitquesincronicelainformacindeesterepositorioconalgn
otro repositorio remoto, de forma que este ltimo pueda tener los ltimos cambios que se han realizado sobre el repositorio local o que ste se actualice a los
ltimoscambiosqueotroshansubidoalrepositorioremoto.
YlaventajaconGitesquenohaynecesidaddehacerestodeformaquecoincidaconningncommit!Lasincronizacinesunprocesototalmentediferenciado
delversionado,ynointerfiereconelfuncionamientomismodeversionarelcdigoymanejarlasversionesdelmismoaconciencia.
Enresumen,seutilizagitfetchparaactualizarelrepositoriolocalconcambiosdelremotoygitpushparaenviarloscambios(versioneshechasconcommit)
dellocalalrepositorioremoto.Laadministracinderepositoriosremotosselogracongitremote.
gitremote
PuestoqueenGitunclienteyunservidoresbsicamentelomismo,sepuedentenerdeclaradosmsdeunrepositorioremotoyelegirelquesedeseeusaren
determinadomomento,porejemplotenerunrepositoriodeaccesocompletoyotrodeslolectura.
Aliniciarunrepositoriocongitinitnohayningnrepositorioremotodeclarado.Sinembargocongitclone, el repositorio remoto por default es el de la URL
utilizadaparaclonarelrepositorio.Pordefaultelnombredesterepositorioesorigin.Gitutilizanombrescortosparaidentificarlosrepositoriosremotos,deforma
quenotengaquerecordarsesiempre,oestartecleando,laURLdelosmismos.
Congitremotesepuedenverlosrepositoriosremotosquesetienenactualmentedadosdealta:
$gitremote
origin
$gitremotev
origingit://github.com/jstitch/masterm.git(fetch)
origingit://github.com/jstitch/masterm.git(push)
ElparmetrovmuestralaURLasociadaalremoto.GitinclusopermitetenerdistintasURLsparaunmismoremoto,dependiendolasoperacionesquesequieran
hacersobreellas:fetch(lecturas)ypush(escrituras).
Congitremoteaddsepuededardealtaotrorepositorioremoto:
$gitremoteaddinvernaliagit@invernalia.homelinux.net:masterm.git
$gitremotev
invernaliagit@invernalia.homelinux.net:masterm.git(fetch)
invernaliagit@invernalia.homelinux.net:masterm.git(push)
origingit://github.com/jstitch/masterm.git(fetch)
origingit://github.com/jstitch/masterm.git(push)
Ycomoseve,yahayunnuevorepositorioremotodeclaradoennuestrorepositorioGit.Ahora,ausarlo...:)
gitfetchmerge/pull
Con Git hay dos opciones para obtener los ltimos commit de un repositorio remoto: gitpull y gitfetch/gitmerge. Bsicamente, el pull hace un fetch
seguido de un merge, pero si lo que se desea es tener mayor control sobre lo que se va a actualizar, puntualmente y procediendo branch por branch, el
fetch/mergesiempreesmuchomejoropcin.
$gitfetchinvernalia
Frominvernalia.homelinux.net:masterm
remote:Countingobjects:5,done.
remote:Compressingobjects:100%(2/2),done.
remote:Total3(delta1),reused0(delta0)
Unpackingobjects:100%(3/3),done.
Frominvernalia.homelinux.net:masterm
23c4c4e..010040bmasterm_lang>invernalia/masterm_lang
*[newbranch]test_remote>invernalia/test_remote
*[newtag]v1.1.2beta1>v1.1.2beta1
Comosepuedeobservar,eneseservidorremotoalguienyahizouncommitsobreelbranchmasterm_langyagregunnuevobranchtest_remoteyunnuevotag
v1.1.2beta1,cambiosqueyafueronbajadosaunqueelcdigoannoreflejaningncambiotodava...
Comopuedeobservarse,Githaceunmapeoconloscambioshechosylosrepositoriosremotos.As,elbranchmasterm_langdelremotoinvernaliasellamaahora
invernalia/masterm_lang.Ahorapodrahacerseungitlogparaobservarqucambiossernsincronizados,yalfinalungitmerge:
$gitloginvernalia/masterm_langonelinedecorategraph
*010040b(tag:v1.1.2beta1,invernalia/masterm_lang)agregounarchivoenelremote
*23c4c4e(origin/masterm_lang,origin/HEAD)removedbianryfile

$gitloginvernalia/test_remoteonelinedecorategraph
*4aa265d(invernalia/test_remote)maspruebasconarchivoenbranchdepruebas
*010040b(tag:v1.1.2beta1,invernalia/masterm_lang)agregounarchivoenelremote
*23c4c4e(origin/masterm_lang,origin/HEAD)removedbianryfile
Esdecir,hayuncommitenmasterm_langydoscommitentest_remote,queporsusdescripcionesyanospodemoshacerunaideadequsern...
$gitmergeinvernalia/masterm_lang
Mergemadebyrecursive.
new_file_from_remote|1+
1fileschanged,1insertions(+),0deletions()
createmode100644new_file_from_remote

$ls
BUGScurstextlib.hINSTALLlanguages.hMakefilemasterm.hnew_file_from_remoteTODO
cursors.hHISTORYintl/LICENSEmasterm.c*new_fileREADMEutils.h
$catnew_file_from_remote
holadesdeelremote\!
$gitlogonelinedecorategraph
*c502d2e(HEAD,masterm_lang)Mergeremotetrackingbranch'invernalia/masterm_lang'intomasterm_lang
|\
|*010040b(tag:v1.1.2beta1,invernalia/masterm_lang)agregounarchivoenelremote
*|8ca28c3(tag:v1.1.2)Mergeluegodeconflicto
|\\
|*|2f77f01(testing)agregocambioaREADMEdeprueba,esperandogenerarconflictoenmaster
*||5d2d17eagregocambioaREADMEesperandogenerarconflictocuandohagamerge
|//
*|97bc9fb(tag:v1.1.2beta)agregotextoanew_file,comoprueba
*|4882d44miscambiosalREADMEycreandonew_file
|/
*23c4c4e(origin/masterm_lang,origin/HEAD)removedbianryfile
Comopuedeobservarse,seagregounnuevoarchivo,einclusoelrboldeversionesseactualizconlainformacinqueseobtuvodesdeelrepositorioremoto...
$gitmergeinvernalia/test_remote
Mergemadebyrecursive.
new_file_from_remote|2++
1fileschanged,2insertions(+),0deletions()
$catnew_file_from_remote
holadesdeelremote\!

linea2
Yestointegratambinamasterm_langloscambiosenelotrobranch:eldeinvernalia/test_remote...
gitpush
En caso de tener permisos, un push nos permitir subir nuestros cambios al repositorio remoto. De lo contrario, es necesario hacer una operacin llamada pull
requestqueexplicarmsadelante.
$gitpushinvernaliamasterm_lang
Countingobjects:22,done.
Deltacompressionusingupto2threads.
Compressingobjects:100%(16/16),done.
Writingobjects:100%(18/18),1.78KiB,done.
Total18(delta10),reused0(delta0)
Togit@invernalia.homelinux.net:masterm.git
010040b..c932ba4masterm_lang>masterm_lang
Como se muestra, se enviaron al repositorio remoto los cambios del branch masterm_lang. Tambin podran enviarse los del branch testing que, dicho sea de
paso,noexisteenelrepositorioremoto(esocranmelo,ashicelaspruebas):
$gitpushinvernaliatesting
Total0(delta0),reused0(delta0)
Togit@invernalia.homelinux.net:masterm.git
*[newbranch]testing>testing
Tambinenviamoslostags:
$gitpushinvernaliav1.1.2
Countingobjects:1,done.
Writingobjects:100%(1/1),213bytes,done.
Total1(delta0),reused0(delta0)
Togit@invernalia.homelinux.net:masterm.git
*[newtag]v1.1.2>v1.1.2
$gitpushinvernaliav1.1.2beta
Countingobjects:1,done.
Writingobjects:100%(1/1),194bytes,done.
Total1(delta0),reused0(delta0)
Togit@invernalia.homelinux.net:masterm.git
*[newtag]v1.1.2beta>v1.1.2beta
Unvistazoalrepositorioremotoluegodelpush:sevenloscambiosqueoriginalmentesehabanhechoenelrepositoriolocal
gitrequestpull
Cuandonosetenganpermisosparaescribirenelrepositorioremoto,peroanassedeseeintentarcolaborar,Gitproporcionaunmecanismoparasolicitaraquien
mantengaelrepositorioquelehagaunpull(ounfetch/merge)anuestrorepositoriolocalyaslograrenviarnuestroscambios.
Paralograresto,paraempezar,elrepositoriolocaldebeestarconfiguradoparapoderproporcionarcdigoamaneradeunservidor,configuracinquequedafuera
delespectrodeesteartculo.
$gitcheckoutmasterm_lang
Switchedtobranch'masterm_lang'
Yourbranchisaheadof'origin/masterm_lang'by9commits.
$echo"nuevocambio">>README
$gitaddREADME
$gitcommitm"otrocambioparaprobarpullrequest"
[masterm_lang36260b0]otrocambioparaprobarpullrequest
1fileschanged,1insertions(+),0deletions()
$gittagv1.1.3beta
$gitrequestpullv1.1.3betagit@invernalia.homelinux.net:masterm.git
Thefollowingchangessincecommit36260b08b8c3e09baa1b4d882d82cc8620fdb016:
otrocambioparaprobarpullrequest(2011071514:26:070500)
areavailableinthegitrepositoryat:
git@invernalia.homelinux.net:masterm.git/masterm_lang
Paramsinformacin,sepuedeconsultarlapginademanualdegitrequestpull(1).
Conclusin
ConestoterminamoselrecorridoporvariasdelascaractersticasmsdestacablesdeGit.Noestntodaslasqueson,peroalmenoslasqueestnpuedenservir
comounprimerpasoparacomenzaraversionarutilizandoestagrandiosaherramienta.
Git tiene muchas caractersticas y comandos ms, a los que hay que ir revisando para utilizarlo en toda su potencia. Los comandos y opciones hasta aqu
mencionadosansepuedencomplementarconmsopciones.
Ycomosiempre,paramsreferencias,consultarladocumentacinoficial,pginasdelmanualygoogle.
Lo nico que queda ya es estudiar como utilizar el servicio GitHub, lo que haremos en la siguiente y ltima parte. Mientras tanto, como conclusin a todo esto,
notarcomoelusodeunversionadorsepuedeconvertirenunadelasherramientasmstilesparaadministrarymanejarcdigofuenteendiversosproyectos.No
eslanicaherramientaimportante,muchomenosparaproyectosdesoftwarelibre,perosunadelasmsfundamentales.Claro,enalgnmomentotambinhabr
que dedicarse a estudiar otras herramientas, en cuanto a administracin: trackers de issues y bugs, posiblemente administradores de proyectos en cuanto a
programacin: frameworks de pruebas unitarias y funcionales acordes al lenguaje en que est hecho el proyecto, depurardores en cuanto a documentacin:
frameworksparadocumentarcdigoygenerardocumentacindeAPIs,wikisytodounlargoetctera...
InterfacesparaGit
gitguisencillainterfazgrficaportablebasadaenTcl/Tk,eslainterfazgrfica'oficial'delproyecto
gitkinterfazgrficaparavisualizarrepositoriosysushistoriales.Tambinesparte'oficial'delproyecto
ViewGitunnavegadorderepositoriosGithechoenPHP
TortoiseGitparaWindows
TowerparalaMac
IDEsquetienensoporteparaGit:Eclipse,Netbeans,Xcode
Parasaberms...
AqupongounoslinksconmsinformacinsobreGit:
ManualdeusuariodeGit[eningls]
TutorialdeGit
ReferenciadeGit[eningls]granpartedelainformacindeesteartculolabaseenste
gittutorial(7)[eningls]
AsuccessfulGitbranchingmodel[eningls]excelenteguasobrecmopodraimplantarseunmodelodeversionadoconbranchesusandoGitenambientes
dedesarrollo
parte1(Versionadores)
parte3(Github)
Aadirnuevocomentario

ThemebyDanetsoftandDanangProboSayektiinspiredbyMaksimer
Default(Danland) Cambiartema
Utlienaur!Autailme!Aurentuluva!
Thedayhascome!Thenightispassing!Dayshallcomeagain!
Fingon/HrinThalion
J.R.R.Tolkien,TheSilmarillion
Accesibilidad Contacto Acercade Feed Mapadelsitio Licencia

También podría gustarte