90
Git – Fast Version Control System Ovidiu Dimulescu

Introduction to Git

Embed Size (px)

DESCRIPTION

An introduction to the world of Git from a historical and practical prospective. Common operations and setup scenarios are covered.

Citation preview

Page 1: Introduction to Git

     

Git  –  Fast  Version  Control  System      Ovidiu  Dimulescu  

Page 2: Introduction to Git

•  What  is  Git?  •  Origin  •  Design  Goals  and  Implementa9on  •  Why  Git?  •  How  is  Git  different?  •  Git  Internals  •  Installa9on  •  Commands  Overview  •  Collabora9on  Workflows  •  Git  as  SVN  client  •  Q&A  •  Live  Demo  

Page 3: Introduction to Git

       

What  is  Git?  

Page 4: Introduction to Git

     

Git   is   an   open   source,   distributed  version  control  system*    *Git   is   also   Bri9sh   English   slang   for   a   stupid   or   unpleasant  person.  According   to   Linus  Torvalds   "I'm  an  ego9s9cal  bastard,  and  I  name  all  my  projects  aSer  myself.  First  Linux,  now  git  “  

Page 5: Introduction to Git

       

Git  Origin  

Page 6: Introduction to Git

•  Feb  2002  Linus  Torvalds  decides  to  use  BitKeeper  for  source  control  

•  April  2005  BitKeeper  owner  withdraws  free  license  for  Linux  kernel  over  reverse  engineer  of  the  protocols  by  Andrew  Tridgell  (rsync,  samba  creator)  to  produce  a  minimal  BK  client  

•  April  2005  Linus  Torvalds  starts  hacking    and  produces  a  working  version  of  Git  in  two  weeks.  The  project  was  self-­‐hos9ng  in  a  week!  

•  April  2005  Ma`  Mackall  Linux  Kernel  developer  hacks  a  compe9ng  tool  called  Mercurial  with  the  same  goal  of  replacing  BitKeeper.  Linus  rejects  it  based  on  its  changset  log  similarity  with  BitKeeper.  

•  June  2005  Linux  Kernel  2.6.12  release  was  managed  by  Git  •  July  2005  maintenance  turned  over  to  Junio  Hamano  •  December  2005  Git  reaches  1.0  status  •  April  2006  1.3,  July  2006  1.4,  Feb  2007  1.5,  Aug  2008  1.6,  Feb  

2010  1.7,  Current  1.7.6  •  Lots  of  point  releases  in  between    

Page 7: Introduction to Git

       

Design  Goals  and  Implementa9on  

Page 8: Introduction to Git

•  Not  like  CSV  

Page 9: Introduction to Git

•  Not  like  CSV    

Linus  Torvalds:  Take  CVS  as  an  example  of  what  not  to  do;  if  in  doubt,  make  the  exact  opposite  decision.  Aka  WWCVSND  (What  would  CVS  never  do)    

For  the  first  10  years  of  kernel  maintenance,  we  literally  used  tar-­‐balls  and  patches,  which  is  a  much  superior  source  control  management  system  than  CVS  is,  but  I  did  end  up  using  CVS  for  7  years  at  a  commercial  company  and  I  hate  it  with  a  passion.  When  I  say  I  hate  CVS  with  a  passion,  I  have  to  also  say  that  if  there  are  any  SVN  (Subversion)  users  in  the  audience,  you  might  want  to  leave.  Because  my  hatred  of  CVS  has  meant  that  I  see  Subversion  as  being  the  most  pointless  project  ever  started.  The  slogan  of  Subversion  for  a  while  was  "CVS  done  right",  or  something  like  that,  and  if  you  start  with  that  kind  of  slogan,  there's  nowhere  you  can  go.  There  is  no  way  to  do  CVS  right.  

Page 10: Introduction to Git

•  Not  like  CSV  •  Not  like  BitKeeper  

Page 11: Introduction to Git

•  Not  like  CSV  •  Not  like  BitKeeper  •  Strong  support  for  non-­‐linear  development  

Page 12: Introduction to Git

•  Not  like  CSV  •  Not  like  BitKeeper  •  Strong  support  for  non-­‐linear  development    

Git  supports  rapid  branching  and  merging,  and  includes  specific  tools  for  visualizing  and  naviga9ng  a  non-­‐linear  development  history.  A  core  assump9on  in  Git  is  that  a  change  will  be  merged  more  oSen  than  it  is  wri`en,  as  it  is  passed  around  various  reviewers  

Page 13: Introduction to Git

•  Not  like  CSV  •  Not  like  BitKeeper  •  Strong  support  for  non-­‐linear  development  •  Distributed  development  

Page 14: Introduction to Git

•  Not  like  CSV  •  Not  like  BitKeeper  •  Strong  support  for  non-­‐linear  development  •  Distributed  development  

-­‐  work  offline  with  full  repository  history  -­‐  every  local  copy  is  a  backup  -­‐  everything  is  fast  -­‐  sync  directly  with  any  collaborator  

Page 15: Introduction to Git

•  Not  like  CSV  •  Not  like  BitKeeper  •  Strong  support  for  non-­‐linear  development  •  Distributed  development  •  Compa9bility  with  exis9ng  systems/protocols  

Page 16: Introduction to Git

