Git Advice

Overview

Git is an increasingly popular source code control tool which is the standard in the linux kernel development community and gaining popularity in many other projects. This documentation page will explain the use of Git commands as they correspond the subversion commands with which you are already familiar.

Git Access

Given that the subversion workflow is what the KUSP team is already familiar with this page will describe a use of Git which closely resembles that workflow. Other workflows are certainly possible and as use of Git for KUSP is established, changes may be made.

Since subversion uses a centralized repository, we will set up an equivelent Git repository, with branches and branch naming conventions representing the Public code, the KUSP internal Stable code, and the KUSP internal Unstable code. Individual repositories may clone or branch from either the Stable or Unstable branches as appropriate in developing new features. New code is first pushed into the Unstable branches, which is then pushed into the Stable branches as appropriate.

The Public branch contains the code we consider ready for public use. The Stable branches contain the code KUSP project members generally use internally but which not yet be considered ready for public use. The Unstable branches contains the code being developed into the next stable version.

We are using the Git protocol, rather than direct HTTP access. The Git protocol makes use of the SSH protocol, so you must have SSH installed on your work station and have an ITTC SSH account to access the KUSP Git repositories.

Note, however, we are looking into anonymous read-only access is supported through a Guest SSH account:

  • username: Guest (TBD)
  • password: Password (TBD)

The KUSP Git repositories are rooted at:

/projects/kurt/git/

Beneath this directory exist the main kernel repositories:

/projects/kurt/git/2.6.31
/projects/kurt/git/etc.

Each of these has the following internal layout:

/projects/kurt/git/2.6.31/vanilla

/projects/kurt/git/2.6.31/rt19
/projects/kurt/git/2.6.31/rt#

/projects/kurt/git/2.6.31/unstable/cd
/projects/kurt/git/2.6.31/unstable/pm
/projects/kurt/git/2.6.31/unstable/pm.cd
/projects/kurt/git/2.6.31/unstable/pm.cd.gsched

