Date post: | 09-Apr-2016 |
Category: |
Documents |
Upload: | eazyduiz2289 |
View: | 1 times |
Download: | 0 times |
1. Introduction2. Licencia3. Elproblema4. Lasolución5. Introducción6. Instalación7. Configuracióninicial8. Gitbásico
i. Ignorandoarchivosii. Revirtiendocambiosiii. Removerymoverarchivosiv. Tagging
9. Ramificaciones10. Repositoriosremotos
i. Creandounrepositorioengithubii. Clonandorepositoriosiii. Enviandocambiosalrepositorioremotoiv. Obteniendocambiosdelrepositorioremoto
TableofContents
DOIDOI 10.5281/zenodo.1395010.5281/zenodo.13950
Elpresentedocumentoesunaguíadeintroducciónagit.Secompartedeformapublicaconelobjetivodeextendersualcanceatodapersonaquedeseecolaboraryaseacorrigiendo,agregandonuevocontenidoobiencompartiendoelpresenteconsusamigos,comunidades,etc.
DesdelaComunidaddeSoftwareyHardwareLibredelaUniversidaddeElSalvadorFMOcc,creemosqueelconocimientodebeestaralalcancedetodosytodasynodebeserdeningunaformalimitadoapocaspersonas.
Nohayaportequenovalga,todoaporte,porpequeñoqueseaesbienvenidoenlacomunidad.
Puedescontribuirconlacomunidadyaseacompartiendocódigo,materialdidáctico,difundiendoelSoftwareyhardwarelibre,difundiendolacomunidad,etc.
Sideseascolaborarhasunforkdelproyectoenhttps://github.com/csluesocc/introduccionGit,edita,agreganuevocontenidoyhasunpullrequestaesteproyecto.
ComunidaddeSoftwareyHardwareLibre
Introducciónagit
CarlosCárcamo,2015
Quedaadisposicióndetodapersonainteresadaenexpandirelconocimientoconsusiguales.Copiar,editarydistribuirestapermitido,siempreycuandoserespetelostérminosdelicenciaabajomencionados.
Quiendeseecontribuiraestedocumento,estaenlalibertaddehacerlo,porlocualestedocumentoserapublicadoenunrepositoriopúblicoengithubenelsiguienteenlace:https://github.com/csluesocc/introduccionGit,desdedondepodrásereditadoyposteriormentepublicado.Enelmomentoquedeseescolaborar,porfavorhasunforkdelrepositorio,haslasrespectivasobservacionesy/oedicionesaldocumentoyagregatunombrealalistadecolaboradoresacontinuación:
EstaobraestábajounaLicenciaCreativeCommonsAtribución-NoComercial-CompartirIgual4.0Internacional.Puedecopiar,distribuiryrealizarobrasderivadasdeltextooriginalsiempreycuandosehagareferenciaalautorynosepersigaunafinalidadcomercial.
COLABORADORES:
Lossistemasdecontroldeversionessonaquellosqueseencarganderegistrarloscambiosrealizadossobreunarchivoounconjuntodearchivosalolargodeltiempo,conelobjetivodemanteneruncontrolsistemáticopermitiendoasíenunfuturorecuperarversionesespecificasdelolosarchivosmodificados.
Esmuycomúnencontrarseconlasituacióndondesecreaunarchivoyluegosemodificaperdiendoloscambioshechosantesdelaultimaactualización;hayunaformadeevitarelproblemaanterioryeshaciendounacopialocal,renombrarlayhacerloscambiosenelnuevoarchivomanteniendolaintegridaddelarchivooriginal,pero,¿quepasasisehanhecho5cambiosbastantesignificativosalarchivo?Habríaquecrear5copiasdiferentes¿ysitrabajoenequipoycadapersonamodificaunapartedelarchivo?,estasituaciónsevuelvecomplicadaypocoeficiente,laimagenacontinuaciónmuestraestasituación:
¿Ysinosoloesunsimplearchivosinounproyectograndecondiferentesmódulosyvariaspersonastrabajandosobreeste?
Elproblemadetenerestetipodecontrol,pocoeficiente,radicaenquepuedecausarseriosconflictosdebidoaquecadausuariodebeentregarsusmodificacionesalosdemásyviceversaycadaunodeestosdebeordenarsusarchivos,teniendocuidadodenosobrescribiralgúnarchivoodirectorio,y¿quepasasiporerrormidiscodurocolapsaynotuvetiempodeentregarmisúltimasmodificaciones?,tengoquevolverahacerloscambios!osilapersonaquellevacontroldelsistemapierdelainformación...quetristesituación,cuantascopiasdeberécrear,cuantotiempoinvertirécopiando,pegando,renombrando,etc.
ELPROBLEMA
SISTEMASDECONTROLDEVERSIONES
Lapenosasituaciónanteriorllevoalanecesidaddecrearunsistemacapazderealizarlastareasanterioresdeformaordenada,concisaysobretodoeficiente,pudiendocentralizareltrabajoenunlugarespecifico,unservidor,aestetipodesistemasselesllamasistemasdecontroldeversionescentralizados(comoapachesubversión)conestosetieneunlugardondemantenerlasversiones,peroaunexisteunproblema,¿Ysielservidorcolapsa?Sepierdetodo!.Tampocosuenamuyeficiente,entoncesquenecesitamos?Larespuestaessencilla,necesitamosunsistemadecontroldeversionesdistribuidos.Enlossistemasdecontroldeversionesdistribuidos(ejemplos:Git,Mercurial,entreotros),losclientesnosólodescarganlaúltimaversióndelosarchivos,lareplicancompletamenteensuscomputadoras.Así,siunservidorcolapsa,cualquieradelosrepositoriosdelosclientespuedecopiarseenelservidorpararestaurarlo(eslomismoquetenerunacopiadeseguridadcompletadelosdatos).
Ahoraendíaconservicioscomolosdegithub,bitbucket,entreotros,mantenerunproyectoesmásfácilynosahorramoslanecesidaddetenerunservidordedicadoparamantenerelproyectoalalcancedetodos,ademáslosusuariospuedenaccederalosrepositoriosdesdecualquierlugarconunaconexiónainternet.
Loanteriorfueunabrevereseñadeloquesonlossistemasdecontroldeversionesydelporquedeberíamosusarlos.
LASOLUCIÓN
LOSSISTEMASDECONTROLDEVERSIONESALRESCATE
Acontinuaciónnoscentraremosenutilizaryponerenpracticaunodelossistemasdecontroldeversiones(SVCporsussiglaseningles)másutilizadosenelmundo,hablamosdegit,creadoporLinusTorvaldselmismocreadordelKernelLinuxyporlacomunidadquetrabajaenelmismokernel.
Enelaño2005naciógitcomounanecesidaddelosdesarrolladoresdelkernelLinuxdetenersupropiosistemadecontroldeversiones,despuésdevariosañosusandoBitKeeper(unsoftwarepropietario)elcualdejodeserunaopciónviableparalacomunidaddedesarrolladores.
GitesdistribuidobajolicenciaGNUGPLv2yestadisponibleparamúltiplessistemasoperativosentreellos,ysindudaalguna,GNU/Linux.
Elpresentedocumentoestahechoamaneradetutorialconelobjetivoqueseafácilyentretenidoutilizargit.
Estetutorialnopretendeserundocumentoextensosobregit,másbienesunabreveintroducciónalmismoysuscomandosmásusados,aunqueconeltiempopuedaqueestedocumentocrezca,tododependedequienescolaboren.
Paramásinformaciónsobregitvisitarladocumentaciónoficialenhttp://git-scm.com/doc.
INTRODUCCIÓN
Parapoderseguirestetutorial,loúnicoquenecesitarásseráunadistroGNU/Linux,unaterminalparaejecutarunpardecomandosysobretodomuchasgranasdeaprendereinvestigar.
Laformamássencilladeinstalargitennuestroordenadoresutilizadoelgestordepaquetesdenuestradistrofavoritaeinstalargitdesdesusrepositorios,gitseguramenteestaenlosrepositoriosdelasdistrosmásconocidasporloquevamosaprocederdelasiguientemanera:
#yuminstallgit-core
obiencon:
$sudoyuminstallgit-core
nota:si“git-core”noexisteenlosrepositoriosutilizar“git”ensulugar.
#apt-getinstallgit
o
$sudoapt-getinstallgit
#pacman-Sgit
otambiéncon:
$sudopacman-Sgit
Situdistronoestaentrelasmencionadas,visitaladocumentacióndetudistro,seguramenteencontraraslospasosnecesariosparainstalargitentusistemafavorito.
Laopciónalternativaausarelgestordepaquetesescompilarelcódigofuentenosotrosmismos.Siquierescompilarelcódigofuentepuedesbuscarenelsiguienteenlacelospasosaseguir:http://git-scm.com/book/en/Getting-Started-Installing-Git.
INSTALACIÓN
INSTALANDOGITENTUDISTROFAVORITA
Fedora,CentOSyderivados:
Debianyderivados:
Archlinuxyderivados:
Loprimeroquedebemoshacer,luegodeinstalargit,esconfigurarnuestronombreyemailconelquegitnosidentificarácadavezquetrabajemossobrenuestrosproyectos.
Gitpermiteconfigurarvariasopcionesysoloesnecesariohacerlounavez,porelmomentonoscentraremosenlobásico,comosiempre,recomendamosindagarunpocoenladocumentaciónoficialparamásdetalles.
Elcomandoqueusaremosparaconfigurarnuestroentornogitsera:gitconfig,quenospermitendefinirvariablesdeconfiguración.
Comencemospordeciragitquienessomosycualesnuestroemail,conestogitydemásusuariossabránquienhahechocambios(commits).
$gitconfig--globaluser.name"Mr.Floyd"
con--globalestasdiciendoagitqueuseestainformaciónentodoloquehagasenelsistema.
Puedesvertuconfiguraciónactualejecutando:
$gitconfig--list
user.name=Mr.Floyd
puedesademáspreguntaragitporparámetrosespecíficosdefinidosentuconfiguración:
$gitconfiguser.email
Sinecesitasunalistacompletadeloscomandosusadosengitpuedesejecutarentuterminal:
$githelp
obienconsultarporuncomandoespecíficocongithelp«comando»:
$githelpconfig
ocomousualmentelohacemosenGNU/Linuxusando'man'
$mangit-config
CONFIGURACIÓNINICIAL
Yahemosconfiguradonuestroentornogit,ahoraeshoradecomenzaratrabajarconel.
Vamosacomenzarcreandoundirectorioenellugarquequeramosylediremosagitquetomeelcontroldetodoloqueenelhagamos:
$mkdirpractica-git&&cdpractica-git
$gitinit
InitializedemptyGitrepositoryin~/practica-git/.git/
gitinitcrearáunsubdirectoriollamado.gitdondeseencuentranlosarchivosnecesariosparallevarelcontroldetudirectorioactual.
$ls-a
$ls.git/
branchesconfigdescriptionHEADhooksinfoobjectsrefs
Comencemosconuncomandoqueusaremosmuchoalolargodeestetutorial:
$gitstatus
#Onbranchmaster
#
#Initialcommit
#
nothingtocommit(create/copyfilesanduse"gitadd"totrack)
gitstatusnosdainformaciónsobrenuestrorepositorioactual,nosdicesialgocambio,sihayconflicto,etc.
Creemosunarchivosencillodentrodenuestrodirectorioactualyveamosquenosdicegitstatus:
$touchscript.py
$gitstatus
#Onbranchmaster
#
#Initialcommit
#
#Untrackedfiles:
#(use"gitadd<file>..."toincludeinwhatwillbecommitted)
#
#script.py
nothingaddedtocommitbutuntrackedfilespresent(use"gitadd"totrack)
Nosdamoscuentaquegithadetectadoquehemoshechocambiosennuestrodirectorio,enestecasohemosagregadounarchivonuevoygitnospidequeusemos“gitadd”parapoderllevarcontroldeestearchivo,procedamosentonces:
$gitaddscript.py
$gitstatus
#Onbranchmaster
#
#Initialcommit
#
#Changestobecommitted:
#(use"gitrm--cached<file>..."tounstage)
#
#newfile:script.py
Hemosincluidonuestroarchivo,perofaltaunpasoyesconfirmar(commit)loscambios:
GITBÁSICO
$gitcommit-m“scriptinicial”
[master(root-commit)3ccd2e0]scriptinicial
0fileschanged
createmode100644script.py
$gitstatus
#Onbranchmaster
nothingtocommit(workingdirectoryclean)
gitstatusnosdicequetenemosundirectoriodetrabajolimpio,estoquieredeciryatenemosunrepositoriogitconunarchivoenseguimientoyunaconfirmacióninicial.Gitademásnosdiceenqueramaestamostrabajando,ennuestrocaso“master”queeslacreadapordefault(másadelantecrearemosyusaremosramas).
Comohemosvistoelprocesodeagregarunarchivoparaquegitllevesucontrolconstadedospasos,agregar(add)yconfirmar(commit).Elcomandogitadd«archivo»puederesultartediosositenemosvariosarchivosyqueremosagregarlostodos,puestendríamosqueagregararchivoporarchivo,perogitnosofreceotrocomandoútil:gitadd.(elpuntodespuésdeladdindicaagitquevamosaagregaralrepositoriotodoslosarchivosdentrodenuestrodirectorio,luegobastaríaconhaceruncommitparaconfirmarloscambios).
Gitnospermiteverloscommitsquesehanhechoennuestrorepositorio,paraellousaremoselcomandologasí:
$gitlog
commit3ccd2e06ed65ce95f7af3df9ca28c0dfb5af5fed
Author:Mr.Floyd<[email protected]>
Date:FriJul1823:39:182014-0600
scriptinicial
Podemosnotarqueelcommittieneunaseriedenúmerosyletras,esoeselidentificadorúnico(ID)quegitasignoanuestrocommit,gitutilizaelhashsha1paraidentificarcadacommitcomoúnicodentrodenuestrorepositorio,porloquepodemoshaceralgocomo:
$gitshow3ccd2e06ed65ce95f7af3df9ca28c0dfb5af5fed
commit3ccd2e06ed65ce95f7af3df9ca28c0dfb5af5fed
Author:Mr.Floyd<[email protected]>
Date:FriJul1823:39:182014-0600
scriptinicial
diff--gita/script.pyb/script.py
newfilemode100644
index0000000..e69de29
conesto,decimosagitquenosmuestrecondetalleelcommitconID3ccd2e06ed65ce95f7af3df9ca28c0dfb5af5fed.EscribirtodoelIDdelcommitresultaunpocotedioso,peronoesnecesarioescribirtodosloscaracteres,podemosobtenerelmismoresultadoanteriorhaciendo:
$gitshow3ccd2e
gitshownospermiteutilizarlosprimeros5,6o7caracteresdelIDdelcommitenlugardelos40,conestoevitamosescribirtanto.Tambiénpodemosusarelcomandoshowsinespecificarunidygitnosdarádetalledelcommitmásreciente.
$gitshow
Ahoravamosamodificarelscriptquehemoscreadoyvercomoreaccionagitanteloscambiosquehagamos,paraelejemploagregaremosunpardelineas:
Nota:concatmostramoslaslineasquehemosagregadoanuestroscript.py,puedesagregarlaslineasquedesees,alfinyalcabosolonosinteresaloquenosmuestregit.
$catscript
#!/usr/bin/envpython
print"holamundo,somoslaCSHL"
$gitstatus
#Onbranchmaster
#Changesnotstagedforcommit:
#(use"gitadd<file>..."toupdatewhatwillbecommitted)
#(use"gitcheckout--<file>..."todiscardchangesinworkingdirectory)
#
#modified:script.py
#
nochangesaddedtocommit(use"gitadd"and/or"gitcommit-a")
Gitnosinformaqueelarchivoquecreamoshasidomodificadoypidequeconfirmemossusmodificaciones,nossugieredoscomandos,“gitadd”o“gitcommit-a”,elprimeroyalohemosutilizadoysabemosqueconstadedospasos,agregar(add)yconfirmar(commit),elsegundocomandoquenossugierepuedeefectuarlosdospasosanterioresdeunasolavez,porconvenienciausaremoselsegundoperoagregaremosunaopciónmás,así:
$gitcommit-am“HolamundodesdelaCSHL”
[master79ba623]HolamundodesdelaCSHL
1filechanged,3insertions(+)
modechange100644=>100755script.py
Veamosahoraqueinformaciónpodemosobtenersobrelosúltimoscambioshechos:
$gitstatus
#Onbranchmaster
nothingtocommit(workingdirectoryclean)
$gitlog–graph
*commit79ba623acf7741e21cc1b6ccb3435301405ec0d3
|Author:Mr.Floyd<[email protected]>
|Date:SatJul1900:36:482014-0600
|
|HolamundodesdelaCSHL
|
*commit3ccd2e06ed65ce95f7af3df9ca28c0dfb5af5fed
Author:Mr.Floyd<[email protected]>
Date:FriJul1823:39:182014-0600
scriptinicial
Vemoscomostatusnosmuestraquenohaymáscambiosennuestroarchivos,elcomandolog--graphnosmuestraunapequeñagráficaenamodoconsoladeloscommitsquehemoshecho.
Podemostambiéndecirleagitqueignoreciertosarchivosy/odirectorios,estosnoseránrastreadosynoseránpartedelrepositorioaunqueestosesténennuestrodirectorioactual,estoesnecesariomuchasvecesporqueavecesloseditoresqueusamosparatrabajarcreanarchivostemporaleseneldirectorioactual,archivoscomo~script.pyquerealmentenoqueremosqueseanpartedenuestroproyecto,paraesogittieneunarchivoespecialllamado.gitignorequedebemoscrearloyhacerleuncommitennuestrarepo.
Elarchivo.gitignoreesunsimplearchivodetextoqueindicaquetipoarchivosqueremosquegitignore,creemosnuestro.gitignore:
$touch.gitignore
$gitstatus
#Onbranchmaster
#Untrackedfiles:
#(use"gitadd<file>..."toincludeinwhatwillbecommitted)
#
#.gitignore
nothingaddedtocommitbutuntrackedfilespresent(use"gitadd"totrack
gitnosdicequehayunnuevoarchivo,enelvamosaagregarlosiguiente:
$cat.gitignore
#ignorarlosarchivosquecoincidanconlossiguientespatrones
~*
*.so
*.log
Agreguemoselarchivoanterioranuestrorepositorio
$gitadd.gitignore
$gitcommit-am"ignorararchivos"
[master8597e52]ignorararchivos
1filechanged,6insertions(+)
createmode100644.gitignore
$gitstatus
#Onbranchmaster
nothingtocommit(workingdirectoryclean)
Ahorapodemosprobaragregandounarchivoquecumplaconlospatronesqueseespecificaronen.gitignore,probemossifunciona:
$touch~temp
$gitstatus
#Onbranchmaster
nothingtocommit(workingdirectoryclean)
efectivamentegithaignoradoesearchivo,puedesagregarlospatronesqueconsideresnecesariosparaquegitignorelosarchivosquecoincidanconloquehasdefinido.
En.gitignorepodemosusarexpresionesregulares,porejemplo,hemosusado~*queindicaagitqueignoretodoslosarchivosquecomienzenconelsimbolo~,asípodemoscrearpatronesparahacerquegitsecomportedemaneramásinteligente.Notarquetambiénhemosusadolaalmohadilla#paraescribiruncomentario,en.gitignoretodoeltextoprecedidoporlaalomadillaseraignoradoynoafectaraelsufuncionamiento.
Podemosignorardirectorioscompletos,porejemplo:
IGNORANDOARCHIVOS
#ignorarlosdirectoriossiguientes
bower/
libs/
Loanteriorlediceagitqueignoreelcontenidodelosdirectoriosbowerylibs,podemosademásdecirleagitqueingnoretodoeldirectorioexceptociertosarchivos,porejemplo:
#ignorarlosdirectoriossiguientes
bower/
libs/
#noignorarelsiguientearchivo
!libs/miScript.py
Lehemosdichoagitqueignoretodoslosarchivoseneldirectoriolibs/exceptoporelarchivomiScript.py,simplementehemosusadoelsimbolo!paraidicarqueesearchivonodebeserignorado,estoesrealmenteutilenproyectosgrandesdondehayarchivosquenodebenserignorados.
Unalistaextensadeejemplosde.gitignoreparadiferentestiposdeproyectospuedeserencontradaen:https://github.com/github/gitignore.Másinformacióndegitignore:http://git-scm.com/docs/gitignore.
Paracontinuarconeltutorialvamosacrearunpardearchivosmásennuestrorepositorioactual.
$touchscript2.pyREADME
$gitstatus
#Onbranchmaster
#Untrackedfiles:
#(use"gitadd<file>..."toincludeinwhatwillbecommitted)
#
#README
#script2.py
nothingaddedtocommitbutuntrackedfilespresent(use"gitadd"totrack)
Efectivamentegitsabequehemoshechocambiosennuestrorepositorioyesperaaqueagreguemoslosnuevosarchivosyqueconfirmemossuseguimiento,procedamosentonces:
$gitadd.
#Onbranchmaster
#Changestobecommitted:
#(use"gitresetHEAD<file>..."tounstage)
#
#newfile:README
#newfile:script2.py
gitnossolicitaqueconfirmemoscambios,tambiénnosdalaopciónderevertirlaacciónanteriorconresetHEAD,veamosquesucedeentonces:
$gitresetHEAD
#Onbranchmaster
#Untrackedfiles:
#(use"gitadd<file>..."toincludeinwhatwillbecommitted)
#
#README
#script2.py
nothingaddedtocommitbutuntrackedfilespresent(use"gitadd"totrack)
Hemosrevertidolaacciónanterioryvolvemosatenerdosarchivosnuevossinagregarennuestrorepositorio,losagregaremosdenuevoparacontinuarconeltutorial.
$gitadd.
$gitcommit-am“segundoscriptyREADME”
[masterfc59723]segundoscriptyREADME
0fileschanged
createmode100644README
createmode100644script2.py
$gitstatus
#Onbranchmaster
nothingtocommit(workingdirectoryclean)
$gitlog--pretty=short
commitfc597238a5147ea8ece42ca6817f932a366b6069
Author:Mr.Floyd<[email protected]>
segundoscriptyREADME
commit79ba623acf7741e21cc1b6ccb3435301405ec0d3
Author:Mr.Floyd<[email protected]>
REVIRTIENDOCAMBIOS
HolamundoestiloCSHL
commit3ccd2e06ed65ce95f7af3df9ca28c0dfb5af5fed
Author:Mr.Floyd<[email protected]>
scriptinicial
Elcomandologtienevariasopcionesútiles(másinformaciónenladocumentaciónoficial)quenosdandetalledeloquehemosestadohaciendoennuestrorepositorio,elcomandoanteriormuestraeldetalledemanerabastanteamigableysencillaalusuario.
Vamosaeditarunarchivomásparamostrarotrasopcionesútilesdegit:
$catREADME
ComunidaddesoftwareyhardwarelibreUESFMOcc
Introducciónagit
$gitdiff
diff--gita/READMEb/README
indexe69de29..d603bef100644
---a/README
+++b/README
@@-0,0+1,3@@
+ComunidaddesoftwareyhardwarelibreUESFMOcc
+
+Introducciónagit
Elcomandogitdiffcomparaloquehayactualmenteennuestrodirectorioconloqueseteniapreviamenteconfirmado,indicaloscambioshechosqueaunnohansidoconfirmados.
$gitcommit-am"README"
AcabamosdeconfirmarloscambiosenREADME.¿Quesucedesinosequivocamosenalgoaleditarelarchivoosiladescripcióndelcommitnonosgustadeltodoyqueremosrevertirlaconfirmación?Puessencillohagamosunresetalultimocommitquehemoshecho:
$gitlog-1--pretty=short
commit592577537bf0587cc4bf80b57b74357081787690
Author:Mr.Floyd<[email protected]>
README
Veamoscualfueelúltimocommithecho,ahorapasemosarevertirelcommit
$gitreset--softHEAD^
$gitstatus
#Onbranchmaster
#Changestobecommitted:
#(use"gitresetHEAD<file>..."tounstage)
#
#modified:README
$catREADME
ComunidaddesoftwareyhardwarelibreUESFMOcc
Introducciónagit
Hemosutilizadogitreset--softHEAD^querevierteelultimocommitrealizadomanteniendoloscambiosquesehicieronenelarchivooarchivosmodificados,alusargitstatusvemosqueefectivamenteregresamosalestadoanteriordelcommit,ahorapodemos,siloqueremos,editardenuevoelarchivoyhacerunnuevocommit.
Vamosahacercommitdenuevoparacontinuar:
$gitcommit-am"READMEactualizado"
[mastere12b294]READMEactualizado
1filechanged,3insertions(+)
Siporcasualidadqueremoseliminarpermanentementeuncommitovarios,podemosusarelcomandoresetconlaopción--hardyelIDdelcommit:sintaxis:$gitreset--hard«commitsha1»Esimportantemencionarqueestecomandoespeligroso,yaqueconestoestaríamosborrandoloscommitquesehanhechoposteriormentealcommitquehemosespecificado,nohabráformaderevertirloscambios¿oquizássi?
«tendríamosqueinvestigarunpoco,depasoaprendemosalgonuevoylocompartimosacá...»
Siporejemploqueremoseliminartodoslosarchivosquenoestansiendoseguidosporgitenelrepositorioactualgitnosdauncomandosencilloyutilparaestatarea:
$gitclean-f
Loanteriorindicaagitqueborretodoloquenohasidopreviamenteañadidoalcontroldeversión,paramásinformacionsobreestecomandoiraladocumentaciónofical.
Siqueremoseliminararchivosdenuestrorepositorio,gitofreceotrocomandoútilllamadogitrmmuysimilaralcomandormunix.
Hablemosunpocosobreloquehaceestecomandogitrm,esteeliminaelolosarchivosdenuestrorepositorioypideunaconfirmaciónparamantenerelregistro,elproblemaconestecomandoesqueeliminaelarchivodelrepositorioydeldirectorioenelqueestamostrabajando,escomohacerrm«archivo»enunaterminalGNU/Linux(perosiformopartedelhistóricodegit,esposiblerecuperarlo),gitesbondadosoyofrecelaopcióndeeliminarelarchivodelrepositorioperodejandoelarchivointactoennuestrodirectorio.Sihemoshechocommitaunarchivoporaccidente,podemosusargitrm--cahed«archivo»gitlodejaratalycomoestabaantesdehacerelcommit,veamosestoconunejemplosencillo:
Vamosacrearunarchivoyloincluiremos“accidentalmente”anuestrorepositorio.
$echo“Oops!”>oops
$gitrmoops
fatal:pathspec'oops'didnotmatchanyfiles
Laoperaciónnofuncionaporqueelarchivoaunnoespartedenuestrorepositorio.
$gitaddoops
$gitcommit-am“commitaccidental”
[master8127794]commitaccidental
1filechanged,1insertion(+)
createmode100644oops
$gitlog-1--pretty=short
commit812779449b6fb39450d1426899a39945b340fb19
Author:Mr.Floyd<[email protected]>
commitaccidental
Hemosagregadoelarchivo“accidentalmente”anuestrorepositorio.Comonoloqueríamosagregar,perosiqueremosmantenerloennuestrodirectorioprocedamosaquitarlodelrepositorio:
$gitrm--cachedoops
rm'oops'
$gitstatus
#Onbranchmaster
#Changestobecommitted:
#(use"gitresetHEAD<file>..."tounstage)
#
#deleted:oops
#Untrackedfiles:
#(use"gitadd<file>..."toincludeinwhatwillbecommitted)
#
#oops
$ls
oopsREADMEscript2.pyscript.py
$gitcommit-am“oopselimiadodelrepositorio”
[master22592c0]oopselimiadodelrepositorio
1filechanged,1deletion(-)
deletemode100644oops
$gitstatus
#Onbranchmaster
#Untrackedfiles:
REMOVERYMOVERARCHIVOS
#(use"gitadd<file>..."toincludeinwhatwillbecommitted)
#
#oops
Githahechobiensutrabajo,haborradodelrepositorioelarchivoperolomantieneintactoennuestrodirectorio.Agregaremosdenuevoelarchivoyestavezloborraremoscongitrm.
$gitaddoops
$gitcommit-am"commitaccidental"
[master43af71f]commitaccidental
1filechanged,1insertion(+)
createmode100644oops
$gitrmoops
rm'oops
$ls
READMEscript2.pyscript.py
$gitstatus
#Onbranchmaster
#Changestobecommitted:
#(use"gitresetHEAD<file>..."tounstage)
#
#deleted:oops
#
$gitcommit-am“oopsborradocorrectamente”
[master0f6d43a]oopsborradocorrectamente
1filechanged,1deletion(-)
deletemode100644oops
Detengámonosunpocoyveamoslosúltimos5commitsquehemoshecho:
$gitlog-5--pretty=short
commit0f6d43a9c0687fa70ca95700aae45d75b782bb43
Author:Mr.Floyd<[email protected]>
oopsborradocorrectamente
commit43af71fcd7a71e468ebfa57d059f51bd5a9cacee
Author:Mr.Floyd<[email protected]>
commitaccidental
commit22592c0f14990764a21437d792c07fadca50d24a
Author:Mr.Floyd<[email protected]>
oopselimiadodelrepositorio
commit812779449b6fb39450d1426899a39945b340fb19
Author:Mr.Floyd<[email protected]>
commitaccidental
commite12b294a508bee8602943644c3e12a4c2f81583b
Author:Mr.Floyd<[email protected]>
READMEactualizado
Conozcamosahoraotroútilcomandogitmv,eselanálogoamvenunixparamoveryrenombrararchivosydirectorios.Segúnladocumentaciónoficial:“Gitnohaceunseguimientoexplicitodelmovimientodearchivos.Sirenombrasunarchivo,enGitnosealmacenaningúnmetadatoqueindiquequelohasrenombrado...”.
«quedandudassobreeso,sisabesalgomásnodudesencompartirloacá...»
Renombremosunodenuestrosarchivos:
$gitmvscript.pyholaMundo.py
$gitstatus
#Onbranchmaster
#Changestobecommitted:
#(use"gitresetHEAD<file>..."tounstage)
#
#renamed:script.py->holaMundo.py
$gitcommit-am"script.pyrenombradoaholaMundo.py"
[masterf3e2083]script.pyrenombradoaholaMundo.py
1filechanged,0insertions(+),0deletions(-)
renamescript.py=>holaMundo.py(100%)
enproceso...
TAGGING
Laramificaciónesunodelosmecanismosmásinteresantesyusadosenlossistemasdecontroldeversionesmodernos,alhablarderamificaciones,hablamosquehemostomadolaramaprincipaldedesarrollo(master)yapartirdeellahemoscontinuadotrabajandosinseguirlaramaprincipaldedesarrollo,esdecirenunaramadiferente.
UnejemplodeestopodríasereldesarrollodelsistemaoperativouniversalGNU/debian,elequipodedebianmantienesiempretresversionesdesusistema,elestable,enpruebasydedesarrollo(actualmenteestasramassonwheezy,jessieysid).Laramaestableesdondelospaqueteshansidoprobadosyestánlistosparasaliralmundoconunmininoonulosbugs,enlaramaenpruebassinembargoesdondesemantienenlospaquetesmásactualizadosperoqueaunnohasuperadolafasedepruebasparasaliralmundoeintegrarsealaramaestable,mientrasquelaramadedesarrolloestánlospaquetes,módulosdelsistema,etc.queaunnoestánlistosparaproducciónyqueestáncambiandoconstantementeyquepuedenterminaragregándoseosereliminadosencualquiermomento.
Procedamosentoncesacrearnuestraprimeraramificación,actualmenteyaestamostrabajandobajounaramayeslaramamasterquepordefectogitnoscreayqueesdondehemosestadorealizandoloscambios,asíquecrearemosunaramanueva,cabemencionarquealcrearunaramaapartirdeotra,lanuevaramacontiene,inicialmente,losmismosarchivosycommitsquelaramabase,hastaquemodifiquemosoagreguemosnuevosarchivosydirectorios.
$gitbranchtesting
$gitstatus
#Onbranchmaster
nothingtocommit(workingdirectoryclean)
Alparecernohemoshechonada,perohemoscreadounaramanuevallamadatesting,paraverqueestoesciertoejecutemos:
$gitbranch
*master
testing
El'*'dosdiceenqueramaestamosactualmente,cambiemosderamaentoncescongitcheckout:
$gitcheckouttesting
Switchedtobranch'testing'
$gitstatus
#Onbranchtesting
nothingtocommit(workingdirectoryclean)
Vamosaagregarunpardelineasdecódigoaunarchivo
$catscript2.py
#!/usr/bin/envpython
forain[1,2]:
forbin["a","b"]:
printa,b
$gitstatus
#Onbranchtesting
#Changesnotstagedforcommit:
#(use"gitadd<file>..."toupdatewhatwillbecommitted)
#(use"gitcheckout--<file>..."todiscardchangesinworkingdirectory)
#
#modified:script2.py
#
nochangesaddedtocommit(use"gitadd"and/or"gitcommit-a")
RAMIFICACIONES
$gitadd.
$gitcommit-am"combinacionesenpython"
[testingd3dbf28]combinacionesenpython
1filechanged,5insertions(+)
modechange100644=>100755script2.py
Añadamosunnuevoarchivoparaluegounirlasramastestingymasterenunasola:
$touchscript3.py
$gitadd.
$gitcommit-am"3erscript"
[testing0294943]3erscript
0fileschanged
createmode100644script3.py
$gitstatus
#Onbranchtesting
nothingtocommit(workingdirectoryclean)
hagamosunsimplelogdelos3últimoscommitshechosenlaramatesting:
$gitlog-3--pretty=short
commit0294943eb590210846c2875a07b5a24b08360c52
Author:Mr.Floyd<[email protected]>
3erscript
commitd3dbf28039a7fede95eafea4c0f5378c144c34d6
Author:Mr.Floyd<[email protected]>
combinacionesenpython
commitf3e208303b789e5d944f11a6565f1514714f4132
Author:Mr.Floyd<[email protected]>
script.pyrenombradoaholaMundo.py
Regresemosallaramamasteryhagamostambiénunlog:
$gitcheckoutmaster
Switchedtobranch'master'
$gitlog-3--pretty=short
commitf3e208303b789e5d944f11a6565f1514714f4132
Author:Mr.Floyd<[email protected]>
script.pyrenombradoaholaMundo.py
commit0f6d43a9c0687fa70ca95700aae45d75b782bb43
Author:Mr.Floyd<[email protected]>
oopsborradocorrectamente
commit43af71fcd7a71e468ebfa57d059f51bd5a9cacee
Author:Mr.Floyd<[email protected]>
commitaccidental
ennuestraramamasternoestánlosúltimoscommitsquehicimosenlaramatesting,tenemosqueunirlasramasparaqueloscambiosentestingseapliquenalaramamaster,paraesousaremoselcomandogitmergeasí:
$gitmergetesting
Updatingf3e2083..0294943
Fast-forward
script2.py|5+++++
1filechanged,5insertions(+)
modechange100644=>100755script2.py
createmode100644script3.py
$gitstatus
#Onbranchmaster
nothingtocommit(workingdirectoryclean)
$ls
holaMundo.pyREADMEscript2.pyscript3.py
$catscript2.py
#!/usr/bin/envpython
forain[1,2]:
forbin["a","b"]:
printa,b
Vemosquetenemoslosarchivosactualizadossegúncomolosteníamosenlaramatesting,hagamosunpequeñologparaverquehapasado:
$gitlog-4--pretty=short
commit0294943eb590210846c2875a07b5a24b08360c52
Author:Mr.Floyd<[email protected]>
3erscript
commitd3dbf28039a7fede95eafea4c0f5378c144c34d6
Author:Mr.Floyd<[email protected]>
combinacionesenpython
commitf3e208303b789e5d944f11a6565f1514714f4132
Author:Mr.Floyd<[email protected]>
script.pyrenombradoaholaMundo.py
commit0f6d43a9c0687fa70ca95700aae45d75b782bb43
Author:Mr.Floyd<[email protected]>
oopsborradocorrectamente
Tenemostodoactualizado.
Unpardeobservaciones:sieditamos/agregamos/borramosalgoenunaramaynohacemoslosrespectivosadds,commitsynoscambiamosaunaramadistinta,estaacciónpuedaquenosgenereproblemasenlaramaalaquenosmovimospuesesoscambiostambiénestaránenestaultimaapesarquenohayamostrabajadoenella.Porloanteriorserecomiendahacerlosrespectivoscommitenlaramaactual(dejandolimpioelrepositorio)antesdemoverseaunaramadistinta.
«Sicreesquefaltaalgoqueaclararoañadirenestaparte,porfavorayúdanosamejorarla...»
Comoyahemosunidosnuestroscambiosdelaramatestingenlaramamaster,hagamosdecuentaqueyanonecesitamoslaramatestingyqueremosborrarla.Paraborrarunaramausamosgitbranchconlaopción-dcomoenelsiguienteejemplo:
$gitbranch-dtesting
Deletedbranchtesting(was060ac2d).
$gitbranch
*master
Agrosomodoestoeslabasedelasramificacionesengit,puedesvisitarladocumentaciónoficialparamásinfoyalgunasbuenaspracticas.Tambiénesteenlacepuedeserútilhttp://nvie.com/posts/a-successful-git-branching-model/enelencontrarasunpardeconsejosparacrearunmodeloderamasexitosoparatutrabajoengitenequipoobienproyectospersonales.
«Sicreesconvenienteydeseasampliarestasecciónnodudesenhacerlo,todaayudaesbienvenida:)»
Comosemencionoalprincipiodeestetutorial,existenvariossitioseninternetqueofrecenserviciosdealojamientodecódigoyquepermitenutilizargitparallevarcontroldenuestrosproyectos.Enesteapartadousaremosunodelossitiosmásfamososenelmundoparaalojarcódigo,hablamosdegithub.com,githubnosofrecealojamientogratuitodecódigoentremuchasotrasinteresantesopciones,tambiénofreceservicioprivadoparaempresasoindividualesquequieranmantenersusrepositoriosenprivado,nosotros,comodebeser,tenemosunacuentaengithubdondepublicamoscódigoopensourcequepuedeserclonado,puedenhacerunforkcontribuirdirectamente,etc.
Veamoscomoluceentonceslainterfazdegithub(interfazparaorganizacionesennuestrocaso):
Nota:paracontinuarconestetutorialdeberáscrearunacuentaengithub(esgratis!!!)conlaquecrearemosunrepositoriopublicoytrabajaremosconel.
REPOSITORIOSREMOTOS
Vamosacomenzarporcrearunrepositorioengithubconelcualtrabajaremosalolargodeestetutorial,acontinuacióntemostramoslospasosnecesarios:
Enelmenúsuperiorderecholuegodetunombredeusuarioencontrarasunaseriedeopcionescomomuestralaimagensiguiente:
Damosclickalaopcióncrearnuevorepositorioynosapareceunapantallasimilaralasiguiente:
Procedamosentoncesacrearnuestroprimerrepositorioengithub,llenamoselformularioconlosdatosquequeramosydamosclickalbotón“createrepository”,nosmostraraunapantallaconunaseriedeopcionesparaelmanejodenuestrosrepositorios,esbuenaideanavegarunpocoestainterfazyverqueopcionesnosofrecegithub.
CREANDOUNREPOSITORIOENGITHUB
Laimagenacontinuaciónnosmuestralainformacióndenuestroreciéncreadorepositorio,pongamosatenciónaláreamarcadaconazul”HTTPScloneURL”,esaáreanosdaelvinculodirectoanuestrorepositorioconelcualpodemosclonarloanuestroordenadorypoderentoncestrabajarsobreel,enviandocambios(push)yobteniendolasactualizacionesmásrecientesdelrepositorio(pull).
Comencemosentoncesconlapractica,copiemoselvinculo“cloneurl”yabramosunaterminalyejecutemoselcomandoclone:
$gitclonehttps://github.com/carloscarcamo/practica-git.git
Cloninginto'practica-git'...
remote:Countingobjects:4,done.
remote:Compressingobjects:100%(4/4),done.
remote:Total4(delta0),reused0(delta0)
Unpackingobjects:100%(4/4),done.
$cdpractica-git
$ls
LICENSEREADME.md
Hemosclonadoexitosamentenuestrorepositorioanuestroordenador,luegoentramosaldirectorioylistamoslosarchivosquetenemosdentro,efectivamentepodemosobservarquetenemosdosarchivosLICENSEyREADMEquesonlosqueseañadieronalmomentodecrearnuestrorepositorioengithub.
Podemosveraqueurlapuntanuestrorepositorioremotousandogitremote-v,así:
$gitremote-v
originhttps://github.com/carloscarcamo/practica-git.git(fetch)
originhttps://github.com/carloscarcamo/practica-git.git(push)
Gitnosinformadelaurlalaquenuestrorepositorioharálosrespectivospushypull.
CLONANDOREPOSITORIOS
Ahoraestamoslistosparaagregarymodificarnuevosarchivosdentrodeesterepositorioyenviarloscambiosagithub,procedamosentoncesagregandounpardearchivosydirectorios:
$mkdircssjs
$touchindex.html
Hemosañadidodosdirectoriosyunarchivonuevos,veamosquehadetectadogitdentrodenuestrorepositorio:
$gitstatus
#Onbranchmaster
#Untrackedfiles:
#(use"gitadd<file>..."toincludeinwhatwillbecommitted)
#
#index.html
nothingaddedtocommitbutuntrackedfilespresent(use"gitadd"totrack)
Apesardequehemosagregadodosdirectoriosnuevos,gitnodetectaesoscambios,esoesdebidoaquegitnollevacontroldelosdirectoriossinodearchivos,almomentoenqueagreguemosunarchivoencualquieradeesosdirectoriospodremosverquegitnosinformarádeello,creemosunarchivoentoncesdentrodeunodeesosdirectorios:
$touchjs/app.js
$gitstatus
#Onbranchmaster
#Untrackedfiles:
#(use"gitadd<file>..."toincludeinwhatwillbecommitted)
#
#index.html
#js/
nothingaddedtocommitbutuntrackedfilespresent(use"gitadd"totrack)
Todobien,ahoraagreguemoslosarchivosyhagamosuncommit:
$gitadd.
$gitcommit-am“Iniciodeproyecto”
[master19118ae]iniciodeproyecto
0fileschanged
createmode100644index.html
createmode100644js/app.js
$gitstatus
#Onbranchmaster
#Yourbranchisaheadof'origin/master'by1commit.
#
nothingtocommit(workingdirectoryclean)
Veamosahoralasalidadelcomandogitstatus,“Yourbranchisaheadof'origin/master'by1commit.”nosindicaquetenemoscambiosennuestrorepositoriolocalquenohansidoenviadosalrepositorioremoto.Podemoscomprobarsitenemosdiferenciasentrenuestrarepolocalylareporemotahaciendoundiffasí:
$gitdifforigin/mastermaster
diff--gita/index.htmlb/index.html
newfilemode100644
index0000000..e69de29
diff--gita/js/app.jsb/js/app.js
newfilemode100644
index0000000..e69de29
Enviemosnuestroscambiosagithub:
ENVIANDOCAMBIOSALREPOSITORIOREMOTO
$gitpushoriginmaster
Usernamefor'https://github.com':
Passwordfor'https://[email protected]':
Tohttps://github.com/carloscarcamo/practica-git.git
7369319..19118aemaster->master
$gitstatus
#Onbranchmaster
nothingtocommit(workingdirectoryclean)
Gitnospidenuestrousuarioycontraseñaparapoderenviarloscambios,luegopodemosverquegitstatusnosmuestraquetenemosnuestrorepositoriolocalyremotoactualizados.Podemosvertambiénengithubqueloscambioshansidoefectuadoscorrectamente:
hemoshechonuestroprimercommitaunrepositorioremoto.
Quepasasielrepositoriohacambiadocomopuedoobtenerloscambiosmásrecientes?,esoesfácil,simplementehacemosunpullalrepositoriodeorigen.Paraesteejemplovamosaeditarlosarchivoseninternetdesdegithub.
Seleccionemosunodelosarchivosparaeditar,lasimágenesacontinuaciónmuestranelprocesodeedicióndeunarchivodesdegithub:
Unavezseleccionadoelarchivoquequeremoseditar,veremosunabarradebotonescomoeldelaimagenanterior.
Hacemosclickalboton“edit”elcualnosmostraraunapantalladondepodemoseditarnuestrosarchivos.
Githubnosofreceunainterfazmuysencillaparaeditaryhacercommitenlinea.Elresultadofinallopodemosverenlasiguienteimagen:
OBTENIENDOCAMBIOSDELREPOSITORIOREMOTO
Haremoslomismoparaeditarelscripten“js/app.js”,elresultadosera:
Podemosverengithubloscommitquehemoshechohastaahora:
Parasabersinecesitamoshacerunpullalrepositorioremoto,vamosaejecutarelcomando:
$gitremoteupdate
Fetchingorigin
remote:Countingobjects:10,done.
remote:Compressingobjects:100%(6/6),done.
remote:Total7(delta1),reused0(delta0)
Unpackingobjects:100%(7/7),done.
Fromhttps://github.com/carloscarcamo/practica-git
19118ae..2a6236cmaster->origin/master
$gitstatus
#Onbranchmaster
#Yourbranchisbehind'origin/master'by2commits,andcanbefast-forwarded.
#
nothingtocommit(workingdirectoryclean)
Congitremoteupdateactualizamostodaslasreferenciasdelosobjetos,ramasydemásquetengamosdenuestrorepositorioremotoennuestrorepositoriolocal,luegoejecutamosgitstatusyestenosdicequenuestraramaactualestadesactualizadarespetoalaramaremota.Tambienpodriamoshaberusadootrocomandollamadofetchparaobtenerelmismoresultadoanterior:
$gitfetchorigin
gitremoteupdateygitfetchoriginnosdaranlosmismosresultados,peroalgunascosaspuedenvariarinternamente,paramásinformaciónvisitarladocumentaciónoficialdegitremoteygitfetch
Vamosaactualizarnuestrarepolocalconloscambioshechosengithub,estoloharemosconunpulldelasiguientemanera:
$gitpullorigin
Fromhttps://github.com/carloscarcamo/practica-git
*branchmaster->FETCH_HEAD
Updating19118ae..2a6236c
Fast-forward
index.html|14++++++++++++++
js/app.js|26++++++++++++++++++++++++++
2fileschanged,40insertions(+)
$gitstatus
#Onbranchmaster
nothingtocommit(workingdirectoryclean)
Hemosactualizadonuestrorepositoriolocalconloscambioshechosengithub,utilizamosgitpull«remote»endondeespecificamoslaramaremota.
Ejecutaloscomandossiguientesyverificasusalida,verasqueenefectotieneslosarchivosactualizados.
$catindex.html
$catjs/app.js
Elprocesodetrabajoconrepositoriosremotosessiempresimilaralquehemoshechoenestetutorialusandogithub.
¿yestoestodo?Puesno,estetutorialessolamenteunapequeñaintroducción,ahoraquedaacriteriodellectorindagarmásenladocumentación,practicar,ytrabajarcongitensusfuturosproyectos.
«Recuerdaquesideseasextenderestetutorial,nodudesenhacerlo,soloasegúratedecompartirloconlosdemás.»