•  Not  like  CSV  •  Not  like  BitKeeper  •  Strong  support  for  non-­‐linear  development  •  Distributed  development  •  Compa9bility  with  exis9ng  systems/protocols    

Repositories  can  be  published  via  HTTP/S,  FTP/S,  rsync,  or  a  Git  protocol  over  either  a  plain  socket  or  ssh.  Git  also  has  a  CVS  server  emula9on,  which  enables  the  use  of  exis9ng  CVS  clients  and  IDE  plugins  to  access  Git  repositories.  Subversion  and  svk  repositories  can  be  used  directly  with  git-­‐svn.  

Page 17: Introduction to Git

•  Not  like  CSV  •  Not  like  BitKeeper  •  Strong  support  for  non-­‐linear  development  •  Distributed  development  •  Compa9bility  with  exis9ng  systems/protocols  •  Efficient  handling  of  large  projects  

Page 18: Introduction to Git

•  Not  like  CSV  •  Not  like  BitKeeper  •  Strong  support  for  non-­‐linear  development  •  Distributed  development  •  Compa9bility  with  exis9ng  systems/protocols  •  Efficient  handling  of  large  projects  •  Very  strong  safeguards  against  corrup9on,  either  accidental  or  malicious  

Page 19: Introduction to Git

•  Not  like  CSV  •  Not  like  BitKeeper  •  Strong  support  for  non-­‐linear  development  •  Distributed  development  •  Compa9bility  with  exis9ng  systems/protocols  •  Efficient  handling  of  large  projects  •  Very  strong  safeguards  against  corrup9on,  either  accidental  or  malicious  

Git  repository  history  is  cryptographically  authen9cated  by  being  stored  in  such  a  way  that  the  name  of  a  par9cular  revision  (a  "commit"  in  Git  terms)  depends  upon  the  complete  development  history  leading  up  to  that  commit.  Once  it  is  published,  it  is  not  possible  to  change  the  old  versions  without  it  being  no9ced.    

Page 20: Introduction to Git

•  Not  like  CSV  •  Not  like  BitKeeper  •  Strong  support  for  non-­‐linear  development  •  Distributed  development  •  Compa9bility  with  exis9ng  systems/protocols  •  Efficient  handling  of  large  projects  •  Very  strong  safeguards  against  corrup9on,  either  accidental  or  malicious  

•  Toolkit-­‐based  design  

Page 21: Introduction to Git

       

Why  Git?  

Page 22: Introduction to Git

•  Rolls  off  the  tongue  well  •  Fast  •  Ton  of  good  documenta9on  freely  available  •  Facilitates  developer  experimenta9on  •  Marketable  skill  •  Cool  kids  are  doing  it:  Android,  PostgreSQL,  Linux  Kernel,  Perl,  jQuery,  Ruby  on  Rails,  Eclipse,  VLC,  Samba,  YUI,  Wine,  Gnome,  KDE,  QT,  X.org,  Debian,  etc.  

•  Available  on  major  code  hos9ng  services:  GitHub.com,  BitBucket.org,  Google  Code,  SourceForge,  RubyForge,  etc.  

 

Page 23: Introduction to Git

So,  how  fast  is  Git?  Let’s  see  some  pictures  *  

*  Comparison  as  of  2009  

Page 24: Introduction to Git
Page 25: Introduction to Git
Page 26: Introduction to Git
Page 27: Introduction to Git
Page 28: Introduction to Git
Page 29: Introduction to Git
Page 30: Introduction to Git

How  is  Git  different    

Delta  storage  SCMs      RCS  CVS  SVN  Perforce  Darcs  Mercurial  

 Snapshot  storage  SCMs    

Git  BitKeeper  Bazaar  

 

•  The  main  difference  is  its  SNAPSHOT  based  storage  rather  then  DELTA  based  

•  Another  difference  is  the  intermediate  step  between  local  edits  and  repository  commits  known  as  staging  area  or  index  

Page 31: Introduction to Git
Page 32: Introduction to Git
Page 33: Introduction to Git
Page 34: Introduction to Git
Page 35: Introduction to Git
Page 36: Introduction to Git
Page 37: Introduction to Git
Page 38: Introduction to Git
Page 39: Introduction to Git
Page 40: Introduction to Git
Page 41: Introduction to Git
Page 42: Introduction to Git
Page 43: Introduction to Git
Page 44: Introduction to Git
Page 45: Introduction to Git
Page 46: Introduction to Git

       

Git  Internals  

Page 47: Introduction to Git

•  At  its  core  Git  is  a  content-­‐addressable  file-­‐system  that  has  a  no9on  of  versions  

•  Versions  are  implemented  as  snapshots  of  an  en9re  tree  •  Git  has  two  data  structures  