/projects/kurt/git/2.6.31/stable/*

/projects/kurt/git/2.6.31/public/*

The various kernel branches for each base version of the kernel are underneath the base kernel number (2.6.31). These include: vanilla, PREEMPT_RT, and various KUSP branches.

  • RT# : RT patch of corresponding #
  • CD : CCSM and DSKI on top of the RT patch
  • PM : Noah’s Proxy Management on top of the RT patch
  • PM.CD : Both of the previous patches together
  • PM.CD.GSCHED : Our full tree, adding Group Scheduling to the previous patches
The KUSP Git repositories may be browsed via the KUSP Trac interface at::
TBD

All of the KUSP user level software, including all of the tools, libraries, examples, and workspaces, will remain in SVN for the immediate future. To learn how to checkout the KUSP user level software, please follow the instructions found here:

Checking Out The Kernel

KUSP Kernel

You will need to build the current KUSP kernel and will most likely want to use one of our predefined configurations. After building the kernel you will want to build the rest of the KUSP software. The current kernel Git path components are:

kernel version = kusp-unstable

The Git command requires a few changes to your .ssh profile to properly access the Git repository through the ssh.ittc.ku.edu machine. The reason for this is that a non standard ssh port is used. You will need to add the following lines to your ~/.ssh/config file:

Host ssh.ittc.ku.edu
   User <ittc-username>
   Port 62
CAUTION: The SSH command is quite cautious in the interest of
security, so it will fail if the permissions on you ~/.ssh/config file are incorrect. The correct permissions seem to be RW for the owner and nothing for anyone else.

The Git command that will clone the repository for a given kernel base version is thus:

bash$ git clone ssh.ittc.ku.edu:/projects/kurt/git/<kernel version>

This clone the entire set of branches for the base kernel version chosen. It is important to note that the Git repository for a given kernel contains many branches and so the working directory is not yet in a usable state. In order to use the working directory we must choose which branch we wish to use and if we intend to make changes we should create a branch of our own. Thus, if we wish to work on 2.6.31.12-rt21-kusp we would first have to check what branch the working directory is set at. We list all branches available using:

bash$ cd <kernel version>
bash$ git branch -a

The output of this is the list of all available branches. The branch to which the current directory is currently set is marked by a ‘*’ in the first column. If the version you want is not already marked, then you need to switch the working directory to that version:

bash$ git checkout <desired-branch>

Now we need to create a unique branch to represent the changes made locally which can then be merged into the original branch using push or pull operations when the new code is ready:

bash$ git checkout -b 2.6.31.12-rt21-kusp-<user-name> \
           origin/2.6.31.12-rt21-kusp

The ‘-b’ indicates that we are creating a new branch and its argument is the new branch’s name. The last argument on the command line is the name of the branch from which the new branch is being made. Note that switching to the new branch is implicit with its creation but it is prudent to check that with:

bash$ git branch -a

Alternate ITTC Internal Network Method

Warning

Only use this method if you are comfortable with Git, SSH, and care enough about Git performance to want to keep track of additional details. All of our Git repository documentation assumes use of the SSH method.

There is an alternate way to access the Git repository directly via the NFS based file system path on machines connected to the ITTC network and mounting /projects. For such machines direct access to the repository is faster using the following command format:

bash$ git clone /projects/kurt/git/<kernel version>

This method is quite a bit faster, but has its own limitations. This should not be used on portable machines, such as a laptop, since outside the ITTC network you will not be able to pull and push changes for a branch cloned this way. The reason for this is that the Git repository cloned retains information about access so if you use an ITTC internal method to create the repository it will not work when the portable machine is not connected to the ITTC network.

KUSP Kernel Configurations

For the moment, our kernel configurations will remain in SVN for the immediate future. To learn how to checkout the kernel configurations, please follow the instructions found here:

Git Command Overview

Introductory Rhetoric

FIXME.j - need some discussion of the keywords remote and origin

Useful Commands

  • git –help : Lists the different subversion commands (recommended to use if unsure of command syntax/ functionality)
  • git help <command> : Help for the specific command entered

Initial Checkout

  • git clone <current stable kernel url> :

Branch

To see all available branches:

bash$ git branch -a

Note that if you have already checked out a branch, this command will also indicated which branch you are currently on by marking that branch with a * on the far left column.

To change to a particular branch:

bash$ git checkout <branch-name>

To create a new branch:

bash$ git branch <new-branch-name>

To delete a branch after merging it with Main:

bash$ git branch -d <branch-name>

To delete a branch without first merging with Main:

bash$ git branch -D <branch-name>

Working with a Remote Branch

To create a local copy of a remote branch, use the git clone command:

bash$ git clone <remote-url>

This does not, however, create work areas. Instead, it allows you to view the existing remote branches.

Using the standard branch listing command, you should see that all branches begin with the keyworkd remote and origin. To view only remote branches, use the following command:

bash$ git branch -r

Note that you see all of the remote branches, but now without the remote identifier, which is considered redundant in this context.

To begin working you will need to create a local branch. It is usually best to create a local branch which tracks the remote branch you wish to start from. This will set necessary internal variables that will make pulling and pushing updates simpler in the future:

bash$ git checkout --track -b <new-branch-name> origin/<remote-branch-name>

Note that the <remote-branch-name> is everthing AFTER the remote and origin keywords when viewing the list of available branches.

Adding and Removing Files from the Working Copy

Anytime a change is made to a file, or a new file is introduced, it must be added again for it to be committed to the repository. This prevents any accidental commits of unintended files. To add a file, use this command:

bash$ git add <path-to-file>

To move or rename a file already under git control, use this command:

bash$ git mv <path-to-file> <new-path-to-file>

To remove a file already under git control, use this command:

bash$ git rm <path-to-file>

Committing Changes to the Local Working Copy Repository

Committing changes (after you have been sure to re-add modified files) uses the following command:

bash$ git commit -m '<commit message>'

A message is required, and failure to provide one will attempt to launch your environments default text editor to give you a chance to write one. Failing to launch the editor or write a message will cause the commit to fail.

Further, if you know that all changes should be committed, rather than re-adding them incrementally with the git add command, you may use the following command:

bash$ git commit -a -m 'commit message'

This command only adds those files which were already under git control, and will automatically perform git rm for any missing files. Because of this last behaviour, this command should be used with great care, as it is quite easy to accidentally delete a file and have that change propagate into your repository.

Pulling Changes from a Remote Repository

Assuming you created your local branch to track a remote branch, and did so properly, this is as simple as:

bash$ git pull

If you did not do this, wish to be absolutely sure you are pulling from the correct remote branch, or even wish to pull updates from a different remote branch (noting that any different branch must share an origin, remote or otherwise, with your current branch) the command is:

bash$ git pull <local-branch-name> origin/<remote-branch-name>

Pushing Changes to a Remote Repository

Assuming you created your local branch to track a remote branch, and did so properly, this is as simple as:

bash$ git push

If you did not do this, wish to be absolutely sure you are pushing to the correct remote branch, or even wish to push updates to a different remote branch (noting that any different branch must share an origin, remote or otherwise, with your current branch) the command is:

bash$ git push <local-branch-name> origin/<remote-branch-name>

Evaluate/ Verify Changes

If you wish to review which branch you are currently working on, and any changes you have made, as well as any files modified, added, removed, or not currently under git control, the command is:

bash$ git status

Undo Changes

To undo uncommited changes to a specific file:

bash$ git checkout <file>

To undo all uncomimitted changes to the currently checked out local branch:

bash$ git reset --hard HEAD

Merge

To merge a local branch into the currently checked out local branch:

bash$ git merge <branch-name>

Resolving Conflicts

When a conflict occurs due to a merge, the conflicted files are marked where the conflict has occurred with these symbols:

>>>>>>>
=======
<<<<<<<

The conflict must be resolved by editing the file. To inform git that the conflict has been resolved use:

bash$ git add <file>