Guide to Using Git

From GlueXWiki
Jump to: navigation, search

Preface

  • This document is intended to contain the basic information needed for GlueX users and code developers to use git in the GlueX software environment. Many expert operations (e.g. making a tagged release) are excluded. Also, some shortcuts/features are skipped so as not to clutter this document.
  • The steps outlined here can be performed in the order as listed to set everything up properly and to use git.
  • This document has been distilled from information in the below references.

References

First-time Setup

  • The GlueX repositories are hosted on GitHub. See Mark's email about how to create an account on GitHub and how to join the "gluex" team on github: Link
  • Also, be sure to tell git your username and email so that it correctly attributes your commits to you. For example:
git config --global user.name "<username>"
git config --global user.email "<username>@jlab.org"

Creating a local clone of the repository

  • The first thing you need to do is to create a clone of the master repository on your local machine. The "git clone" command pulls all of the code, branches, etc. for the entire history of the project into the current, local directory.

Setup Philosophy

  • In general, you probably want to have several separate copies of the repository built simultaneously on your machine. For example, you may want to have a program running off of a tagged release, and meanwhile develop code separately on a different branch.
  • The (My) recommended way of doing this is to have a wholly separate clone of the repository for each tagged release, in addition to one clone of the repository used for code development.
  • Each new code development project (bug fix, feature addition, etc.) should have it's own code development branch in the development clone.
    • This way, you can switch between development projects/branches as needed, keeping them clean and separated from each other, and merge them back to the "master" branch individually when they're ready.
  • This setup isn't required, just my recommendation. Feel free to setup your system up as you see fit of course.

Examples

  • To create clones of the master repositories into the directories <mydir>:
# SIM-RECON
cd $GLUEX_TOP/sim-recon/
git clone https://github.com/jeffersonlab/sim-recon/ <mydir>

# HDDS
cd $GLUEX_TOP/hdds/
git clone https://github.com/jeffersonlab/hdds/ <mydir>

References

Creating & Switching Branches

  • In git, branches are simply pointers to different snapshots of the content of the git repository.
  • By default, the "master" branch is created on your local machine after performing "git clone," but it is not a special or unique branch. There is no inherent definition of a "trunk" in git like there is svn, just a series of branches.
  • However, for GlueX, we treat the remote, "origin," "master" branch of the sim-recon/hdds/etc. repositories (stored on Github) as the "trunk" from which we create tagged releases.
  • Also, there's no such thing as a revision number. Instead, each commit (and corresponding snapshot) is uniquely identified with a hash number.
  • "Checking out" a branch replaces the local files/folders with those in the new, current branch. Checking out a different branch is not possible if you have uncommitted changes in your current branch.

Examples

  • To create the branch <mybranch> (whose content will be identical to the current branch) (Note: you must still switch-to/checkout the branch to use it):
git branch <mybranch>
  • To show all of your branches, along with which branch you are currently using (marked by an asterisk (*)):
git branch
  • To switch-to/checkout the branch <mybranch> (this replaces the local files/folders of your current branch with those of the new branch):
git checkout <mybranch>
  • To create the branch <mybranch> (whose content will be identical to the current branch) and switch-to/checkout it all in one step:
git checkout -b <mybranch>

References

Checking out a Tagged Release

  • When you check out a tagged release, what you're really doing is you're creating a new local branch on your machine that looks exactly like the tagged release. See the example below.
    • If you intend to use this tagged release for frequent running, it is recommended that you create it with an entirely separate repository clone than your development repository, in order to keep the tagged release in a steady state.

Examples

  • To list the available tagged releases that are present in your local repository:
git tag
  • To check out a tagged release <mytag>, giving it a new branch name <mybranch>:
git checkout -b <mybranch> <mytag>

References

Adding files and/or Committing changes

  • There are two cases where you might want to commit changes: New content and changes to existing content. In both cases, you must first "stage" the change with "git add," before committing it with "git commit."
    • Note that any changes made after "git add" but prior to "git commit" will NOT be committed; run "git add" again on the changed files in order to re-stage them for committing.
    • When you run "git commit" the text editor defined by the environment variable $EDITOR will be launched for you to add commit comments.
  • These operations add/commit the changes to your current, active branch. See the following sections about merging branches and remote repositories to upload these changes to the GitHub repositories.

