HOWTOlabs git
tips and best practices

git

git is a 'peer-to-peer' style source code management application developed originally by Linus (creator of Linux) to better manage Linux kernel development.  It has been enhanced and ported to various computer operating systems including Linux, OS X, and Microsoft Windows.

It differs from traditional source code management systems in that is eschews the client/server model, instead allowing multiple peer code repositories to exists and interact with each other organically as needed.  This provides increased flexibility, but also increases the conceptual complexity of managing code that now can evolve in many repositories simultaneously.

Increasingly folks are hosting primary code repository on git compatible services like GitHub.com.  Such sites offering free and paid hosting plans, and offer additional software development tools and services. 

 

Elsewhere [edit]

Getting git: Linux RedHat/Centos

$ cd ~

# yum list \*git\*

  git.x86_64

# yum install git

  Downloading Packages:
  (1/3): git-1.7.1-2.el6_0.1.x86_64.rpm
  (2/3): perl-Error-0.17015-4.el6.noarch.rpm
  (3/3): perl-Git-1.7.1-2.el6_0.1.noarch.rpm                              |  

# exit

$ cd ~/test-git/test 

Getting git: Apple OS X

Elsewhere [edit]

More recently, OS X comes with git already installed.  However, as far back as OS X 10.4, may need to use an installer.

Often terminal path does not include location of git commands.  As root, it doesn't hurt to add git path as default for standard logins.

$ cat /etc/rc.common | grep PATH

  PATH=/bin:/sbin:/.../CoreServices:/usr/local/git/bin; export PATH 

If OS X needs to accept remote git requests (i.e. server mode), each user account making requests may need path settings tweaked to include git commands.  This needs to be done only on the server-side.

$ cd ~

$ cat .bashrc

  export PATH=$PATH:/usr/local/git/bin 

Getting git: Microsoft Windows

git-scm.com: download/win

Using git: managing local files

$ cd /public/test-git

$ cd test

$ git status -s

  fatal: Not a git repository (or any of the parent directories): .git

$ vi hello.txt

$ git init

  Initialized empty Git repository in .../test-git/test/.git/

$ git status -s

  ?? hello.txt

$ git add hello.txt 

$ git status -s

  A_ hello.txt

$ git commit

  1 files changed, 1 insertions(+), 0 deletions(-)
  create mode 100644 hello.txt

$ git status -s 

Using git: cloning files

$ cd /public/test-git$ cd ~/test-git

$ git clone /public/test-git/test

  Cloning into test...
  done.

$ cd test

$ git status -s 

Using git: undoing changes

$ vi hello.txt

$ git add

[ perform a bogus edit ]

$ git status -s

  _M hello.txt

$ git reset HEAD -- hello.txt

$ git status -s

$ rm hello.txt

$ git status -s 

  _D hello.txt

$ git checkout -- hello.txt

$ git status -s 

Remote Clone

Cloning from a remote location will automatically add remote alias.  Prepend username@ to hostname if remote is different.

$ git clone test.zaptech.org:/public/test-git/basic

  Cloning into basic...
  username@git.mydomain.com's password: 
  Receiving objects: 100% (3/3), done.

$ git remote -v

  origin git.mydomain.com:/public/test-git/basic (fetch)
  origin git.mydomain.com:/public/test-git/basic (push)

[ create a new file ]

$ git add

$ git commit

$ git diff origin --shortstat

  1 files changed, 1 insertions(+), 0 deletions(-) 

Remote Branches

$ git branch

  [ show branches and which one is current ]

$ git branch --track exp origin

  Branch exp set up to track remote branch master from origin.

$ get checkout exp

  [ switch to exp branch ]

$ git branch

  [ show branches and which one is current ] 

Client/Server Setup

Clone, prepare - for server only

$ git clone --bare b2 b0 

Alternative, create an empty repository ...

$ git init --bare foobar 

Alternative 2, create an empty shared repository ...

$ git init --bare --shared foobar 
Clone, checkout, commit, push - for client
$ git clone test.zaptech.org:/public/test-git/basic

  [ change some files ]

$ git add

$ git commit -m "comment"  

$ # if remote repository is empty
$ git push origin master

  * [new branch]      master -> master

$ # otherwise if remote repository already has files
$ git push 
Elsewhere

Remote Merging

$ git fetch origin

  From test.zaptech.org:/public/test-git/basic
  ... master -> origin/master

$ git diff origin/master

  @@ -1,2 +1,2 @@
  -update 2012-01-13
  +test
 
$ git merge origin/master

  Fast-forward
  notes.txt |    2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)