-­‐   an  immutable,  append-­‐only  object  database  -­‐   a  mutable  index  that  caches  informa9on  about  the  working  directory  and  the  next  revision  to  be  commi`ed  

•  The  index  is  the  middle  man  between  the  object  database  and  the  working  directory.  Referred  to  as  staging  area.  

•  The  object  database  has  four  types  of  objects:  -­‐  BLOB  -­‐  TREE  -­‐  COMMIT  -­‐  TAG  

•  Each  file  revision  is  stored  as  a  unique  BLOB  object.  The  object  iden9fier  is  an  SHA-­‐1  hash  of  its  content.  

 

Page 48: Introduction to Git

•  A  BLOB   object   is   the   content  of   a  file.   Blob  objects  have  no  filename,  9mestamps,  or  other  metadata.  

•  A  TREE  object  is  the  equivalent  of  a  directory.  It  contains  a  list  of  filenames,  each  with  some  type  bits  and  the  name  of  a  blob  or   tree   object   that   is   that   file,   symbolic   link,   or   directory's  contents.  This  object  describes  a  snapshot  of  the  source  tree.  

•  A  COMMIT  object  links  tree  objects  together  into  a  history.  It  contains   the   name   of   a   tree   object   (of   the   top-­‐level   source  directory),  a  9mestamp,  a  log  message,  and  the  names  of  zero  or  more  parent  commit  objects.  

•  A  TAG  object  is  a  container  that  contains  reference  to  another  object  and  can  hold  addi9onal  meta-­‐data  related  to  another  object.  Most  commonly,  it  is  used  to  store  a  digital  signature  of  a  commit  object  corresponding  to  a  par9cular  release  of  the  data  being  tracked  by  Git.  Tags  do  not  move.  Two  tags  types  exist:  Lightweight:   is   not   an   object   just   a   reference   poin9ng   to   a   tag   or  commit  object  Regular:  a  container  object  can  contain  a  message  similar  to  a  commit  and  op9onally  a  (PGP)  signature.  In  the  la`er  case  it  is  called  “signed  tag  object”  

 

Page 49: Introduction to Git

Some  Git  terminology  BRANCH   a   reference   poin9ng   to   a   commit   object.   It   auto-­‐advance   as  commits  are  performed  on  the  branch  head  -­‐    A  named  reference  to  the  commit  at  the  9p  of  a  branch  HEAD  -­‐  A  reference  to  head  of  the  current  (or  checked  out)  branch  MASTER  -­‐  The  default  ac9ve  branch  created  when  ini9alizing  a  repository  REMOTE  -­‐  A  reference  (aka  alias)  to  a  remote  repository  ORIGIN  -­‐  Default  upstream  repository.  It  can  have  any  name  REPOSITORY  -­‐  A  collec9on  of  refs  together  with  an  object  database  containing  all  objects  which  are  reachable  from  the  refs  BARE  REPOSITORY  –  A  directory  that  does  not  have  locally  checked-­‐out  copy.  Usually  public  repositories.  Common  names  are  myproject.git  SHALLOW  REPOSITORY  -­‐  A  shallow  repository  has  an  incomplete  history  SYMREF   -­‐   Symbolic   reference   to   another   reference   rather   then   SHA-­‐1.  HEAD  is  a  prime  example  of  that.  TREE-­‐ISH  -­‐  A  ref  poin9ng  to  either  a  commit  object,  a  tree  object,  or  a  tag  WORKING  TREE  -­‐  The  tree  of  actual  checked  out  files.  The  working  tree  is  normally  equal  to  the  HEAD  plus  any  local  changes  that  you  have  made  but  not  yet  commi`ed.  

 

Page 50: Introduction to Git

A  branch  points  to  a  commit  A  tag  points  to  a  commit  A  Commit  points  to  a  Tree  A  Commit  can  have  mul9ple  Parents  A  Tree  can  contain  mul9ple  Trees  A  Tree  can  contain  mul9ple  Blobs  

Object  Rela9onships  

Page 51: Introduction to Git

Every  Git  working  directory  is  a  full-­‐fledged  repository  with  complete  history  and  full  revision  tracking  capabili9es,  independent  of  network  access  or  a  central  server.    Most  entries  are  text  based  and  human  readable  except  for  packed  objects  which  are  binaries.    Aside  for  a  few  select  entries  like    ‘hooks’  ,  ‘config’  ,  ‘descrip9on’  you  do    not  have  a  need  to  edit  the  files  directly.  Git  has  aliases  for  manipula9ng  the  configura9on  for  instance.  

Page 52: Introduction to Git

Checkout  (re)ini9alizes  your  working  directory  (as  a  whole  or  individual  files)  and  staging  area  from  the  local  repository.  All  three  areas  are  in  sync    Make  changes  in  the  working  directory.  At  this  point  is  out  of  sync  with  index  and  repository  Stage  adds  changes  (modified  files,  newly  added  files,  removed  files).  At  this  point  the  working  directory  and  the  index  are  in  sync  for  the  changed  files  that  were  staged    Commit  brings  the  repository,  the  index  and  the  working  directory  in  sync.    

Working  Directory    –  Where  you  make  edits    Staging  Area  or  Index    -­‐  Where  you  stage  what  changes  you  plan  to  commit  next  -­‐  Has  no  actual  content  just  references.  Temporary  objects  are  inserted  into  repository.  They  will  be  dangling  un9l  a  commit  links  them  or  discarded  on  next  repository  clean  up    Repository  -­‐  Where  commits  or  permanent  copies  are  stored      

Page 53: Introduction to Git
Page 54: Introduction to Git

commit

tree

blob

tree

tree blob

blob

branch

commit

tree

blob

tree

tree

commit

tree

blob

tree

tree blob

blob

branchtag

Snapshot  views  

ASer  a  commit  and  tag  

ASer  one  more  commit  

Page 55: Introduction to Git

commit

tag

tree

blob

tree

tree

commit

tree

blob

tree

tree blob

commit

tree

blob

blob

branch

Snapshot  views  

Page 56: Introduction to Git

       

Installa9on  

Page 57: Introduction to Git

1.  From  git-­‐scm.com  choose  the  link  that  matches  your  plazorm  (Windows,  OSX,  Linux)  and  follow  the  instruc9ons  

2.  On  Linux  rather  the  compiling  from  source  you  can  use  your  distro  package  manager  to  install  Git  

3.  On  Mac  you  can  use  the  ports  systems  (Homebrew,  MacPorts,  etc.)  if  you  have  trouble  with  the  pre-­‐packaged  installer.      

4.  Install  GUI  clients  if  CLI  is  not  your  cup  of  tea    

Mac:  Tower,  GitX,  GitHub  4  Mac,  Gi{,  SmartGit  Windows:    TortoiseGit,  SmartGit,  Git  Extensions  Linux:  git-­‐colo,  giggle,  gitg,  SmartGit  Cross-­‐plazorm:  git  gui,  gitk,  9g,  SmartGit  

 5.  Install  IDE  clients  if  desired    

Eclipse  EGit  IntelliJ  –  Support  out  of  the  box  since  9.0  Xcode  –  Basic  support  included  na9vely  since  4.0  

   

Page 58: Introduction to Git

Setup  and  Configura9on  -­‐  Basics  Git  uses  cascading  loca9ons  to  determine  effec9ve  config  similar  to  other  *nix  tools    

 /etc/gitconfig  System  Wide    ~/.gitconfig  Per  User    proj/.git/config  Per  project  

 You  can  manipulate  entries  for  each  level  by  issuing  git  config  and  passing  -­‐-­‐system,  -­‐-­‐global  and  no  argument  respec9vely.  To  see  current  se{ngs  issue      

$  git  config  -­‐-­‐list    You  need  to  set  your  iden9ty  locally  as  Git  has  no  central  server    

$  git  config  -­‐-­‐global  user.name  ”John  Smith"    $  git  config  -­‐-­‐global  user.email  [email protected]  

 You’d  want  to  ignore  certain  file  (*.class,  *.swp,  *~,  target,  DS_STORE,  etc.)    

git  config  -­‐-­‐global  core.excludesfile  ~/.gi9gnore  Where  .gi9gnore  accepts  various  pa`erns  .DS_Store  *~  *.swp  tmp/**/*  

