★ git basics
posted Tue 15 Dec 2015 by Michael Galloy under IDLI migrated my libraries to git, and GitHub, from Subversion over eight and a half years ago. While there is a bit of a learning curve to git, it is possible to handle basic operations fairly easily. The following is an overview of the basic features of git with some comparisons to Subversion. This basic overview completely omits many features of git; for more information check out the git docs.
Setup
It is useful to configure git with your name, email, and editor for all the projects that you will be using it for. For example, the following is my setup for git:
$ git config --global user.name "Michael Galloy"
$ git config --global user.email mgalloy@gmail.com
$ git config --global core.editor "emacs -nw"
$ git config --global core.autocrlf input
You can also do configurations per project. For example, in the case you have a project where you interact with a remote repository where you have a different account name.
Create a new repo
If you have a directory (with possible subdirectories) that you would like to turn into a git repo, use init
from the directory:
$ git init
This is a major advantage of git over Subversion: you can very quickly turn any directory into a git repository and start working.
Use clone
to make your own local copy of an existing repo, e.g., a repo created on GitHub. For example, the following command will grab the mglib
GitHub repo and make a local copy:
$ git clone https://github.com/mgalloy/mglib.git
This is analogous to a Subversion checkout.
Add files and commit them
If you are familiar with Subversion or other version control systems, this is similar. We need to tell git to track a particular file with the add
subcommand, then use commit
to indicate that you want to save the current contents:
$ git add
$ git commit
There are several differences with Subversion at this stage though:
- The changes are only saved locally, not pushed to a centralized repository (see next section about communicating with a remote repository).
- It is necessary to “stage” files with the
add
subcommand before every commit, not just the first time.
The status
subcommand is useful to check which the state of the files in repo:
$ git status
Push/pull to/from another repository
If you cloned from a remote repository, then you have a remote called “origin”. You can push commits from your local repository to this remote repository with the following:
$ git push origin master
The “master” refers to the default branch. Similarly, you can retrieve new commits from origin by pulling:
$ git pull origin master
Look at your history
The log
subcommand gives the history of your commits:
$ git log
commit cac05188a6997d4dc8febd7363d706768cd8cd16
Author: Michael Galloy <mgalloy@gmail.com>
Date: Mon Aug 25 18:40:50 2014 -0600
Doing total to find contrast.
commit 4bb170a6a57e53a87b1a5dd4db3ed31774f977af
Author: Michael Galloy <mgalloy@gmail.com>
Date: Mon Aug 25 17:51:22 2014 -0600
Adding example in main-level to compute contrast from GLCM.
Sometimes, I like using a few options to get a history that is easier to glance down through many changes:
$ git log --color --pretty=oneline --abbrev-commit
cac0518 Doing total to find contrast.
4bb170a Adding example in main-level to compute contrast from GLCM.
Note that git commits are referenced by a long hash value, not an incrementing integer value. Because of the distributed nature of git, it would not be possible to keep a simple incrementing counter. The first seven digits of the hash are usually all that is needed to reference a commit.
See your changes
The diff
subcommand shows differences between items. To see the changes that have not been add
ed yet do:
$ git diff
To see the changes just for a single filename, do:
$ git diff FILENAME
To see the changes between two commits, do:
$ git diff COMMIT1 COMMIT2
Undo a change
One of the main features of version control is to be able to revert changes and to retrieve old versions of code. There are multiple commands to revert, depending on the stage of the code that is being reverted.
For example, to destroy the changes to a file that has not been add
ed or commit
ed, you can just checkout a fresh copy of it:
$ git checkout --
To “visit” the repo at the state it was on a specific commit, do:
$ git checkout
To make a new commit that undoes existing commits (like a version control inverse function), use the reset
subcommand. The first few characters of a hash found from the log
subcommand are needed to refer to commits, though there is special notation for the most current commit HEAD
and back n
commits HEAD~n
. So to create a new commit that reverts the last two commits, you can do:
$ git revert HEAD~2..HEAD
To create a new commit that reverts the commits from 0123456
to the HEAD
, do:
$ git revert 0123456..HEAD
It is also possible to actually delete commits using the reset
subcommand, either “soft” or “hard”. This can be problematic if the commit has been pushed to a remote; it is much simpler if the commit hasn’t been pushed yet.
For example, to delete the last commit, keeping the state of the repo as it was just before the commit, i.e., the code changes are still present:
$ git reset --soft HEAD~1
To really delete the commit and its changes fully, do:
$ git reset --hard HEAD~1
Branching and merging
Branching and merging are fundamental to using git effectively. Branching is useful because there are usually multiple versions of the code that are progressing at the same time. For example, you might create a branch for a specific feature so that large changes can be made without breaking the main branch. Or a branch for a release might be made so that quick fixes for the release can be made as well as progressing along for the next release.
To create a branch named “geometry”, do:
$ git branch geometry
That will create the branch, but you will still be on the default “master” branch. To change to the “geometry” branch, do:
$ git checkout geometry
After doing commits on this branch, when it is time to merge the changes back into the “master” branch, use the merge
subcommand:
$ git checkout master
$ git merge geometry
There can be conflicts in a merge, if both branches have made changes. In that case, the merge will indicate the issues. Fix the conflicts and do an add
/commit
. Use git status
to find the remaining conflicts.
If you are done with the geometry branch now, you can delete it with:
$ git branch -d geometry