C. David Sherrill
School of Chemistry and Biochemistry
Georgia Institute of Technology
These notes introduce some basic git commands and operations. They assume you are working off private or locally shared repositories. They do not cover community development, like with GitHub.
Recommended book: Pragmatic Version Control Using Git, Travis Swicegood (The Pragmatic Bookshelf, Raleigh, 2010)
To make a repository for your own (non-shared) use:
git init
To make a shared repository for use by a group:
I have some separate notes on this
To clone a local repository:
git clone other-repository-location proj-dir
To clone a remote repository:
git clone username@machine://remote-repository proj-dir
username@machine
specifies an SSH login to a remote machine.
With certain services like GitHub, it is also possible to clone via
http
.
To add a new file to the repository:
git add [filename]
git commit -m "log message"
git add -i
git add -p
Checking in changes: This requires two steps: (1) staging the change, and (2) committing the change.
git add [filename]
git commit -m "log message"
git commit -m "log message" filename
git commit -a -m "log message"
To check on the status of the working copy:
git status
Get changes from repository:
git pull [remote-repository] [remote-branch-to-pull]
git fetch
Communicate local changes to remote repository:
git push [--dry-run] [remote-repository] [refspec]
--dry-run
option shows you what changes would be
pushed. refspec is a tag, branch, or keyword like HEAD; e.g.,
mybranch:master
pushes changes from mybranch to the remote master
branch. The default remote repository is named origin.
To see what's been changed in a file:
git diff
git diff --cached
git diff HEAD
git diff [revision-id]
git diff --stat [tagname or revision-id]
To get a summary of recent committed changes,
git log [-n] [--pretty=oneline]
git log -p
git log [revision-id]
git log --since="7 hours"
git log --pretty-format:"%h %s" 1.0..HEAD
To see who changed a particular file: so you know whom to blame for an error,
git blame filename
git blame -L 208,+5 filename
git blame -L "regexp",+5 filename
To remove a file from the repository:
git rm filename
git commit -m "log message"
To move a file:
git mv oldname newname
git commit -m "log message"
To tell git to ignore some files in a working directory:
Sometimes you'll have files, like vi
swap files with names
like .file.swp
, that you don't want git to worry about.
This is easy to fix, just add the relevant filenames or wildcard
filenames (like *.swp
) to the file .gitignore
.
Alternatively, if this is a personal preference appropriate to
a particular developer, and maybe not appropriate to adding to a
shared repository, exclusions like this can be added to the local
.git/info/exclude file
.
To create a branch:
git branch new-branch-name branch-to-create-from
git checkout -b new-branch-name branch-to-create-from
To switch the working copy to a different branch:
git checkout branch-name
To see a list of all available local branches:
git branch
To see a list of all available remote branches:
git branch -r
To rename a branch:
git branch -m oldname newname
Rebasing: to apply changes from one branch to some other branch: First, figure out what branch you want to absorb changes from another branch (usually, master). Assuming the other branch is already up-to-date and checked in, switch to the branch you want to absorb the changes:
git checkout master
git rebase other-branch-name
git branch -d other-branch-name
Resolving merge conflicts:
Sometimes you might get a conflict when trying to do the merge.
In such a case, the file(s) with the conflict will have the standard
"conflict markers." The beginning of the conflict region will be
marked with "<<<<" symbols and the name of the current branch and file.
That version of the file will continue until another marker of "======"
symbols. Then, the conflicting version of the text will appear until
closed off by ">>>>" symbols and the name of the conflicting branch
and filename. Multiple areas of conflicting text might appear in a
single file.
Edit the file by hand to resolve the conflict. Make sure you
delete the conflict marker lines beginning with ">>>", "<<<", or
"===". We don't want those checked in. Once the file is the
way it's supposed to be, git add the conflicted file and do a
git commit. In this particular case, if you leave off a log
message, git will automatically create one specifying that it's
related to a merge.
Squashed commits: If you had to experiment quite a bit in an alternate branch before getting something right, you might not want to commit all the individual changes, but just the final changes in the alternate branch relative to the main branch. In a case like this, finish checking in any changes on the alternate branch, check out the master branch
git checkout master
git merge --squash alternate-branch
git commit -m "log message"
Cherry-picking merges:
If you want to merge in just one change from another branch, you
can use the fact that commit identifiers are unique across the
entire repository to select the commit you want to merge. Get
the commit ID by noting it after it's printed in git commit,
or from the log file (you don't need the entire ID number from
the logfile, the first 7 characters or so should do it). Then,
switch to the branch you want to merge changes into, like
git checkout master
git cherry-pick [commit-id]
git commit -m "message"
git cherry-pick -n [commit-id-1]
git cherry-pick -n [commit-id-2]
git commit -m "message"
Tags:
you can tag a specific point in the repository by
git tag tag-name branch-name
git tag
Multi-paragraph commit messages: can be specified by multiple -m "message" arguments to git commit
To create a gzip archive of the project as of some specific tag:
git archive --format=tar \
--prefix=proj-dir tagname \
| gzip > proj-dir.tar.gz
Reverting a commit:
To undo the latest commit, do
git revert
-n
flag:
git revert -n [commit-id, or HEAD for most recent]
git revert -n [other-commit-id]
git commit -m "revert [commit-id1] and [commit-id2]"
Resetting the repository:
If we really did something terrible (like checked in a private password
file), we can reset the whole repository to its state at some given
point
get reset [commit-id]
[commit-id]
defaults to HEAD, the previous version.
the flag --soft
allows you to stage the previous commits
but not commit them. The --hard
option removes the commit
from the repository and from the working tree.