Git

Installing Git

http://git-scm.com/book/en/Getting-Started-Installing-Git

Git Setup

Git comes with a tool called git config that lets you get and set configuration variables that control all aspects of how Git looks and operates. These variables are stored in ~/.gitconfig file which is specific to your account. You can make Git read and write to this file specifically by passing the --global option:

$ git config --global color.diff auto
$ git config --global color.status auto
$ git config --global color.branch auto
$ git config --global user.name "User Name"
$ git config --global user.email user.name@example.com
$ git config --global core.editor "gedit -w"
$ git config --global merge.tool meld

If you want to check your settings, you can use the git config --list command to list all the settings Git can find at that point:

$ git config --list
color.diff=auto
color.status=auto
color.branch=auto
user.name=User Name
user.email=user.name@example.com
core.editor=gedit
merge.tool=meld

You can also check what Git thinks a specific key’s value is by typing git config {key}:

$ git config user.name
User Name

Getting developper/write access

GATE code repository currently lives at gitolite@imnctrunch.in2p3.fr. You will need a gitolite access account to access it.

If you don't have an account yet, send an e-mail to dubois@imnc.in2p3.fr with your desired username and SSH public key. There are no passwords; all authentification is via SSH public keys.

Generating a key pair on your workstation is done by running the command ssh-keygen -t rsa -f username. This produces two files in your ~/.ssh. One is username; this is the private key -- never let it out of your machine. The other is username.pub, which is the corresponding public key to send by e-mail. This public key is usually just one long line of text.

Then, just to make it easy to, you have to give your machine an SSH alias, by adding some config under your ~/.ssh/config file.

Edit or create a ~/.ssh/config file and add the following lines :

Host gitopengate
User gitolite
Hostname 134.158.199.140
Port 2221
IdentityFile /home/username/.ssh/username

Lastly, check your gitolite access account works properly by typing :

$ ssh gitopengate

If everything's fine, this command line should return the following message :

PTY allocation request failed on channel 0
hello username, this is gitolite@imnctrunch running gitolite3 v3.2-11-gf1c69a3 on git 1.7.0.4
R W opengate
R W testing
Connection to 134.158.199.140 closed.

Cloning (checking out) GATE code remote repository

If you want to get a copy of the GATE code repository, the command you need is git clone.

If you’re familiar with other VCS systems such as Subversion, you’ll notice that the command is clone and not checkout. This is an important distinction — Git receives a copy of nearly all data that the server has. Every version of every file for the history of the project is pulled down when you run git clone. In fact, if your server disk gets corrupted, you can use any of the clones on any client to set the server back to the state it was in when it was cloned.

$ git clone gitopengate:opengate.git

This command creates a directory named opengate, initializes a .git directory inside it, pulls down all the data for that repository, and checks out a working copy of the latest version. If you go into the new opengate directory, you’ll see the project files in there, ready to be worked on or used. If you want to clone the repository into a directory named something other than grit, you can specify that as the next command-line option:

$ git clone gitopengate:opengate.git myrepository

That command does the same thing as the previous one, but the target directory is called myrepository.

Recording changes to the local repository

Adding a new file

Right after the cloning process, you have a local Git repository and a checkout or working copy of the files for that project. You are now able to make some changes and commit snapshots of those changes into your local repository each time the project reaches a state you want to record. The commands to use are the following:

echo '# New build system!' > CMakeList.txt
git status See the status of files in the working directory
git status -s The same in format familiar to SVN users
git add CMakeList.txt Add a new file to be tracked by Git
git commit -m “Commit message” Commit the changes (the file addition)
git log View the commit history

Editing a file and committing the changes

