Common Git Tasks

Overview

This page describes common tasks a developer performs using Git.  Throughout, I will use the GMAT Git repository location ssh://djconway@gs-mesajade.gsfc.nasa.gov/home/GMAT/git/gmat.git.  

When you work in Git, there are a few key things to know. 

Your Git clone is a full repository

You make a forking repository using Git's Clone command.  Clone places a full copy of the repository on your hard drive.  Unlike Subversion or CVS, Git lets you work directly in the full repository.  Updates to the development repository merge your local repository changes into the development repository.  This feature has several implications for your local work flow:

  • Pull before Pushing  You are working in a full repository.  Generally speaking, when you are ready to push new code to the GMAT development repository, you should pull the code from the dev repo first.  This is similar to good work flow on Subversion: update code before committting.  With Git, you'll find that the system is a bit more stringent about enforcing this work flow because the push process is essentially a merge of two separate repositories into one.
  • Commit frequently!  Since you have a local repository, you can commit code often without affecting other team members.  That means that rather than collecting a big collection of files and then making a massive commit, you can commit as each piece of your work is finished.  Then when you push your updates to the development repository, all of your local commits will be passed to the dev repository along with their individual commit messages.  Frequent commits (with log messages that are explanatory) will make it easier to track how a given file change affects the rest of GMAT. 

Git Commits are a Two Step Process

(This piece is adapted from the book Pro Git, by Scott Chacon.  The entire book is available here.)

Git views files as being in one of 3 states:

  1. Committed Files: These are files that are incorporated into the repository.
  2. Edited Files: Files that you have changes but not yet passed to Git.
  3. Staged Files: Files that you have told Git you intend to add or update to the repository that have not yet been added. 

The User's Machine box of Figure 1 shows how Git views the files and local repository that you will be using for typical development tasks.

Figure 1: Repository - File Interactions


When you create your working repository in Git using the clone command, the development repository is copied to your computer, and that repository is used to create a working directory system.  The working directory created this way contains copies of the committed files  You then make changes to files in the working directory.  The files that you change (or add) are then in the edited state.  You can then stage these files by telling Git that the file is ready to be committed using the add command.  The repository does not yet contain files that have been staged, but they are treated by Git as being in a local staging area.  The files are migrated into the repository using the commit command.  Files that have been committed are configuration managed in your local repository; a commit does not make the file available to other developers.

The Local Repository is not the Team Repository 

You make your local repository using the Git clone command. Clone makes a local copy of the full repository and uses that repository to create the working directory file system.  You then work in the working directory on a day by day basis.

When you are ready to make the files available to the rest of the team, you send them to the development repository using the push command.  This command merges your local repository into the development repository, making your changes available for other team members to retrieve.  This process is shown in the figure as the blue arrow labeled "Push."

You pick up changes from other team members using the pull command, shown as the yellow "Clone / Pull" arrow in the figure.  This command merges the development repository into your local clone, and then uses the local clone to update the files in your working directory system.

The following sections show how to use each of these commands in your daily work.  Each example is illustrated using the command line interface, TortoiseGit, and SmartGit.

First Steps

Before using Git, there are a few steps you will need to perform to prepare your computer.  This section describes those steps.

Install a Git Client

You will need a Git client installed before you can use Git.  There are several options available for Git clients, depending on your preferences and operating system.  The following instructions include examples using command line Git, TortoiseGit with git-gui, and SmartGit/Hg.  The following table contains links to these products:

ProductWindowsMacLinux
Command line Gitmsysgit - Includes git-guiInstalls with XcodeInstalled from the OS Package manager
TortoiseGit

Requires msysgit (or other command
line client)

Not available - Windows onlyNot available - Windows only
SmartGit/HgAvailableAvailableAvailable

The links in the table take you to the corresponding product pages, which include installation instructions.

Set some Git global environment variables

Before proceeding further, you should set up your Git identity.  You do this with the following commands – please replace Your Name and the e-mail address with your data; keep the quotes around your name when you make that substitution.

git config --global user.name "Your Name"
git config --global user.email your.email@email.server

When you update the central repository, GIt provides several options for the way changes are delivered.  Most of the time you will want to push your code updates for the current branch of the code you are using.  Git 1.x tries to push updates from all of the repository branches.  Git 2.0 changes that default to just push commits from the branch you are currently using, which is the preferred approach for the GMAT team.  You set this preference with the command

