TubeTK/Development/GITBranchingUsage: Difference between revisions

From KitwarePublic
Jump to navigationJump to search
No edit summary
No edit summary
Line 3: Line 3:
* All developments should use the workflow to maintain an organized git history in TubeTK
* All developments should use the workflow to maintain an organized git history in TubeTK
* Key concepts:
* Key concepts:
** Each feature (also known as a "topic") should be developed in its own separate branch on the author's clone of TubeTK on Gitorious
** Each feature (also known as a "topic") should be developed in its own separate branch on the author's public repository (i.e. the author's clone of TubeTK on Gitorious)
** Once the feature has been programmed and tested, its branch should be merged into TubeTK's master branch
** Once the feature has been programmed and tested, its branch should be merged into TubeTK's master branch
** After the feature has been merged, its branch should be deleted
** After the feature has been merged, its branch should be deleted


== Setting up your TubeTK clone on Gitorious ==
== Setting up your personal TubeTK public repository ==


* Create an account at [www.gitorious.com | Gitorious ]
* Create an account at [www.gitorious.com | Gitorious ]
Line 22: Line 22:


Then, setup the remote repositories that should be tracked:
Then, setup the remote repositories that should be tracked:
* '''origin''': your Gitorious clone
* '''origin''': your public repository
* '''upstream''': the TubeTK remote repository
* '''upstream''': the TubeTK central repository


  git remote set-url --push origin git@gitorious.org:~'''<yourName>'''/tubetk/'''<yourName>'''-tubetk.git
  git remote set-url --push origin git@gitorious.org:~'''<yourName>'''/tubetk/'''<yourName>'''-tubetk.git
Line 29: Line 29:
  git remote set-url --push upstream git@gitorious.org:tubetk/tubetk.git
  git remote set-url --push upstream git@gitorious.org:tubetk/tubetk.git


== Repository setup ==
== Remote repository setup ==
* '''origin''': keeps a master branch that is only a pointer to the TubeTK master branch, + any of your topic branches
* '''origin''': keeps a master branch that is only a pointer to the TubeTK master branch, + any of your topic branches
* '''upstream''': has a master branch
* '''upstream''': has a master branch
Line 79: Line 79:
  ''' run tests again, to ensure that the merge did not introduce problems '''
  ''' run tests again, to ensure that the merge did not introduce problems '''


Now, publish your changes to your Gitorious clone, and to TubeTK's repository.  This will add your contribution to TubeTK:
Now, publish your changes to your public repository, and to TubeTK's central repository.  This will add your contribution to TubeTK:


  git push origin master
  git push origin master
  git push upstream master
  git push upstream master


Delete your topic branch both locally and on your remote Gitorious clone.
Delete your topic branch both locally and on your public repository.


  git branch -d '''<topic>'''
  git branch -d '''<topic>'''
Line 101: Line 101:


To get changes that have been committed to the location you originally cloned from:
To get changes that have been committed to the location you originally cloned from:
  git stash            # To push your uncommitted local changes to a stack
  git stash            # Push your uncommitted local changes to a stack.  Be careful, they are not saved anywhere else.
  git pull --rebase
  git pull upstream --rebase
  git stash pop        # To apply the changes on the stack to the update local repository
  git stash pop        # To re-apply the changes on the stack to the local repository


== From other repositories ==
== From other repositories ==


Pull changes made by another developer in his public repository but not yet committed to the central repository:
Pull changes made by another developer in his/her public repository, but not yet committed to the central repository:
  git pull git://some-other-repo.git master
  git pull git://'''<some-other-repo>'''.git master


'git remote' can be used to manage short names for repositories that you frequently pull from.
'git remote' can be used to manage short names for repositories that you frequently pull from.

Revision as of 06:31, 22 November 2010

Git commands for a branchy workflow

  • All developments should use the workflow to maintain an organized git history in TubeTK
  • Key concepts:
    • Each feature (also known as a "topic") should be developed in its own separate branch on the author's public repository (i.e. the author's clone of TubeTK on Gitorious)
    • Once the feature has been programmed and tested, its branch should be merged into TubeTK's master branch
    • After the feature has been merged, its branch should be deleted

Setting up your personal TubeTK public repository

  • Create an account at [www.gitorious.com | Gitorious ]
  • Clone the TubeTK repository:

Setting up your local repository

First, setup your local repository:

  • In the example below, <yourName> is the name of your Gitorious account
cd Projects
git clone git://gitorious.org/~<yourName>/tubetk/<yourName>-tubetk.git

Then, setup the remote repositories that should be tracked:

  • origin: your public repository
  • upstream: the TubeTK central repository
git remote set-url --push origin git@gitorious.org:~<yourName>/tubetk/<yourName>-tubetk.git
git remote add upstream git://gitorious.org/tubetk/tubetk.git
git remote set-url --push upstream git@gitorious.org:tubetk/tubetk.git

Remote repository setup

  • origin: keeps a master branch that is only a pointer to the TubeTK master branch, + any of your topic branches
  • upstream: has a master branch

Adding a feature

  • A feature may be new functionality, a new test, a bug fix, performance enhancements, added documentation, style fixes, etc.
  • Each feature should have its own branch
  • Do all of your work in a topic branch, not in master. Do not git add/git update in the master branch.
  • In the workflow below, <topic> refers to the name of your branch.

For new features, use the git 'upstream/master' branch as the starting point:

git checkout master
git fetch upstream
git merge upstream/master
git checkout -b <topic>
git push origin <topic>:refs/heads/<topic>

All commits for that feature should be committed to the topic branch:

git checkout <topic>
 code, code, code 
git add -u
git commit
 code, code, code 
git add -u
git commit
git push origin <topic>
 code, code, code 
git add -u
git commit
 code, code, code 