Page 59: Introduction to Git

Setup  and  Configura9on  -­‐  Convenience  Colored  Output    

$  git  config  -­‐-­‐global  color.ui  true    Custom  Editor    

$  git  config  –global  core.editor  emacs    Custom  Diff  /  Merge  Tools  

 $  git  config  -­‐-­‐global  diff.tool  beyondcompare  $  git  config  -­‐-­‐global  di�ool.prompt  true  

 Aliases    

$  git  config  -­‐-­‐global  alias.compactlog  'log  -­‐-­‐pre`y="%h  %s"’  $  git  config  -­‐-­‐global  alias.co  checkout  $  git  config  -­‐-­‐global  alias.ci  commit  

 GeQng  help  

 $  git  help  config  $  git  config  –help  $  man  git-­‐config  

Page 60: Introduction to Git

Setup  and  Configura9on  –  SysAdmin  Version  Git  has  no  built  in  access  mechanism?    Yes.  This  allows  you  to:  

•  Be  up  and  running  quickly    •  Implement  access  control  of  your  choice  •  Not  worry  about  yet  another  system  to  secure  

 What  opSons  are  out  there?    Gitolite      -­‐  Allows  permissions  not  just  by  repository,  but  also  by  branch  or  tag  names  within  each  

repository.  That  is,  you  can  specify  that  certain  people  (or  groups  of  people)  can  only  push  certain  “refs”  (branches  or  tags)  but  not  others.  

-­‐  Works  over  SSH.  Requires  only  one  users  on  the  host    Basic  control  via  file  share  permissions  and  ACLs    -­‐  Use  your  normal  Unix  or  Windows  file  access.  Suitable  for  internal  access  only    Hosted  soluSon  -­‐    GitHub,  BitBucket,  etc.    

Page 61: Introduction to Git

Setup  and  Configura9on  –  Cool  Tricks  Shell  Tab  CompleSon    Save    h`ps://raw.github.com/git/git/master/contrib/comple9on/git-­‐comple9on.bash  Source  it  in  from  your  shell  profile    $  git  log  TAB  HEAD                        master                    origin/HEAD          origin/master      $  git  TAB  

Shell  Prompt  Context  SensiSve    $  export  PS1='\u  \W$(__git_ps1  "  (%s)")\$  '  odimulescu  jaxjug-­‐1011  (master)$  

Page 62: Introduction to Git

       

Commands  Overview  

Page 63: Introduction to Git

Crea9ng  Repositories  Staging  changes  Stashing  away  changes  Commi{ng  changes  I  know  what  you  did  last  ...  It’s  all  in  the  logs  Undoing  changes  Let’s  play  tag  Branch  out  Calling  home  

Page 64: Introduction to Git

Crea9ng  repositories  Create  a  repository  from  scratch    $  git  init  [DIRECTORY]    Handy  op9ons  in  some  cases    -­‐-­‐shared=(false|true|umask|group|all|0xxx)  –  useful  to  share  the  repo  over  NFS  or  Samba  -­‐-­‐separate-­‐git-­‐dir  <git  dir>  –  used  to  store  the  .git  folder  outside  of  your  project  area.  GIT_DIR  

environment  needs  to  be  set  for  further  opera9ons  as  default  behavior  is  to  look  up  the  current  dir  un9l  a  .git  folder  is  found  

 Clone  an  exisSng  repository    git  clone  REPO_URL  LOCAL_DIR  $  git  clone  h`ps://github.com/jquery/jquery.git  jquery-­‐local    You  can  use  the  –separate-­‐git-­‐dir  as  above    Create  bare  repository    git  init  -­‐-­‐bare  [LOCAL_DIR]  git  clone  -­‐-­‐bare  REPO_URL  [LOCAL_DIR]  $  git  clone  –bare  my-­‐local-­‐project  /Volumes/passport/my-­‐project-­‐backup.git    Creates  a  repository  without  a  checked-­‐out  working  directory.  This  is  typically  used  for  public  or  shared  repository  or  to  backup  to  an  external  drive.  LOCAL_DIR  are  typically  named  with  a  .git  extension  