$ vi notes.txt 

  [ change notes.txt ]

$ git status -s

   M notes.txt

$ git add notes.txt 

$ git commit notes.txt -m "second tweak"

  1 files changed, 1 insertions(+), 1 deletions(-)

$ git status -s

$ git push origin

  Total 3 (delta 1), reused 0 (delta 0)

  ...  master -> master 

Removing Files

$ git rm foo.bar -m "remove against local cache"

$ git push origin 

Archiving

Related

Archiving provides a way to strip git management files from a given file set.  Typically this is done when releasing or distributing a project to an environment that needs a clean file set free of unnecessary information.

$ git clone ... [projectname] ...

$ cd [projectname]

$ git archive master --format tar -o ../test.tar

$ cd ..

$ ls -lh test.tar

  -rw-r--r--  1 rickatech  staff    40K Jan 18 17:40 test.tar

$ rm -fr [projectname]

$ tar xvf images/test.tar 

  x admin/
  x admin/admin.php
  x admin/upload_debug.php
  x common_default.php
  x latest.php
  x notes.txt
  x prettydb.php
  x schema.txt
  x single.php
  x tags.txt

$ ls

  drwxr-xr-x   4 rickatech  staff   136B Jan 18 14:07 admin
  -rw-r--r--   1 rickatech  staff   1.2K Jan 18 14:07 common_default.php
  drwxr-xr-x  12 rickatech  staff   408B Jan 18 17:40 images
  -rw-r--r--   1 rickatech  staff   835B Jan 18 14:07 latest.php
  -rw-r--r--   1 rickatech  staff   1.4K Jan 18 14:07 notes.txt
  -rw-r--r--   1 rickatech  staff   3.8K Jan 18 14:07 prettydb.php
  -rw-r--r--   1 rickatech  staff   2.2K Jan 18 14:07 schema.txt
  -rw-r--r--   1 rickatech  staff   1.9K Jan 18 14:07 single.php
  -rw-r--r--   1 rickatech  staff   494B Jan 18 14:07 tags.txt
  -rw-r--r--   1 rickatech  staff    40K Jan 18 17:47 test.tar 

Miscellaneous

Elsewhere

$ git log --pretty=oneline

$ git remote add [ nickname ] [ remote path ]

  ... default with clone is origin/master,
      addition remotes should have distinct name like, redbox/master 

$ git push -u ...

  ... if clone wasn't recently used,
      the argumentless settings will be reset with -u ???

$ git tag [ tag name ]

  ... light tag ...

$ git tag -a [ tag name ] -m "some description"

  ... annotated release style tag ... 

$ git push [ tag name ]

  ... otherwise tags typically are not automatically pushed ...

$ git push --tags 

  ... push all local tags ...

$ git fetch [ tag name ]

  ... typically tags in current branch fetched automatically,
      use this to access tag from a different branch ...

$ git fetch --tags

  ... this also fetches tags not in active branch ...
    
$ git push origin cool_tag_name 

  ... push specific tag to remote repository ...

$ git push --follow-tags

  ... push commits and 'topical' annotated tags to remote repository ...

$ git tag -d cool_tag_name

  ... delete tag locally ...

$ git push origin --delete cool_tag_name

  ... delete tag on remote, best to also remove it locally first  ...

  [ if cool-tag_name doesn't exist error, try git remote prune origin ]

$ git branch -a

  ... show local and remote branches

$ git branch iss53

$ git checkout iss53

  ... create new iss53 branch, then switch to it

$ git branch -D x

  ... obliterate local branch x ...

$ git checkout --track -b px origin/px

  ... magically create a local branch, then make it track given remote branch ...

$ git push origin --delete x

  ... delete branch x on remote

$ git log --graph --pretty="format:%C(yellow)%h%Cred%d%Creset %s %C(white) %C(cyan)%an%Creset, %C(green)%ar%Creset"

  * fb9189c (HEAD, master) the image upload manager link updated  Rick Armstrong, 26 minutes ago
  * 21f1d51 (tag: 20151012_fp) fp 20151012_fp  Rick Armstrong, 4 hours ago 

$ git reset --merge

  [ handy if a merge conflict occurs and you just want to abort ]

$ git diff --name-status rick_symp..qa

$ git diff --stat --color rick_symp..qa

  [ overview of file changes between branches ]

$ git diff; git diff --cached; git diff HEAD

  [ see changes that have been added, but not yet committed ]

### danger, avoid space when specifying branch to merge from 

$ git merge origin/editprof (yes)
$ git merge origin editprof (no!) (will assume origin/master!)