Version control for local files using GIT

This guide shows how to have local files under version control using git. It does not cover how to clone remote repositories (there are plenty of guides already available for that).

Setting up a git repo:

  • Install git:
$sudo apt-get install git
  • Basic configuration. This step can be skipped. The third command is to tell git to use your favorite editor for editing commit messages.
   $git config --global user.name "Vaivaswatha N"
   $git config --global user.email "vaivaswatha@hpc.serc.iisc.in"
   $git config --global core.editor emacs
  
  • I assume henceforth that the directory you want to version control is ${SRC}. Files inside this directory will be under the git version control. Go inside this directory.
$cd ${SRC}
  • Create a new git repo for this directory. This command will create an empty repo.
$git init
  • Mark all files in the directory for committing (note the trailing '.').
$git add .
  • Commit all these files to the repo. This step completes the repo setup. GIT will prompt you to enter a commit message. Just say something like “creating new repo”, save the file and exit.
 git commit
  • Your git repo is now ready. All your files are under version control.

Basic version control using git:

  • To check currently modified files in your repo, run this command in any (sub)directory of your repo.
$git status
  • Mark modified files for commit: This command will add files to the staging area, which means its marked for commit, and will be committed the next time you run “git commit”. If you make any changes to files after “adding” them, those changes will not make it to the commit, you will need to again “add” the file.
$git add <filename(s)>
  • Commit files: This will commit marked files to the repo. After this, these files will no longer be shown under “git status” command. As before, you will need to enter a commit message.
$git commit
  • Revert files: If you would like to discard changes you have made (but not committed) to a file, use this command.
$git checkout <filename>
  • Revert all uncommitted changes: All current changes will be reset.
$git checkout .
  • Revert a commit: This will try to undo all changes done during a commit. The revert itself will be a new commit.
$git revert SHA1
  • Diff: See the changes you've made to a file
$git diff <filename>

This will display differences between the repo copy and the modified copy of the file.

  • Log: see commit logs for your repo
$git log
  • View changes from a commit: While “$git diff SHA1 SHA2” in most cases shows the diff between two commits, with merges in between, it may be simpler to use below command to see changes from a particular commit.
$git show SHA1
  • Checkout old versions: This command will checkout an older version into a new branch. Here SHA1 is the hash of the older revision you want to check out (this can be obtained from “git log”).
$git checkout -b <NewBranchName> SHA1
  • Switch branches using this. You need to have all files committed before you can switch branches.
$git checkout <BranchName>
  • See all branches present:
$git branch
  • Delete a branch:
$git branch -D <BranchName>
  • Merge branches: This command will merge “BranchName” to the currently active (selected) branch.
$git merge <BranchName>
  • Rebase branch: This command will update the branch with changes from master. i.e. After you branched out, master might have moved forward. Rebasing your branch with master will get your branch up to date with master.
$git rebase master
  • Typical workflow is to branch out (say branch1) from master, do your work in “branch1” and commit it. Then switch to master and merge “branch1” to it. Changes from different branches come into master this way (via merges). Your branch can keep updated with the master by rebasing against it. Note that rebasing will cause all commits since divergence from base to be re-committed. This will create a mess if your local branch is tracking a remote branch and you push to the remote branch. Use `git merge` to merge from the base, instead.
  • Cherry pick a change from another branch, instead of merging all of it. i.e. Instead of all changes “till” a specific commit (or the HEAD) (which is what “git merge” would do), just pick *only* a specific commit.
$git cherry-pick SHA1
  • See this link for more details on branching in git.
  • Stashing and getting back local working changes (i.e, those changes in the working area - not yet committed). The first one stashes away the code and restore the codebase to HEAD (last committed change). The second one will restore back the changes.
$git stash
$git stash pop
  • Adding a “remote” to an existing git repository: (If adding a second remote, give it a name other than “origin”).
$git remote add origin path://to/git/repo 
  • Checking out and updating branches (not necessarily master) from remote:
 $git remote update
 $git checkout -b branchname origin/branchname 
  • Push changes up-stream (you can omit the last two arguments if you are on “master”). The ”-u” argument ensures that from next time, you can do an argument less “pull” or “push” on that branch to correspond with “origin”.
 $git push -u origin branchname 
  • Pull changes from a repository other than “origin” (repository needs to be added using “git remote add” command).
 $git pull repo branchname 
  • Modify the last commit. Any changes you want to make, like including adding new files from the staged area to the commit or editing the commit message, can be done with this command:
 $git commit --amend 
  • Pretty print (branch graph etc) git log. Use command “git lg” after running this command
 $git config --global alias.lg "log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n''          %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all"