Summary of Git Operations
The following describes the operations one ordinarily executes with git during source code development activities.
Perform the following
git config settings when configuring git for the first time:
Cloning an Existing Project
The following will clone the afw package to a subdirectory called
Add a New File
Edit a File and Commit the Changes
View the Commit Tree
You can view the commit tree with graphical tools such as gitk or gitx (for OS X), or do the following on the command line:
Amending a Commit
Use the following to change the most recent commit message (and more):
A check of the status will show that the branch is ahead of origin/master by 2 commits. Do a
push to make the changes available to everyone–i.e., they become part of the official LSST code history:
Working with Branches
Create a Branch
View the current branch, create a new branch named
tickets/DM-9999, and then check out the new branch:
or, you can do it in one line:
The above checks out
HEAD into a newly created branch
tickets/DM-9999 and switches to it.
Add a Source File
After adding a source file (as above), you may switch branches like so:
List Available Branches
The following are variations for listing available branches:
Making Branches Available
The following will push the branch
tickets/DM-9999 to the remote repository '
origin' and set it up so we can pull from the remote branch in the future:
git pull --rebase" instead of just "
git pull" when working on a branch with someone else; this will avoid unnecessary merge commits without rewriting any history that has already been pushed.
Checking out and tracking an existing branch from an upstream repository
Given a branch
tickets/DM-8888 that resides in the remote repository "
origin", you can check out that branch with the following:
Note: newer versions of git allow just
Alternatively, the following checks out
tickets/DM-8888 from remote '
origin' into a local tracking branch named '
Listing commits on a branch
List commits reachable from '
tickets/DM-8888' that are are not reachable from the master. This will exclude any commits that were merged to the ticket from master.
Now display the differences caused by the above commits. Note: there are 3 dots in this syntax, which is unique to
To merge your work on a branch back to master, first ensure that you've checked out master, and that your source is up-to-date. Then perform the merge, in this case the branch
Now verify the merge, then upload the changes to the main LSST repo:
Tagging a package, as might be done for a release, is done using the
You can use
-m MSG with
-a to save, starting an editor. Note: you must use
git describe will ignore your tag. Then finish with:
Oops, I should have done that on a ticket branch
The following tip is adpted from http://schacon.github.com/git/git-reset.html.
I thought it was going to be a tiny bug-fix that I could commit straight to master but it grew into something that should be done on a ticket.
The following fix is for when you have already committed your changes, but have not yet pushed them:
Remember that number 5.
If you're making a new ticket for a fix,
and keep working as usual. If you want to apply your commits to an existing ticket branch,
Be aware that the above will also merge all other commits to master into your ticket branch.
Some useful command-line prompt hacking
Git is distributed with a shell script,
contrib/completion/git-prompt.sh, that defines a function,
__git_ps1 that's useful for displaying the branch and status of a git repository in your command-line prompt. This file seems to be generally installed by distributors, and so you probably already have
__git_ps1 defined in your environment. If not, grab that shell script and source it. If you can't get it, or don't want it, then a poor-man's version is supplied, below.
The behaviour of
__git_ps1 is configurable with the following environment variables:
|Environment Variable||Define to Value||Meaning|
|Non-empty||* indicates unstaged changes and + indicates staged changes|
|Non-empty||$ indicates the presence of untracked files|
<> indicates you've diverged
= indicates there's no difference
The result is something like:
(i.e., I'm on branch
tickets/DM-1234 with changes committed that I can push) but all you have to do is add
$(__git_ps1) at the desired location in your current PS1 definition. You can source the following script:
What is the difference between git commit and git commit -a ?
See this great explanation here, that I didn't find until I wrote the text below (sigh)...
Committing changes to a git repository is a two-step process:
- Step 1: specify which of the (possibly many) modified files would you like to commit as a part of this change set
- Step 2: execute the commit.
The two above steps equate to the following commands:
- Step 1: git add modifiedFile1.cc modifiedFile2.cc modifiedFile3.cc ...
- Step 2: git commit
Most version control systems (including SVN and hg) omit Step 1. and always assume you want to commit all files that have been modified. Git is not as presumptuous, because there are sometimes good reasons why you'd want to split the modifications into two different commits (e.g., if you've modified 10 files while developing a new feature, while the one-line modification in the 11th file was an unrelated bug that you stumbled upon and fixed in the process). Now, what if you do want to commit changes to all modified files (or if you're used to SVN behavior and see no point in extra typing)? Then use:
- git commit -a
-a switch tells git to run an implicit
git add for all modified files in the working directory, before performing the commit.
How do I restore a file to unmodified state ?
The way to read this command is: 'Dear git, please check out from branch
HEAD the file
myfile.txt'. In git,
HEAD always refers to the current branch. You can probably already tell that writing:
would check out the file from
otherbranch. It's even more general than that: instead of a branch name, you can give it any tree-ish out of which to extract the file.
What are best practices for developing on a branch?
Often the features you're developing take a long time to mature. Therefore your feature branch (also sometimes called a "topic branch") may lag behind master quite a lot by the time you're done. What should you do? Should you "sync up" often by merging 'master' into your feature branch, or should you wait and fix any conflicts until the very end?
Junio Hamano has an excellent post on this that is a MUST to read. To summarize:
- Merge your feature branch into the master only when it's complete (up to bugfixes).
- Merge the master into your feature branch only when there's a new feature in master that the code in your branch needs to use
This strategy minimizes the number of merges in the history of the project, which helps with tools like
git bisect (automated finding of commits that caused bugs/regressions). And if you are nervous about doing all the conflict resolution at the very end, look into git rerere.
What are 'cache', 'index', and 'staging area'?
To first (and second, and probably third) order, they're the same: the staging area where you place the files (using
git add) that are to be a part of the next commit. That there are three terms for one and the same thing is a historical artefact.
I'm having problems with 'git push' and 'non-fast-forward merge' errors
How can I avoid stepping on people's toes when making changes?
See this page on interacting with git.