Terminology

  • Tracked/untracked files: Untracked files are files that have never been added to git (via git add). Tracked files are ones that have been previously added to git.

Examples

  • To stage a file/folder for the next commit to the current branch (and/or add a new file):
git add <myfile>
  • To commit all of the staged files/folders in the current folder to the current branch:
git commit
  • To commit all changes to "tracked" files/folders in the directory to the current branch (bypassing the "add" staging: similar to "svn commit"):
git commit -a

References

Removing Files

  • Use "git rm <myfile>" followed by "git commit" to remove files from the current git branch.

Examples

  • To remove the file/directory <myfile> from the current branch:
git rm <myfile>
git commit

References

Merging and Deleting Local Branches

  • Once you finish the project/feature/bugfix for which you created your current branch, you can merge those changes back to your local "master" branch by using the "git merge" command.
  • Since you've finished with this branch, you can then delete it using the "git branch" command.
  • For handling merging conflicts, see the "Basic Merge Conflicts" section of the git book: Link

Examples

  • To merge the changes committed to branch <my_work_branch> into the local branch <my_master_branch>:
git checkout <my_master_branch> # Switch to make the master branch active (you can skip this if it's active already)
git merge <my_work_branch> # Merge
  • To delete the branch <my_work_branch>
git branch -d <my_work_branch>

References

Updating from Remote Repositories

  • To retrieve updates that have been posted to the main GlueX repositories, type "git fetch origin." This updates your local repository, but doesn't update any of your local branches. You must still merge these changes into the branches that you want to update.
    • The "origin" remote repository is the repository that you cloned-from when you initialized your setup with "git clone."
  • Also see the section below on "Tracking Branches"

Examples

  • To list the remote repositories that your clone is connected to:
git remote -v
  • To update your local repository with information from the remote repository "origin" (does not change any of your local branches):
git fetch origin
  • To list all of the branches in the remote repository "origin" that your clone knows about (updated via "git fetch" above):
git remote show origin
  • To merge the changes from a branch in the remote repository "origin" <remote_branch> into one of your local branches <my_branch>:
git checkout <my_branch> # Switch to make this branch active (you can skip this if it's active already)
git merge origin/<remote_branch> # Merge remote branch into the active branch
  • If you are on a branch that is tracking a remote branch (e.g. the master branch), then you can simply call:
git pull
  • If you want to update your local branch <my_branch>, ignoring and overwriting any local edits:
git fetch --all
git reset --hard origin/<my_branch>

References

Tracking Branches

  • A "tracking" branch is a local branch that is directly linked to a specific remote branch. This makes it easier to update your local branch with changes that others have posted to the remote branch.
  • When you cloned the repository with "git clone," your local "master" branch was automatically created as a tracking branch with respect to the "master" branch in the "origin" repository.

Examples

  • To create a local tracking branch <mybranch> that tracks the remote branch <remote_branch> on "origin:"
git checkout -b <mybranch> origin/<remote_branch>
  • To create a local tracking branch that has the same name as the remote branch <remote_branch> on "origin:"
git checkout --track origin/<remote_branch>
  • When a local tracking branch is active, to merge the contents of the remote branch into the local branch:
git pull
  • To have an existing local branch track an existing remote branch:
git branch --set-upstream <my_branch> origin/<remote_branch>

Pushing to Remote Repositories

  • In order for other collaborators to see/use your changes, you must "git push" the branch that contains them to the "origin" GlueX repositories stored on GitHub.
    • The "origin" remote repository is the repository that you cloned-from when you initialized your setup with "git clone."
  • Once you've uploaded (pushed) your branch, in order to update the "master" branch, you need to create a "pull request" on GitHub. This sends an email out to everyone in the group, and one of them will need to accept your changes for them to be incorporated into the "master" branch.
  • Once your changes have been incorporated into the "origin/master" branch on GitHub, you probably want to delete the remote and local branches you used.