Page 65: Introduction to Git

Staging  changes  Add  changes  to  the  staging  area    git  add  <file>  git  add  <directory>  git  add  –all  git  add  -­‐-­‐patch    git  add  <file>                        will  add  the  file  to  the  staging  area.    git  add  <directory>  will  add  the  en9re  <directory>  to  the  staging  area  git  add  -­‐-­‐all                              will  the  en9re  current  directory  to  the  staging  area.  Equivalent  to  git  add  .  git  add  -­‐-­‐patch                  allows  selec9ng  individual  sec9ons  (aka  hunks)  of  a  file  rather  as  whole    None  of  the  changes  are  visible  in  the  repository  un9l  commit  is  invoked  Empty  directories  are  not  supported.  As  an  workaround  you  can  add  a  .gi9gnore  (any  other  name  will  work)  to  force  the  folders  structure  to  be  added    Viewing  status  of  the  working  directory    $  git  status  #  On  branch  master  #  Changes  to  be  commi`ed:  #      (use  "git  reset  HEAD  <file>..."  to  unstage)  #  #  modified:      README.1st      

Page 66: Introduction to Git

Staging  changes  Removing  changes  from  the  staging  area  and  working  directory    git  rm  <file>  git  rm  -­‐r  <directory>  git  rm  -­‐f  <file>  or  git  rm  -­‐r  -­‐f  <directory>    git  rm  <file>                                    will  remove  the  file  from  the  staging  area  and  working  directory  git  rm  -­‐r  <directory>      will  removed  the  directory  recursively  from  staging  and  working  directory  git  rm  –f  <file>                          force  removal  of  the  file  even  it  has  modifica9ons  in  the  working  directory    Removing  changes  from  the  staging  area  only    git  rm  -­‐-­‐cached  <file>          will  remove  the  file  from  the  staging  area  only  git  rm  -­‐-­‐cached  -­‐r  <dir>    will  removed  the  directory  recursively  from  staging  area  only    This  is  useful  when  you  realize  you  added  some  unwanted  files  (*.class,  build  folder  etc.  that  you  haven’t  ignored  it).    Moving  files  around    Git  does  not  explicitly  track  file  movement.  This  is  primarily  due  to  being  content  addressed  (ie  does  not  care  about  loca9on)  but  has  built-­‐in  heuris9c  to  detect  movement.    git  mv  file_from  file_to  this  is  really  a  convenience  to    mv  from_file  file_to  ;  git  rm  old_path;  git  add  new_path    This  poses  an  issue  with  all  9me  history  for  a  file.  Use  git  log  -­‐-­‐follow  

Page 67: Introduction to Git

Stashing  away  changes  Dealing  with  interrupSons    Scenario:    You  are  happily  working  on  your  task  when  your  boss  asks  you  to  implement    a  hozix      

Stash  away  precious  work  $  git  stash  Edit  /  test  /  commit    the  hot  fix  restore  previous  work  $  git  stash  pop  Con;nue  hacking  

 Granularity  is  near    Scenario:  You  like  to  predict  the  future  by  using  smaller  commits  you  can  test  and  later  isolate.      

Hack,  hack,  hack  ...  Stage  the  files  or  file  changes  you  want  as  first  commit  $  git  add  file1  file2  etc                                $  git  add  -­‐-­‐patch  file1  Save  all  other  changes  to  the  stash  $  git  stash  save  -­‐-­‐keep-­‐index          Edit/build/test/commit  current  changeset  Prepare  to  work  on  all  other  changes  $  git  stash  pop                                                            Repeat  above  five  steps  un;l  one  commit  remains  ...  Edit/build/test/commit  last  changeset  

Page 68: Introduction to Git

