Git notes

Written on Sat 14 Nov 06:30 2015

What’s a Git?

Git is an open source version control system (VCS) typically used for tracking changes in text files.

A long time ago, VCS were centralised which meant there was a single central project stored on a server. People would ‘commit’ their files - a process to record their changes to the server - so that when others checked them out, they would see the most recent version. This idea of one project and all it’s history (aka repository) shared amongst all contributors was superior to the old method where people kept multiple copies of the same files and passed them to each other via email/floppy disk. (eg. essay_v1.txt, essay_v2.txt) Some popular examples are CVS and Subversion (SVN).

In distributed VCS’s like Git and Mercurial, instead of storing the repository on a server, everyone can clone or get a full copy on their local system. Unlike centralized VCS, committing changes and viewing different versions is extremely fast as it occurs over the hard drive instead of the network. To collaborate with others, you still have a ‘central’ repository stored on a server (like Github) where changes are ‘pushed’ to the server’s repository and ‘pulled’ to keep your local repository in sync. In this sense, DVCS can still be viewed as centralised but it isn’t required.

Terminology

  • Fork A personal copy of someone’s online repository that lives on your online account. Forks can be modified without affecting the original. Forks are linked to the original so you can make a pull request.

  • Pull request after making changes to a fork, a pull request tells the original repository’s owner that you want them to include your changes into their repo, which they can reject or integrate.

  • Clone The act of copying an online repository to a local system. Once cloned, you use the Git tool to commit, view version history and sync with the online repository.

  • Commit A file or set of files which you want Git to record in it’s history. A commit is identified by a hash (a 40 character string unique identifier), author, email and a short message from the committer about what’s changed.

  • Remote A repository stored online or on a server, like on Github.

  • Push Sending a set of commits to a remote so that others may see your latest work.

  • Pull Copying a set of commits from a remote to a local repository. A pull will sync the remote with the local repo. It is generally a good idea to pull often to lower the chance of conflicts between the remote and local repos.

  • Merge conflict If the remote and local repo have modifications to the same part of text in the same file and you try to do a push or pull operation, a conflict occurs. Git will mark portions of text and it is up to the author to decide which parts stay and go.

  • Working directory The directory where git is actively monitoring for changes to your project

  • Staging area/index Your working directory may contain superfluous files that you may not want in the repo, such as executibles, graphics or log files. The staging area is like a loading bay for files so you can decide what exactly goes inside a commit. You may have implemented several features but want to make separate commits for each of them. The staging area allows this kind of flexibility.

  • Branch Just like a tree’s branches diverge from a trunk, so to does software development. A branch is a separate path of development that allows you to work on different stages of work. The ‘trunk’ is called master and you create branches off master that move indepedantly from and parallel to it. For eg. you have an experimental branch for writing features that may be unstable that you do not want affecting the main branch. Once they are stable, you can merge them back into master.

  • HEAD A pointer to the tip or latest commit in a repo

Commands

CRUD

Command Desc
git init start tracking changes in the current working dir. Everything in this folder will be monitored
git status compares the files to the last commit. Shows files that have changed since the last commit (unstaged) as well as files that are ready to be committed (staged)
git log show commit history or a timeline of the changes.
Options
--oneline list each commit on a single line showing hash and message
-NUM show last NUM commits
[-p] FILE list commits affecting FILE and optionally -p to show content changes
git diff show the file content differences between the last commit and changes in the working dir.
Options
--staged for staged files
--color-words show changes in color
HASH1 HASH2 compare differences between the 2 commits
HASH FILE compare differences for FILE between working dir and commit HASH
-w ignore white space differences
--name-only --diff-filter=U list files that have merge conflicts
git add FILE add FILE to the staging area. Any changes to FILE up to the point when the file was added will be recorded. If you change the file afterwards, those changes won't be reflected if you do a commit
git rm FILE remove FILE from working dir and staging area
git commit -m "MSG" record the changes in the staging area to the repository. The message _MSG_ helps people understand what high level changes you made when they do a git log
git clone URL [DIR] copy the repo from URL to the local system's DIR. If DIR unspecified, the repo will be created in a folder with the repo name
git commit --amend Update the last commit with files in staging index. Can also use this to update the commit message only

Ignore files

The .gitignore file is stored in the root folder of the project and tells git what files to ignore so you don’t get a whole bunch of ‘untracked files’ that you know you will never commit

Inside .gitignore, you can put:

  • DIR/ - ignore tracking a directory called DIR

  • !DIR/FILE - if you ignore DIR but wish to make an exception to DIR/FILE

Undo

Command Desc
git reset FILE remove FILE from staging area
git revert HASH Undo commit HASH completely and commit those changes
git checkout -- FILE revert FILE back to last commit. Works for directories too. Any changes since will be lost! The -- means current branch
git reset --soft HASH Move HEAD to an older commit HASH. Most recent changes in working dir and staging index remain
git reset --mixed HASH Move HEAD to an older commit _HASH_ and modify staging index to match that commit. Does not change working dir
git reset --hard HASH Move HEAD to an older commit _HASH_. Both working dir and staging index match the older commit. This destroys all changes since that commit!

Remote

Command Desc
git push [-u] [NAME] [BRANCH] copy the latest changes from the local repo to a remote. The name is a shorthand associated with a url. The -u (upstream) flag tells Git to use the alias and branch as default from now on when you do 'git push'. You need to have specified a remote beforehand. see 'git remote add ..'
git pull [NAME] [BRANCH] copy the latest changes from the remote to the local repo
git remote -v list the remote alias and url's for the repo
git remote add NAME URL links a local repository to a remote
git remote rm NAME Remove remote NAME

Branches

Command Desc
git branch Show branches in repo. The star shows which branch you are on.
Options
-r lists remote branches
-a lists all branches
git branch BRANCH Create a new branch called BRANCH but stay in current branch
git checkout BRANCH Switch to branch BRANCH. Ie. make working dir match the latest commit in branch
Options
-b creates a new branch called `BRANCH` and switches to it immediately
git branch -d BRANCH Delete branch BRANCH. It will not delete if you have unmerged changes.
Options
-D Force delete, even if it has unmerged changes.
git merge BRANCH Merge changes from BRANCH into current checked out branch git merge --abort Abort a merging operation when there are merge conflicts git branch -m BRANCH Rename the current branch to BRANCH

Stash

If you are in the middle of working on something and an interruption requires you to switch branches, stashes allow you to save what you are currently working on so you can come back to it later without having to commit those unfinished changes. Think of it as a storage area for half baked work.

Command Desc
git stash save "MSG" Save changed files to stash with _MSG_
git stash list Show all the saved items in stash
git stash show stash@{0} Show file differences in item stash@{0}
git stash show -p Show file content changes in a stash
git stash pop stash@{0} Merge item stash@{0} into current branch and remove it from stash
git stash apply stash@{0} Merge item stash@{0} into current branch but keep it in stash
git stash drop stash@{0} Delete item stash@{0}
git stash clear Empty entire stash