Examples

  • Push a local branch <my_local_branch> that contains your changes up to the GlueX "origin" repository on GitHub, changing the branch name to <my_new_remote_branch>:
git push origin <my_local_branch>:<my_new_remote_branch>
  • To have your local branch now track the remote branch:
git 1.8, branches have same name: git branch -u origin/<my_local_branch>
git 1.8, branches have different names: git branch -u origin/<my_new_remote_branch> <my_local_branch>
git 1.7: git branch --set-upstream <my_local_branch> origin/<my_new_remote_branch>
  • Issue a pull request: See Step 6 in Mark's guide at: Link
  • To act on a pull request: See Step 7 in Mark's guide at: Link
  • To delete the branch <my_new_remote_branch> that you created on the GlueX "origin" repository on GitHub:
git push origin --delete <my_new_remote_branch>

Error Fix

  • I've had problems pushing my changes back up to GitHub, receiving the following error:
error: The requested URL returned error: 403 Forbidden while accessing https://github.com/jeffersonlab/sim-recon//info/refs
  • I was able to fix this by doing the following:
cd $HALLD_HOME
git remote set-url origin https://<my_github_username>@github.com/JeffersonLab/sim-recon.git
cd $HDDS_HOME
git remote set-url origin https://<my_github_username>@github.com/JeffersonLab/hdds.git

References

EXAMPLE SESSIONS

Getting Started and Checking out Tagged Releases

  • HDDS (Tagged release 3.3)
cd $GLUEX_TOP/hdds/
git clone https://github.com/jeffersonlab/hdds/ hdds-3.3   # Makes a clone of the hdds repository into a folder called "hdds-3.3"
cd hdds-3.3
git checkout -b 3.3 hdds-3.3                               # Checks out tagged release "3.3" into a branch named "hdds-3.3" and switches to it
  • sim-recon (Tagged release 1.4.0)
cd $GLUEX_TOP/sim-recon/
git clone https://github.com/jeffersonlab/sim-recon/ sim-recon-1.4.0   # Makes a clone of the sim-recon repository into a folder called "sim-recon-1.4.0"
cd sim-recon-1.4.0
git checkout -b 1.4.0 sim-recon-1.4.0                                  # Checks out tagged release "1.4.0" into a branch named "sim-recon-1.4.0" and switches to it

Setting up a Code Development Branch

cd $GLUEX_TOP/sim-recon/
git clone https://github.com/jeffersonlab/sim-recon/ development   # Makes a clone of the sim-recon repository into a folder called "development"
cd development
git pull                                                           # Updates the active "master" branch with the latest changes in the remote master branch "origin/master"
git checkout -b my_bug_fix                                         # Create the branch "my_bug_fix" (with same content as (active) "master" branch) and switch to it

Committing Changes to the Local and Origin Repositories

git commit -a                           # Commit all changes to the (active) "my_bug_fix" local branch
git push origin my_bug_fix:my_bug_fix   # Push the "my_bug_fix" local branch to the GlueX repository on GitHub
git branch -u origin/my_bug_fix         # Optional: Your local branch will now track the remote branch (can pull changes with 'git pull')
  • Issue a pull request on GitHub: See Step 6 in Mark's guide at: Link
  • To act on someone else's pull request on GitHub: See Step 7 in Mark's guide at: Link

Cleanup Once Changes Have Been Accepted

git push origin --delete my_bug_fix   # Delete the remote branch you created on the GlueX "origin" repository on GitHub
git checkout master                   # Switch back to your local "master" branch
git branch -D my_bug_fix              # Delete the local branch you created
git pull                              # Update your local "master" branch with your (and others') changes

Revert to Previous Commit, Deleting Current Workspace Changes

git log                               # Git hash #'s of previous commits (e.g. f07e19cd4cb9dc1cb66150d71308f3ad045b264a)
git reset --hard my_hash              # Revert to previous commit with hash "my_hash," deleting local changes