echo '#more stuff' >> CMakeList.txt Change the file
git status See that the file is now "dirty"
git diff See the changes
git commit -a -m “Commit message” Commit all changes (don't forget the -a!)

Working with remote

To be able to collaborate on OpenGATE project, you need to know how to manage the GATE code remote repository. Collaborating with others involves managing this remote repository and pushing and pulling data to and from them when you need to share work.

Showing your remote

To see which remote servers you have configured, you can run the git remote command. It lists the shortnames of each remote handle you’ve specified. If you’ve cloned your repository, you should at least see origin — that is the default name Git gives to the server you cloned from:

$ git clone gitopengate:opengate.git
Cloning into 'clone'...
remote: Counting objects: 5458, done.
remote: Compressing objects: 100% (2364/2364), done.
remote: Total 5458 (delta 3065), reused 5445(delta 3061)
Receiving objects: 100% (5458/5458), 229.30 MiB | 11.23 MiB/s, done.
Resolving deltas: 100% (3065/3065), done.


$ git remote
origin

You can also specify -v, which shows you the URL that Git has stored for the shortname to be expanded to:

$ git remote -v
origin gitopengate:opengate.git (fetch)
origin gitopengate:opengate.git (push)

Fetching and pulling from your remote

As you just saw, to get data from your remote project, you can run:

$ git fetch origin

The command goes out to that remote project and pulls down all the data from that remote project that you don’t have yet. After you do this, you should have references to all the branches from that remote, which you can merge in or inspect at any time.

If you clone a repository, the command automatically adds that remote repository under the name origin. So, git fetch origin fetches any new work that has been pushed to that server since you cloned (or last fetched from) it. It’s important to note that the fetch command pulls the data to your local repository — it doesn’t automatically merge it with any of your work or modify what you’re currently working on. You have to merge it manually into your work when you’re ready.

If you have a branch set up to track a remote branch (see the next section), you can use the git pull command to automatically fetch and then merge a remote branch into your current branch. This may be an easier or more comfortable workflow for you; and by default, the git clone command automatically sets up your local master branch to track the remote master branch on the server you cloned from. Running git pull generally fetches data from the server you originally cloned from and automatically tries to merge it into the code you’re currently working on.

Pushing to your remote

When you have your project at a point that you want to share, you have to push it upstream. The command for this is simple: git push [remote-name] [branch-name]. If you want to push your master branch to your origin server (again, cloning generally sets up both of those names for you automatically), then you can run this to push your work back up to the server:

$ git push origin master

This command works only if you cloned from a server to which you have write access and if nobody has pushed in the meantime. If you and someone else clone at the same time and they push upstream and then you push upstream, your push will rightly be rejected. You’ll have to pull down their work first and incorporate it into yours before you’ll be allowed to push.

See the next sessions for more detailed information on how to push to GATE remote server.

Inspecting a Remote

If you want to see more information about a particular remote, you can use the git remote show origin command. If you run this command with a particular shortname, such as origin, you get something like this:

$ git remote show origin
* remote origin
Fetch URL: gitopengate:opengate.git
Push URL: gitopengate:opengate.git
HEAD branch (remote HEAD is ambiguous, may be one of the following):
develop
master
Remote branches:
develop tracked
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)

It lists the URL for the remote repository as well as the tracking branch information. The command helpfully tells you that if you’re on the master branch and you run git pull, it will automatically merge in the master branch on the remote after it fetches all the remote references. It also lists all the remote references it has pulled down.

This command shows which branch is automatically pushed when you run git push on certain branches. It also shows you which remote branches on the server you don’t yet have, which remote branches you have that have been removed from the server, and multiple branches that are automatically merged when you run git pull.

Remote branches and development model

At the core, GATE's development model is greatly inspired by existing models out there. The GATE remote repository holds two main branches with an infinite lifetime:

  • master
  • develop

We consider the remote origin/master branch to be the main branch where the source code always reflects a production-ready state.

We consider the remote origin/develop branch to be the branch where the source code always reflects a state with the latest delivered development changes for the next release. Some would call this the “integration branch”.

When the source code in the develop branch reaches a stable point and is ready to be released, all of the changes should be merged back into master somehow and then tagged with a release number. How this is done in detail will be discussed further on.

Therefore, each time when changes are merged back into master, this is a new production release by definition.

Permissions

GATE code remote repository is managed using gitolite. Gitolite is an authorization layer on top of Git, relying on sshd for authentication. There are two main groups of users, @leaders and @staff, with varying degrees of permissions over the repository.

As a simple contributor, you are automatically added to @staff group. You have read-access (git clone / git fetch / git pull) to the whole GATE code remote repository, including master and develop branches, but you have write-access (git push) only to the develop branch.

Only @leaders group has write-access to the remote master branch.