git config --global push.default simple

Cloning the Repository

The first task you need to do when working with GMAT's Git repository is to make a local copy of the repository.  This task is accomplished using the clone command.  The repository is located on the gs-mesajade server behind the GSFC firewall.  I'll use my NDC username, djconway, for this step.  Replace my username with your own.  

You clone the repository from the command line into the folder GmatDevelopment using the command (shown here, and throughout, as copied from a Mac Terminal window)

$ git clone ssh://djconway@gs-mesajade.gsfc.nasa.gov/home/GMAT/git/gmat.git GmatDevelopment

 When you issue this command, you'll see the following response:

Cloning into 'GmatDevelopment'...
               !!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!
      This U.S. Government resource is for authorized use only.
      If not authorized to access this resource, disconnect now.
   Unauthorized use of, or access to this resource may subject you to
            disciplinary action or criminal prosecution.
      By accessing and using this resource, you are consenting to
            monitoring, keystroke recording or auditing
               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
djconway@gs-mesajade.gsfc.nasa.gov's password: 

Enter your password, and the clone process will start.  This will take a few minutes to a couple of hours to complete.  (It took over four hours for me across VPN.  Hopefully, your results will vary!)  Here is a snapshot of the terminal window partway through the clone:

djconway@gs-mesajade.gsfc.nasa.gov's password: 
remote: Counting objects: 76796, done.
remote: Compressing objects: 100% (26586/26586), done.
Receiving objects:  11% (8560/76796), 125.05 MiB | 482 KiB/s    

If you are running on Windows using TortoiseGit, you can make the repository clone as follows:

  • Open Windows Explorer
  • Changing the current folder to the target location for the repository
  • Right click in the Explorer window
  • Select "Git Clone..."  from the pop-up window
  • Enter the following URL: ssh://djconway@gs-mesajade.gsfc.nasa.gov/home/GMAT/git/gmat.git (replacing djconway with your NDC user name)
  • Click the Browse button and locate the target folder.   Tortoise will append a "gmat" to the folder name; change it if you have a dufferent preferred folder name for your GMAT repository.  (I use "GmatDevelopment.")

You should see the following panel:

Figure 2: The TortoiseGit clone screen

Press the OK button, and the clone process will begin.  You will be prompted to enter your NDC password, and then a Git Command Progress panel will open showing you information similar to the terminal window output shown above.

If you are using SmartGit/Hg (my tool of choice), you create the clone by opening SmartGit/Hg and following these steps:

  • Start SmartGit/Hg
  • If this is the first time you've run the program or if you don't have any existing Git configurations in SmartGit, a Welcome screen will open with options to "Open an existing local or create a new repository" or to "Clone and existing repository."  Select the Clone option.  If you have an existing Git configuration in SmartGit/Hg, select "Clone..." from the "Project" node on the menu bar.
  • SmartGit/Hg's Clone wizard will open.  Enter the following repository URL in the Remote Git, Mercurial or SVN repository field:
    ssh://djconway@gs-mesajade.gsfc.nasa.gov/home/GMAT/git/gmat.git  (replacing djconway with your NDC user name)
  • Press the "Next >" button.  You might be asked to accept an SSH server fingerprint.  Accept it.
  • An SSH Authentication" panel will open.  For Authentication Type, select Password and enter your NDC password.  Press the button to apply your password.
  • The Selection panel will open.  Keep the default settings and press the "Next >" button.
  • Set the local directory path for your repository and press the "Next >" button.
  • Set the project name you want to use to identify the repository in SmartGit.Hg, and press the "Finish" button.  

SmartGit/Hg will start the cloning process, and report progress in its "Output" panel and in the status bar on the bottom of the SmartGit/Hg window, as shown in FIgure 3.

Figure 3: Cloning in SmartGit/Hg

Committing a Code Change: Local Commits

The Git commit process is a two-stage process, as described above.  Once files are ready to be committed, they are moved into a staging area that preserves their state until a commit is performed.  This action is performed using the "add" command.  Files are committed into your local repository using the "commit" command.  The commit command includes an option to combine both of these steps into a single command.

While setting up the Git repositories, I added settings to ignore a number of folders and files by constructing .gitignore files in the folders that needed them.  I'll illustrate the local commit of these files using the two step process.  