git add -u
git commit
git push origin <topic>

After the feature is completed and tested, merge its topic branch to TubeTK's master branch:

First, make sure that your local master branch is up to date, by fetching and merging all of the changes that have recently occurred on the TubeTK master branch:

git checkout master
git fetch upstream
git merge upstream/master

Next, merge your topic branch to your local master branch:

git merge <topic>
 you may have to fix merge conflicts 
 run tests again, to ensure that the merge did not introduce problems 

Now, publish your changes to your public repository, and to TubeTK's central repository. This will add your contribution to TubeTK:

git push origin master
git push upstream master

Delete your topic branch both locally and on your public repository.

git branch -d <topic>
git push origin :<topic>

If you want to add more features, start over with a new topic branch.

Use multiple commits to organize changes

When appropriate, organize your changes into a series of commits where each commit is a logical step towards your ultimate goal. For example, first factor out some complex code into a new function. Then, in a second commit, fix an underlying bug. Then, in the third commit, add a new feature which is made easier by the refactoring and which would not have worked without fixing that bug. This is helpful to reviewers, because it is easier to see that the "factor out code into new function" step was right when there aren't other edits mixed in; it's easier to see that the bug is fixed when the change that fixes it is separate from the new feature; and so on.

Get changes from others

From the central repository

To get changes that have been committed to the location you originally cloned from:

git stash            # Push your uncommitted local changes to a stack.  Be careful, they are not saved anywhere else.
git pull upstream --rebase
git stash pop        # To re-apply the changes on the stack to the local repository

From other repositories

Pull changes made by another developer in his/her public repository, but not yet committed to the central repository:

git pull git://<some-other-repo>.git master

'git remote' can be used to manage short names for repositories that you frequently pull from.

From patches

Apply a patch from another developer, preserving the other developer's identity as the patch author:

git am --signoff patch.mbox

Work with branches

To list just the branches in your local repository:

git branch

To list all the branches in the remote repository:

git branch -r

To check out a branch for example the 2.4 branch:

git checkout -b vBeta origin/vBeta

To work on the Beta branch instead of 'master' ('master' is the git equivalent of cvs 'TRUNK'):

git branch --track vBeta origin/vBeta
git checkout vBeta

After you branch, you can switch freely between master and branch:

git checkout master
git checkout vBeta

You can create your own branch based off another branch:

git branch my-topic master

git often uses "topic" as a placeholder for a branch name, because everything in a branch should be on one "topic"--a topic might be to add feature X, refactor subsystem Y, only fix bugs from version Z, and so on.

If you prefer to use different directories for different branches

The following sequence creates "tubetk-vBeta" alongside "tubetk", then uses 'git relink' to save disk space, then switches to the vBeta in the tubetk directory:

cp -r tubetk/ tubetk-vBeta
git relink tubetk-vBeta/ tubetk/
cd tubetk-vBeta
git branch vBeta origin/vBeta 
git checkout vBeta

Share your changes with others

Choose an appropriate starting point

For new features, use the git 'origin/master' branch as the starting point. For bugfixes, use the merge-base of master and vBeta. You can make a bugfix and merge it into both branches like so:

git checkout $(git merge-base origin/vBeta origin/master)
git checkout -b descriptive-bugfix-branch-name
edit/compile/test/commit
git checkout master
git merge descriptive-bugfix-branch-name
compile/test
git checkout vBeta
git merge descriptive-bugfix-branch-name
compile/test

Check with tubetk developers before pushing changes to vBeta. If your bugfix is approved for vBeta, then it will also be fixed on master when changes in the branch are merged up.


Prepare commits to share with fellow developers

With git, it's possible to record every edit and false start as a separate commit. This is very convenient as a way to create checkpoints during development, but often you don't want to share these false starts with others.

Git provides two main ways to do this, both of which can be done freely before you share the change:

  • 'git commit --amend' lets you make additional changes a part of the last thing you committed, optionally modifying the commit message as well. Use this if you realized right away that you left something out of the commit, or if you typo'd the commit.
  • 'git rebase --interactive origin' lets you go back through each change made since 'origin', possibly editing it or combining ('squashing') it with another change. In the most extreme case, you can 'squash' it into a single commit, if there's no value to other developers in seeing the individual steps.

Send patches through e-mail or the web

When you think your changes are ready to be used by others, you can share it in the form of a patch. Make a series of patches for each commit in your local branch but not in 'origin':

git format-patch -M origin

This creates a number of files with names like

0001-my-well-intentioned-change.patch

These patch files are suitable for putting on a webserver or for sending as e-mail with your favorite mail client or git-send-email (some configuration required).

To submit a patch, email it to one of the TubeTK Developers.

Push changes to the central repository

If you've been approved to directly push your changes to the central repository, then after some initial setup of ssh keys it's a fairly simple process:

git pull --rebase
# resolve any conflicts, but generally there won't be any
git push

If another developer pushed between your pull and your push, you will have to pull and then push again. This isn't expected to happen very frequently, but it will happen more frequently than with cvs since it's required when any file changed, not just when a specific file being committed changed. It is also best to use "git pull --rebase" in this case, this will cause the changes from the central repository to be positioned before your own changes (thus skipping a merge).

Push changes to your own public repository

You can host a public repository to which you "push" and from which others can "pull". If you don't have a server of your own to do this, services like github and gitorious are free for open source projects. After you push to your own public repository, other developers can browse your changes or "pull" them.

Policy

Just because a thing can be done with git doesn't mean it should be done.

Prefer "rebase"

Use "git pull --rebase" instead of bare "git pull" in order to keep a nice linear history. When you "--rebase", you always retain your work as revisions that are ahead of origin/master, so you can do things like git format-patch them to share with others without pushing to the central repository.