Stashing  away  changes  Common  stash  operaSons    git  stash  [<message>]]  Save  your  local  modifica9ons  to  a  new  stash,  and  run  git  reset  -­‐-­‐hard  to  revert  them  git  stash  [-­‐-­‐keep-­‐index]  All  changes  already  added  to  the  index  are  leS  intact.  git  stash  –patch  You  can  interac9vely  select  hunks  from  the  diff  between  HEAD  and  the  working  tree  to  be  stashed.  Implies  -­‐-­‐keep-­‐index.    git  stash  show  [<stash>]  Show  the  changes  recorded  in  the  stash  as  a  diff  between  the  stashed  state  and  its  original  parent  git  stash  list  -­‐  List  the  stashes  that  you  currently  have.  git  stash  pop  [<stash>]  Remove  a  single  stashed  state  from  the  stash  list  and  apply  it  on  top  of  the  current  working  tree  state.  The  working  directory  must  match  the  index.  git  stash  apply  [<stash>]  Like  pop,  but  do  not  remove  the  state  from  the  stash  list.  git  stash  drop  [<stash>]  Remove  a  single  stashed  state  from  the  stash  list.  git  stash  clear  Remove  all  the  stashed  states.  git  stash  branch  <branchname>  [<stash>]  Creates  and  checks  out  a  new  branch  named  <branchname>  star9ng  from  the  commit  at  which  the  <stash>  was  originally  created,  applies  the  changes  recorded  in  <stash>  to  the  new  working  tree  and  index.  This  is  useful  if  the  branch  on  which  you  ran  git  stash  save  has  changed  enough  that  git  stash  apply  fails  due  to  conflicts.  Since  the  stash  is  applied  on  top  of  the  commit  that  was  HEAD  at  the  9me  git  stash  was  run,  it  restores  the  originally  stashed  state  with  no  conflicts.  

Page 69: Introduction to Git

Commi{ng  changes    Basic    git  commit  -­‐a  -­‐m  <msg>    -­‐a  -­‐  Tell  the  command  to  automa9cally  stage  files  that  have  been  modified  and  deleted,  but  new  files  you  have  not  told  git  about  are  not  affected  -­‐m  -­‐  Use  the  given  <msg>  as  the  commit  message.    When  you  are  not  the  author  git  commit  -­‐-­‐author=<author>    When  you  are  not  a  good  speller  or  have  short  aXenSon  span  git  commit  –amend    This  allows  you  to  re-­‐edit  the  last  commit  message  and  replaces  it  with  the  updated  content  or  To  add  other  files  to  the  commit  that  you  forgot  ini9ally  …    I’m  not  feeling  lucky.  Don’t  worry  it’s  local  you  can  rollback  as  needed  git  commit  -­‐-­‐dry-­‐run  

Page 70: Introduction to Git

I  know  what  you  did  last  ...  It’s  all  in  the  logs    

git  log    Out  of  the  box  will  list  all  the  commits  from  newest  to  oldest.  It  has  a  built  in  pager  like  more.    commit  ce77789bf91c4dc6fa659264699221e0f24e3894  Author:  Ovi  Dimulescu  <[email protected]>  Date:      Wed  Oct  12  10:27:24  2011  -­‐0400            JIRA-­‐1234  added  logging  to  captcha  processing    Narrowing  down  by  author    

git  log  -­‐-­‐author  Ovi      Narrowing  down  by  commiter    

git  log  -­‐-­‐commiter=<pa`ern>    The  author  is  the  person  who  originally  wrote  the  work,  whereas  the  commiDer  is  the  person  who  last  applied  the  work.    Narrowing  down  by  commit  message    

git  log  -­‐-­‐grep=<pa`ern>  

Page 71: Introduction to Git

I  know  what  you  did  last  ...  It’s  all  in  the  logs    

Narrowing  down  by  mulSple  fields    

git  log  -­‐-­‐all-­‐match  All  of  -­‐-­‐grep,  -­‐-­‐author  and  -­‐-­‐commi`er  have  to  match  rather  than  a  least  one    Narrowing  down  by  date    

git  log  [-­‐-­‐since=<date>]  [-­‐-­‐un9l=<date>]    Follow  a  file  that’s  been  renamed    

git  log  -­‐-­‐follow  <file>    Determine  when  a  file  has  been  deleted    

git  log  -­‐-­‐remove-­‐empty    Controlling  the  output  format    

git  log  –format=<format>  Pre`y-­‐print  the  contents  of  the  commit  logs  in  a  given  format,  where  <format>  can  be  one  of  oneline,  short,  medium,  full,  fuller,  email,  raw  and  format:<string>.    When  omi`ed,  the  format  defaults  to  medium.  

Page 72: Introduction to Git

Undoing  changes    Unstaging  a  file    

   

Page 73: Introduction to Git

Undoing  changes    Unstaging  a  file    

git  reset  HEAD  <file>    Rolling  back  a  modified  file    

git  checkout  <file>    Altering  last  local  commit    

git  commit  -­‐-­‐amend    ReverSng  faulty  commit  (already  pushed  to  reference  repository)    

git  revert  [-­‐n]  <commit>    git  revert  HEAD~3  Revert  the  changes  specified  by  the  fourth  last  commit  in  HEAD  and  create  a  new  commit  with  the  reverted  changes.    git  revert  -­‐n  master~5..master~2  Revert  the  changes  done  by  commits  from  the  fiSh  last  commit  in  master  (included)  to  the  third  last  commit  in  master  (included),  but  do  not  create  any  commit  with  the  reverted  changes.  The  revert  only  modifies  the  working  tree  and  the  index.      

Page 74: Introduction to Git

Let’s  play  tag    I  tagged  you  git  tag  <tagname>  [<commit>  |  <object>]    Creates  a  shorthand  name  for  the  given  a  commit  or  object.  If  only  <tagname>  was  provided  the  9p  of  the  current  branch  is  tagged.  Mostly  you’d  tag  commits  but  you  could  tag  a  special  file  so  you  can  access  it  directly  regardless  of  its  path.  By  default  a  lightweight  tag  is  created  that  is  only  a  references  is  stored  in  .git/refs/tags  and  no  object  is  created  in  the  database.  You  can  see  this  as  an  anonymous  tag  with  regard  to  author.    I  tagged  you  and  want  the  world  to  know  git  tag  –a  <tagname>  [<commit>  |  <object>]    Creates  an  annotated  tag  that  has  a  corresponding  object  with  9mestamp,  message,  author,  etc.    I  changed  my  mind,  untag  git  tag  –d  <tagname>    Fat  fingers,  now  what  git  tag  –f  <tagname>    If  you  haven’t  pushed  the  tag  to  a  shared  repository  no  problem.  Otherwise  users  that  already  updated  will  see  that  copy  (ie  git  does  not  change  them  without  you  knowing).    

Page 75: Introduction to Git

Let’s  play  tag    I  tagged  you  and  want  the  world  to  know  it  was  really  me  git  tag  [-­‐s  |  -­‐u  <key-­‐id>]    Makes  a  GPG-­‐signed  tag  either  using  default  e-­‐mail  address  key  (-­‐s)  or  the  given  key  (-­‐u)    I’m  paranoid  and  want  to  verify  a  tag  git  tag  -­‐v  <tagname>    Verifies  the  GPG  signature    What  are  all  my  tags  git  tag  -­‐l  [<pa`ern>]    Without  any  arguments  it  lists  all  the  tags.  The  pa`ern  is  a  shell  wildcard.  Mul9ple  pa`erns  may  be  given;  if  any  of  them  matches,  the  tag  is  shown.    What  is  the  most  recent  tag  before  or  a]er  a  commit  git  describe  [-­‐-­‐all]  [-­‐-­‐tags]  [-­‐-­‐contains]  <commit>    By  default  it  looks  up  what  was  the  last  tag  before  the  commit  and  just  annotated  tags.  Use  –contains  to  find  a  tag  aSer  a  commit.  Use  –tags  to  enable  lightweight  tags.  When  –all  it’s  used  will  search  across  all  references  (including  local  branches  and  remote  branches)  