Determining the state of the changes

Before you commit a change, you need to know the files that have been changed.  Git provides a "status" command that can be used to list the states of files that are not yet tracked in the repository.

Working from the command line, you can determine the status of your working files by typing "git status" from your top level repository folder.  For example, if it run this from the Windows command line:

C:\gsfcgit\GmatDevelopment>git status

 then I see this output after adding some of my .gitignore files to the staging area:

Figure 4: Running "git status" in the Windows command prompt


If you are using TortoiseGit, Windows Explorer will mark new files with a small question mark ("?") icon badge, and edited files and folders with an exclamation point, "!".  Staged files get a plus sign, "+".  You can see the status of all of the files in the repository by opening the TortoiseGit Gui (right click in a folder in your repository and select "Git Gui" from the popup menu).  The Gui panel for the files shown above looks like this:

Figure 5: Git Status in TortoiseGit

SmarGit/Hg shows the status of new and changed files in under the Files tab on its main window:

Figure 6: Git Status in SmartGit/Hg

Staging the Change 

You stage files from the command line with the add command.  You can do this on a file-by-file basis:

git add application/bin/.gitignore
git add application/debug/.gitignore
git add application/plugins/.gitignore
...

 or by using wildcards for specific folders:

git add application/*/.gitignore
...

global wildcards:

git add *

(be careful with this option because you may end up adding files that do not belong in the repository)

or using the add interactive option:

git add -i

illustrated here with the sequence 

  • git add -i
  • a
  • *
  • q

Figure 7: Git Add Interactive from the Windows command prompt 

The GUI based tools are a bit simpler for the staging options.  In TortoiseGit, you can stage files from the Git GUI by selecting the file or files you want to stage from the "Unstaged Changes" panel and selecting "Stage to Commit" from the "Commit" item on the menu bar.  This action stages the files, and shows that change by moving files from the "Unstaged Changes" list into the "Staged Changes (Will Commit)" list on the gui.  The result of doing this for the three .gitignore files in the application folder looks like this:

Figure 8: Staging three files in TortoiseGit

Using SmartGit/Hg, the staging status is indicated by the Index column and the Working Tree State column in the GUI.  You stage files by selecting an Untracked or Edited file in the Files list, then pressing the Stage button on the toolbar.  This sent the Add command to git, and reflects the change in the file table, as shown after staging three more files here:

Figure 9: Staging six files in SmartGit/Hg

Staged files are not yet part of your local repository.  To add the files to the repository, they must be committed, as described in the next section.

Committing the Code

Once you have staged files, you commit them with the commit command.  From the command line, you just type

git commit -m "Put a meaningful message here"

 Git responds by reporting the process on the commit process, as shown in Figure 10:

Figure 10: A local commit 

From TortoiseGit, you enter a commit message in the "Commit Message" panel and commit the staged files by pressing the Commit button.  Figure 11 shows a commit in progress.

Figure 11: A TortoiseGit Commit

SmartGit/Hg has a dedicated panel used for the commit process, and provides a fine grained approach to making commits.  First select a folder in the Directories panel of the SmartGit/Hg gui, then either right click on that directory and select "commit," or press the Commit button on the toolbar.  Alternatively, you can activate it by selecting one or more files in the Files panel, right clicking, and then selecting "Commit" from the popup menu. The resulting panel lets you select on a file-by-file basis the files that you are adding to the repository.  You select or deselect files using the checkbox next to the file's name, enter a commit message, and then press the Commit button.  The SmartGit/Hg commit panel is shown in Figure 12.

Figure 12: Committing files in SmartGit/Hg

Staging and Committing in One Step

Git allows you to stage and commit files in a single step for files that have previously been added to the repository.  You do this by adding the -a flag to the commit command on the command line.  So if we had edited the application/bin/.gitignore file that was committed earlier, we could skip the staging area from the command line using the command

git commit -a -m "Added ignore for the file foo.bar" application/bin/.gitignore

to commit the change to the file into the repository.  The gui tools provide similar capabilities.  (Note: I know this is the case for SmartGit/Hg.  Does Tortoise also let you skip staging?)

Pulling Updates from the Development Repository

Everything presented above after the clone section involves actions taken and changes that have been made to your local repository.  If another user of the repository has made changes, you do not have their changes locally until you fetch those changes from the repository on gs-mesajade and merge them into your local repository.  The words "fetch" and "merge" were chosen carefully here – the pull process used in git is actually a two step process.  First git executes a command to retrieve updates from a remote repository – the GMAT repository on gs-mesajade for us – using the git fetch command, and then it merges those changes into the working directory using the merge command.  This process is combined into a single "pull" command that you will use when performing day-to-day tasks.  The procedure for executing the pull process is described in this section.

When working from the command line, the pull command is simple:

git pull

A pull operation will ask for your password, and then retrieve and merge the changes into your local file system.  On windows a command line pull looks like this:

Figure 13: Pulling changes into a repository

A pull is executed on TortoiseGit from Windows Explorer by right clicking in a repository fielder, selecting "TortoiseGit > Pull..." from the popup menu, and then pressing the OK button on the resulting panel, shown in Figure 14.

Figure 14: The TortoiseGit Pull panel

The pull command is executed in SmartGit/Hg by pressing the "Pull" button on the toolbar.  This opens a dialog showing the location of the remote repository and options to pull updates, or to fetch them without the merge step.  Press the "Pull" button to complete the action.

Pushing a Change to the Development Repository

Before pushing changes to the remote repository on gs-mesajade, always pull the updates others have committed first.  You will forget to do this from time to time, and receive annoying messages about a failed push command as a result.

The push command is used to send updated code from your local repository to the remote repository, so that the rest of the team can use your code updates.  The process from the command line is straightforward:

git push

and results in messages telling you what happened:

Figure 15: Pushing local changes to the central repository

In TortoiseGit, you push changes by opening WindowsExplorer, right clicking in a repository folder, and selecting "TortoiseGit > Push..." from the popup menu.  The Pressing the "OK" button on the resulting dialog (Figure 16) initiates the push command.

Figure 16: Pushing Changes using TortoiseGit

In SmartGit/Hg, repository pushes are launched by pressing the "Push" button on the toolbar.  This button opens a panel that lets you select between pushing either your current branch or all "matching" branches to the remote repository.  (Branching is discussed on the Branching Strategy page.)

Examining the Log

 

Using SSH Authentication on Windows

The Windows git client can be configured to use SSH authentication instead of password-based authentication. This is useful for avoiding password prompts during remote operations (clone, pull, push, etc.).

Official Client or TortoiseGit

The official Git client and TortoiseGit can either use PuTTY or OpenSSH for SSH authentication. This guide configures OpenSSH. To use PuTTY, take a look at the TortoiseGit help.

  1. Configure TortoiseGit to use OpenSSH:
    1. Right-click an empty part of your Desktop, point to TortoiseGit, and click Settings.
    2. In the left column, click Network.
    3. In the SSH client box, type ssh.exe (no path).
    4. Click OK.
  2. Remove any old GIT_SSH environment variables:
    1. In Windows, click the Start button and type "environment". Click Edit environment variables for your account.
    2. In the upper box, look for a line that starts with "GIT_SSH". If one exists, click it and click Delete.
  3. Create your SSH key:
    1. In Windows, click the Start button and start Git Bash (All Programs > Git > Git Bash).
    2. Type ssh-keygen and press Enter.
    3. Press Enter to accept the default filename (C:\Users\username\.ssh\id_rsa).
    4. Press Enter twice to generate a key with no passphrase. We're relying on other security mechanisms (like your computer login) here. You can use a passphrase here if you want, but you'll need to type it in each time you perform a remote operation.
    5. Navigate to C:\Users\username\.ssh to view your new keys. You'll see id_rsa (your private key) and id_rsa.pub (your public key).
    6. Open id_rsa.pub in a text editor (e.g. Notepad) and copy the entire contents.
  4. Save your SSH key on gs-mesajade:
    1. In the Git Bash window, run:
      ssh username@gs-mesajade
    2. If you get an authenticity message, type "yes" and press Enter to continue.
    3. Run:
      mkdir .ssh
      cd .ssh
      vi authorized_keys
    4. Press "i" to start inserting text.
    5. Right-click inside the Git Bash window to paste the copied key.
    6. Press ESC and type ":wq" to quit vi.
    7. Type exit and press Enter.
  5. Navigate to a git repository and run "git pull" to test the connection. A password prompt should not appear. Test again with TortoiseGit if desired.

SmartGitHg

Looking for content...