Git step-by-step workflow


$ git clone gitopengate:opengate.git
Cloning into 'clone'...
remote: Counting objects: 5458, done.
remote: Compressing objects: 100% (2364/2364), done.
remote: Total 5458 (delta 3065), reused 5445(delta 3061)
Receiving objects: 100% (5458/5458), 229.30 MiB | 11.23 MiB/s, done.
Resolving deltas: 100% (3065/3065), done.


$ git branch #List local branches
* master


$ git branch -r #List remote branches
origin/HEAD -> origin/master
origin/develop
origin/master


$ git branch -a #List all branches (both local and remote)
* master
remotes/origin/HEAD -> origin/master
remotes/origin/develop
remotes/origin/master

As you can see, when you clone a repository, it generally automatically creates a local master branch that tracks remote origin/master. That’s why git push and git pull work out of the box with no other arguments. However, you can set up other tracking branches if you wish — ones that don’t track the master branch.

Checking out a local branch from a remote branch automatically creates what is called a tracking branch. Tracking branches are local branches that have a direct relationship to a remote branch. If you’re on a tracking branch and type git push, Git automatically knows which server and branch to push to. Also, running git pull while on one of these branches fetches all the remote references and then automatically merges in the corresponding remote branch.

To track remote develop branch, type :

$ git checkout -b develop origin/develop
Branch develop set up to track remote branch develop from origin.
Switched to a new branch 'develop'


$ git branch
*develop
master


$ git branch -r
origin/HEAD -> origin/master
origin/develop
origin/master


$ git branch -a
* develop
master
remotes/origin/HEAD -> origin/master
remotes/origin/develop
remotes/origin/master


$ git remote show origin
* remote origin
Fetch URL: gitontrunch:opengate.git
Push URL: gitontrunch:opengate.git
HEAD branch: master
Remote branches:
develop tracked
master tracked
Local branches configured for 'git pull':
develop merges with remote develop
master merges with remote master
Local refs configured for 'git push':
develop pushes to develop (up to date)
master pushes to master (up to date)

Next to the main branches master and develop, you can use a variety of supporting and purely local branches to aid parallel development between team members, ease tracking of features, prepare for production releases and to assist in quickly fixing live production problems. The essence of these branches is that it exists as long as the feature is in development, but will eventually be merged back into develop (to definitely add the new feature to the upcoming release) or discarded (in case of a disappointing experiment). Unlike the main branches, these branches always have a limited life time, since they will be removed eventually.

In any case, these branches may branch off from develop and must merge back into develop. Branch naming convention: anything except master and develop.

Note that, these branches typically exist in developer's local repository only, not in origin server.

When starting work on a new feature, creating a local branch by branching off from the develop branch.

$ git checkout -b myfeature develop
Switched to a new branch "myfeature"

Finished features may be merged into the local develop branch definitely add them to the upcoming release:

$ git checkout develop #Check out the branch you wish to merge into
Switched to branch 'develop'


$ git merge myfeature #Merge your myfeature work into local develop branch


$ git branch -d myfeature #Delete the myfeature branch, because you no longer need it — the master branch points at the same place


$ git push origin develop #Push develop branch commits up to the server (in develop branch)

Summary

Guessing you have followed the above-mentioned instructions, you have in our local repository three branches : two local master and develop branches set up to respectively track the remote master and develop branches on the server you cloned from, and a purely local branch named myfeature.

To commit into your local repository a file modified on your develop branch (reminder: developing directly on the master branch is not recommended), you will have to type:

$ git add FileModified.cc
$ git commit -m “Commit message”

Then, to push these modifications to the remote repository, and hence make the changes available to everyone (they become a part of official GATE code) you will have to type :

$ git push origin develop

This command works only if you cloned from a server to which you have write access and if nobody has pushed in the meantime. If you and someone else clone at the same time and they push upstream and then you push upstream, your push will rightly be rejected. You’ll have to pull down their work first and incorporate it into yours before you’ll be allowed to push.

To get your modifications, another contributor will have to type (in his develop branch):

$ git fetch origin
$ git merge origin/develop

or simply,

$ git pull

which generally fetches data from the server you originally cloned from and automatically tries to merge it into the code you’re currently working on.