Page 76: Introduction to Git

Branch  out  -­‐  Context  switching  is  cheap  and  easy    Create  a  new  branch  git  branch  <branchname>  [<start-­‐point>]    

This  will  create  a  new  branch  named  <branchname>  using  <start-­‐point>  as  reference.  If  not  passed  in  will  use  the  current  HEAD.    DeleSng  an  exisSng  branch  git  branch  –d  <branchname>    Deletes  the  branch  as  long  as  it’s  fully  merged  with  it’s  upstream.  Use  –D  if  you  really  want  to  drop  it    Renaming  an  exisSng  branch  git  branch  -­‐m  <old_name>  <new_name>    If  the  new_name  exists  you  can  use  –M  to  force  the  opera9on.  That  in  turn  will  drop  the  new_name  reference    Switching  to  a  branch  git  checkout  <branchname>  -­‐  this  switches  transparently  you  working  directly  __CONTENT__    CreaSng  and  switching  to  a  branch  in  one  go  git  checkout  –b  <branchname>  [<start-­‐point>]    

Page 77: Introduction to Git

Calling  home    

Where  is  home?  

git  remote  show  origin      Show  me  more  info  about  home  git  remote  show  orgin  *  remote  origin      Fetch  URL:  /Volumes/NO  NAME/Git  Repos/jaxjug1011.git      Push    URL:  /Volumes/NO  NAME/Git  Repos/jaxjug1011.git      HEAD  branch:  master      Remote  branches:          master  tracked  Local  branch  configured  for  'git  pull':          master  merges  with  remote  master      Local  refs  configured  for  'git  push':          master  pushes  to  master  (up  to  date)    GeQng  stuff  from  home  git  fetch  Fetches  the  content  but  does  not  update  working  directory  git  pull        Fetches  the  content  and  merges  them  into  working  directory  

Page 78: Introduction to Git

Calling  home    

Give  back  the  easy  way  

git  push  [<repository>  [<refspec>...]]    By  default  git  sends  the  local  changes  on  the  current  branch  to  the  reference  (upstream)  repository.  You  can  control  to  which  <repository>  and  what  local  references  (ie  other  then  current  branch)  you  want  to  push.    Not  feeling  lucky?  git  push  -­‐-­‐dry-­‐run    But  I  am  selecSve  git  push  [-­‐-­‐delete]  [-­‐-­‐tags]  [-­‐-­‐all]  [-­‐-­‐mirror]    -­‐-­‐all                Instead  of  naming  each  ref  to  push,  specifies  that  all  refs  under  refs/heads/  be  pushed  -­‐-­‐delete  All  listed  refs  are  deleted  from  the  remote  repository.  This  is  the  same  as  prefixing  all  refs  with  a  colon.  -­‐-­‐tags          All  refs  under  refs/tags  are  pushed,  in  addi9on  to  refspecs  explicitly  listed  on  the  command  line  -­‐-­‐mirror  Instead  of  naming  each  ref  to  push,  specifies  that  all  refs  under  refs/  (which  includes  but  is  not  limited  to  refs/heads/,  refs/remotes/,  and  refs/tags/)  be  mirrored  to  the  remote  repository.  Newly  created  local  refs  will  be  pushed  to  the  remote  end,  locally  updated  refs  will  be  force  updated  on  the  remote  end,  and  deleted  refs  will  be  removed  from  the  remote  end.  This  is  the  default  if  the  configura9on  op9on  remote.<remote>.mirror  is  set.  

