Git Setup and Configuration

This article explains how to perform version control using Git (Linux or Windows server) and TortoiseGit (Windows client).

Installation

Install git server and client in Ubuntu Linux:

$ sudo apt-get update
$ sudo apt-get install git

Install git server and client in Windows:

Configuration

Customize Git environment (Git Client) to include developer's name and email address:

Repository Setup (directory under Version Control)
Setup for EOL Normalization

When adding and committing files to Git, EOL characters get normalized, ie. translated to Git's default, which is [LF]. You can specify how to translate it (or not translate it at all).

Git checks the [projname]/.gitattributes file first, and if nothing matches there, it drops back to the local and system wide settings, such as found in [projname]/.git/config.

How core.autocrlf works:

core.autocrlf=true     core.autocrlf=input       core.autocrlf=false

       repo                     repo                    repo
    /        \               /        \              /        \
crlf->lf    lf->crlf     crlf->lf       \          /            \      
 /              \        /                \      /                \
push            pull    push              pull  push              pull

End-of-line marker:

In file [projname]/.git/config, under [core]:

GitAttributes file
Working with Git

Source:

Create Repositories

Start a new repository or obtain one from an existing URL.

$ git init [project-name]   # Creates a new local repository with the specified name.
$ git clone [url]           # Downloads a project and its entire version history.

Make Changes

Review edits and craft a commit transaction

$ git status          # Lists all new or modified files to be commited
$ git add [file/dir]  # Snapshots the file in preparation for versioning
$ git reset [file]    # Unstages the file, but preserve its contents
$ git diff            # Shows file differences not yet staged
$ git diff --staged   # Shows file differences between staging and the last file version
$ git commit -m "[descriptive message]"   # Records file snapshots permanently in version history

Group Changes

Name a series of commits and combine completed efforts

$ git branch                    # Lists all local branches in the current repository
$ git branch [branch-name]      # Creates a new branch
$ git checkout [branch-name]    # Switches to the specified branch and updates the working directory
$ git merge [branch]            # Combines the specified branch’s history into the current branch
$ git branch -d [branch-name]   # Deletes the specified branch  

Refactor Filenames

Relocate and remove versioned files

$ git rm [file]           # Deletes the file from the working directory and stages the deletion
$ git rm --cached [file]  # Removes the file from version control but preserves the file locally
$ git mv [file-original] [file-renamed]  # Changes the file name and prepares it for commit  

Suppress Tracking

Exclude temporary files and paths *.log, build/, temp-*. A text file named .gitignore suppresses accidental versioning of files and paths matching the specified patterns.

$ git ls-files --other --ignored --exclude-standard  # Lists all ignored files in this project  

Save Fragments (to Stash)

Shelve and restore incomplete changes (see also: Git Stashing)

$ git stash [<msg>]  # Temporarily stores all modified tracked files
$ git stash list     # Lists all stashed changesets
$ git stash pop      # Restores the most recently stashed files, removing top of stash
$ git stash apply    # Restores the most recently stashed files, without removing top of stash (no popping)
$ git stash drop     # Discards the most recently stashed changeset  
$ git stash clear    # Clear stash

Review History

Browse and inspect the evolution of project files

$ git log                   # Lists version history for the current branch
$ git log --follow [file]   # Lists version history for a file, including renames
$ git diff [first-branch]...[second-branch]  # Shows content differences between two branches
$ git show [commit]         # Outputs metadata and content changes of the specified commit  

Redo Commits

Erase mistakes and craf replacement history

$ git reset [commit]          # Undoes all commits afer [commit], preserving changes locally
$ git reset --hard [commit]   # Discards all history and changes back to the specified commit  

Synchronize Changes

Register a repository bookmark and exchange version history

$ git fetch [bookmark]           # Downloads all history from the repository bookmark
$ git merge [bookmark]/[branch]  # Combines bookmark’s branch into current local branch
$ git push [alias] [branch]      # Uploads all local branch commits to GitHub
$ git pull                       # Downloads bookmark history and incorporates changes  

