git with sipXecs

Table of Contents

Getting source

Downloading the source

Installing git

Since git is used by Linux kernel developers it's easily available on most modern distributions. If you use, say, Fedora, run this (as root) to install the git distributed version control system:

yum install git*

This is a crude way to perform such an installation, and will install many possibly unwanted packages.

More elegant is to install just what is sought, to avoid over-filling a development environment with un-needed and potentially unwanted packages:

yum install git

If you are using CentOS you may wish to add and temporarily enable the EPEL repository before installing git via yum. More information here Alternatively, more current git RPM packages are available here from the primary 'upstream' for the development of git

Branching

Let's develop a new 'super' features. You should never write new code develop new code against the release-4.6 branch. In the mirror source code repository, release-4.6 is used only to provide a record of the former subversion mainline.

To write new code, create a new branch and check it out. (Since the branch is local, creating a new branch takes only a second or two).

git checkout -b super-feature

Option -b means that you are creating a new branch and checking it out. If you later want to switch to this branch, run the same command without a -b option. 'git checkout' is similar to 'svn switch' (not to 'svn checkout').

You can make some changes now using your favorite editor

Once you happy with your changes, and they pass your local testing, commit them. You'll be only checking in to your local git repository, so commit early, commit often.

git commit -a

Option -a means that you want to add all changed files to the commit. Alternatively you can run

git add

and add the files one by one, or on a directory by directory bases. Differently than in subversion, when using git you must tell it explicitly which files you are committing.

Git is more liberal and forgiving than subversion. You can amend a commit later if you forgot about something. You can even rewrite the history several commits back, as long as you did not externally share your changes with any other archive.

Generating patches

Before you generate a patch against release-4.6, it's a good idea to rebase release-4.6 against the git mainline and then rebase your branch against a fresh copy of: release-4.6

  • Switch to active development release-4.6 branch
git checkout release-4.6

 

  • Retrieve the latest commits from git repo:
git svn rebase

 

  • Switch to your feature branch:
git checkout super-feature

 

  • Rebase your branch against the active development branch release-4.6
git rebase release-4.6

 

Git is quite efficient at merging your changes during rebase. Check here about how to resolve conflicts if you have any (not sure where "here" was meant to be, but 'git mergetool' is useful).
Now you're ready to generate the patches.

git format-patch release-4.6

Or you can redirect your patches to another directory:

git format-patch release-4.6 -o ~/patches

Git will generate one patch file for every commit on the branch. Since git lets you modify the history of the commits you can generate a series of patches that can show the logical development of your feature. Alternatively you can choose to generate a single patch like this:

git diff release-4.6 > super-feature.patch

You can attach patches to JIRA issues or send them on the list for discussion.

Let's assume that you have been hacking for a while on a branch (say: XECS-2387) and your work spans more than one component (in this example, let's assume: sipXbridge and sipXconfig ). You want to commit your sipXbridge changes to the version control system, because you are happy with them but want to submit some other changes as a patch to the owner of that other component because he wants to inspect your patch before accepting it. Here is how to proceed.

This will generate two patches

git commit sipXconfig/ -m"XECS-2378: sipxconfig changes for supporting hidden parameters"
git commit sipXbridge/ -m"XECS-2378: sipxbridge changes for supporting hidden parameters"
git format-patch release-4.6 -o ~/patches
git rebase XECS-2378 release-4.6
git rebase -i HEAD~3

and remove the line that you want to remove when the editor brings up the interactive screen (i.e. the sipXconfig patch in this case). Then do the

git commit

as above. Pick up the other patch and attach it to the issue, thus maintaining friendly relations with the owner of the other component.

Accepting patches sent by other developers

Quite often people will comment on your patches. Sometime developers will generate patches on top of your patch. You can commit them to your git repository.

If someone sends you a patch generated with git

Make sure you are in the proper branch before running these comands

git checkout super-feature
git am -3 0005-some-fixes.patch

That will commit the patch to super-feature branch - it will preserve the name of the patch author and their comments.

'-3' means that git will try to merge the patch. If there are conflicts use:

git mergetool

to resolve them.
You can list multiple commits, or an entire directory full of patches:

git am -3 patches/*patch

You can make your changes on top of the patch and commit them separately. Or you can amend the previous commit with your changes.

-a means add all changes, --amend means fix previous commit


git commit -a --amend

You can also easily accept/review patches generated with svn diff, gendiff etc:

git apply -p0 0005-some-fixes.patch

That will apply the patch but not commit it (if patch was not generated by git it does not have enough information to create commit). It's slightly more convenient than using patch command since it'll behave in an atomic way (the apply will succeed or fail - it won't leave your workspace partially patched)

More tips

There is several git GUIs - if you use Gnome giggle is a good choice

yum install giggle
giggle &

If you encounter problems when rebasing or merging 'git mergetool' command can be used to launch graphical 3-way merging tool. Make sure that you run it from the root of your git repository.

git rebase master

  1. ... reports merge conflicts
    git mergetool
  2. launches your favorite merge tool (meld in my case)
  3. after you merge all conflicting changes
    git rebase --continue

'checkout' and 'status' are probably 2 most commonly used commands. To add svn-like aliases for them:

git config --global alias.co checkout
git config --global alias.st status

And now you can use those aliases, 'st' and 'co' instead of the fully spelled out keywords:

git st # instead of git status
git co release-4.6 # instead of git checkout release-4.6

 

Enable colorized output for various commands:

git config --global color.branch auto
git config --global color.diff auto
git config --global color.interactive auto
git config --global color.status auto

If you use bash, use git-completion.bash. It enables simply pressing: <TAB> to display a list of potential commands, arguments and parameters. For example:

git checkout <TAB>

will show the list of branches.

Source it in your ~/.bashrc:

. /path-to/git-completion.bash

To have the current branch appear on your bash prompt:

export PS1='[xecsdev:\u@\h`__git_ps1` \W]\$ '

If you want to roll back to a particular point in history ( say some feature that is currently broken, but formerly worked a week ago and is blocking your progress ): Look at your git repository using giggle. You will see each commit has a global UUID. You can pick out the specific point in history when the world still looked rosy by doing:

git checkout -b proxy-still-worked UUID