Page 79: Introduction to Git

Calling  home    

Most  of  Smes  I’m  doing  it  a  certain  way    git  config  push.default  current    ‘current’  in  this  setup  means  that  by  default  you  will  only  push  the  current  branch  when  you  do  git  push    nothing  :        Do  not  push  anything  matching  :  Push  all  matching  branches  (default)  tracking  :      Push  the  current  branch  to  whatever  it  is  tracking  current  :        Push  the  current  branch    If  you  have  many  repositories  and  want  the  same  for  all  then  you  can  use  git  config  -­‐-­‐global  push.default  current    Backups  maXers!    Full  backup  aSer  you  started  working  locally  git  clone  –bare  my-­‐local-­‐project  /Volumes/passport/my-­‐project-­‐backup.git    A  be`er  way  would  be  to  create  a  bare  remotely  and  clone  it  locally.  Then  you  can  do  incremental  backups  by  pushing  changes  regularly  git  push    

Page 80: Introduction to Git

       

Collabora9on  Workflows  

Page 81: Introduction to Git

The  workflows  are  generally  driven  by  who  has  commits  rights  to  the  reference  repository.  The  majority  of  projects  fall  in  one  of  the  following  or  combina9on  of:  

•  All  developers  are  direct  commi`ers  •  A  project  maintainer  is  the  sole  commi`er  

Page 82: Introduction to Git

All  developers  are  direct  commi`ers  

•  Everyone  has  push  access  •  Uses  a  familiar  paradigm  •  Works  well  with  a  small  team,  minimal  overhead  and  bo`lenecks  •  First   developer   to   commit   a   change   to   the   same   file   wins.   Second  

developer   has   to  merge.   Git   will   no9fies   the   second   developer   and  will  refuse  a  push  un9l  conflicts  are  marked  as  resolved  

Page 83: Introduction to Git

A  project  maintainer  is  the  sole  commi`er  

1.  Only  the  project  maintainer  can  push  to  the  reference  repository  2.  Contributors  clone  (fork)  that  repository  and  makes  changes  3.  Contributor  pushes  those  changes  to  their  own  public  copy  4.  Contributor  asks  the  projects  maintainer  to  review  and  pull  changes  5.  The  project  maintainer  adds  the  contributor’s  repo  as  a  remote  and  

merges  locally  6.  Then  the  maintainer  pushes  merged  changes  to  the  reference  repository    Common  in  public  projects.  GitHub  uses  this  model.  Advantages:  •  No  commi`er  setup  needed  for  the  reference  repository  •  Each  party  can  work  independently  

Page 84: Introduction to Git

       

Git  as  an  SVN  client  

Page 85: Introduction to Git

Git  SVN  Client    Basic  flow  

1.  Clone  the  SVN  repository  locally  into  a  Git  2.  Configure  ignored  files  from  SVN  so  Git  honors  them  3.  Work  normally  locally  as  you  would  with  Git  4.  Synchronize  with  SVN  server  as  needed  

 

Caveats  •  Stay  within  guidelines.  Prefer  safety  over  fancy  •  Use  rebase  over  merge  to  keep  history  linear  

Page 86: Introduction to Git

Create  a  Git  clone  of  the  SVN  repository    $  git  svn  clone  –s  SVN_REPO_URL  LOCAL_DIR    -­‐s  stands  for  -­‐-­‐stdlayout  which  presumes  the  svn  recommended  layout  for  tags,  trunk,  and  branches    $  git  svn  clone  -­‐T  trunk  -­‐b  branches  -­‐t  tags  -­‐r  START_REVISION:HEAD  SVN_REPO_URL  LOCAL_DIR    -­‐T  how  trunk  is  called  -­‐b  how  branches  are  called  -­‐t  how  tags  are  called  -­‐r  is  for  the  revision  to  start  taking  history  from    Ignore  SVN  ignored  files    $  git  svn  show-­‐ignore  >  .git/info/exclude  $  git  svn  show-­‐ignore  >  .gi9gnore    Pull  changes  from  SVN  Repo    $  git  svn  rebase    Push  changes  to  SVN  Repo    $  git  svn  dcommit  -­‐-­‐dry-­‐run  (ensures  it  ends  up  on  the  desired  branch)  $  git  svn  dcommit  

Page 87: Introduction to Git

References:    Steve  Chacon  –  h`ps://github.com/schacon/git-­‐presenta9ons    Steve  Chacon  –  Pro  Git  Book    Travis  Swicegood  -­‐  Pragma9c  Guide  to  Git  

Page 88: Introduction to Git

Resources:    h`p://git-­‐scm.com/documenta9on  h`p://gitready.com  h`p://progit.org/book/  h`p://marklodato.github.com/visual-­‐git-­‐guide/index-­‐en.html  h`p://gitref.org/  h`ps://wincent.com/tags/git  

Page 89: Introduction to Git

       

Ques9ons  &  Answers  

Page 90: Introduction to Git

       

Live  Demo