Fetch vs. Pull: Do a git fetch at any time to update your remote-tracking branches under refs/remotes/<remote>/. This operation never changes any of your own local branches under refs/heads. A git pull is what you would do to bring a local branch up-to-date with its remote version, while also updating your other remote-tracking branches.

Basically a git pull is a git fetch + git merge FETCH_HEAD, but the latter allows time to review changes before the merge (the former does the merge automatically, which sometimes can be disastrous).

Therefore, instead of a git pull, using git fetch; git reset –hard origin/master is a safe method to add to your workflow. It eliminates local changes, keeps you up to date with master, but ensure new changes do not get pulled in on top on current changes and make a mess. It is a safer practice. Just be sure to add/commit/stash any work-in-progress first.

See:

Get any changes in the remote branch since the last pull:

$ git fetch
$ git diff ...origin (or $ git diff origin/master)

Merge or Rebase

Merge the master to the feature branch:

$ git checkout feature
$ git merge master

Or, you can condense this to a one-liner:

$ git merge master feature

As an alternative to merging, you can rebase the feature branch onto master branch using the following commands:

$ git checkout feature
$ git rebase master  

The golden rule of git rebase is to never use it on public branches. For example, never rebase master onto the feature branch. This affects all developers, which causes a lot of problems.

If you treat rebasing as a way to clean up and work with commits before you push them, and if you only rebase commits that have never been available publicly, then you’ll be fine. If you rebase commits that have already been pushed publicly, and people may have based work on those commits, then you may be in for some frustrating trouble, and the scorn of your teammates.

FYI, you could run git pull –rebase to try to reduces issues after it happens.

At this point, you can go back to the master branch and do a fast-forward merge.

$ git checkout master
$ git merge feature

References:

Remote Git Server

To have Git working as a remote backup repository, create the remote repository as a bare repository (by convention, a bare repo has .git at the end):

$ mkdir my_remote_repo.git
$ cd my_remote_repo.git
$ git --bare init

Now clone that remote repository:

$ git clone [url-my_remote_repo]

Now, using the new working copy, you can add files then push those files back into the remote repo. The remote location will not have a working tree.

Alternatively, to turn an existing “non-bare” repository into a “bare” repository in Git, you can do this:

$ git clone --bare [non-bare-repo] [new-bare-repo]

You can also:

Remote Git Repositories
Setup Local Repo to Push to BitBucket Repo using SourceTree

Install SourceTree and add BitBucket account:

  1. On the SourceTree application options (Tools > Options > Authentication > Accounts), add a BitBucket account.

Set the authentication to use Preferred Protocol SSH instead of HTTPS.

  1. On the SourceTree local repo, go to Settings and change remote origin address from https (ie: https://[username:password]@bitbucket.org/[username]/[repo].git) to ssh (ie: git@bitbucket.org:[user]/[repo].git). You will find these addresses at the top of your BitBucket repository page.

Create an SSH key

  1. On SourceTree, select Tools > Create or Import SSH Keys.
  2. In PuTTY Key Generator, generate a 2048-bit SSH-2 RSA key, then:
    • Copy the public key.
    • Save the private key locally.
    • Save the public key.

Install Private Key on Pageant (PuTTY Authentication Agent)

  1. Run Pageant or open from icon tray.
  2. Add private SSH key, by clicking on Add Key button, then entering the passphrase.

Add Public Key to BitBucket

  1. In SourceTree, open the PuTTY Key Generator from Tools > Create or Import SSH Keys.

Click Load and select the private key file.

  1. Copy the public key.
  2. On BitBucket Account Settings (user avatar), select SSH keys, then Add Key.
  3. Enter label “Default Public Key”.
  4. Paste public key to Key field, and save.

References

Git Flow

Organizing your repository to use git flow. Author: Vincent Driessen | Original blog post: http://nvie.com/posts/a-succesful-git-branching-model | License: Creative Commons BY-SA

References

See more: