20110213 GitWorkflowAgenda/StevesIdea

From KDE Community Wiki

This page assumes the following:

  • The kdelibs repo is kdelibs.git. This is where releases comes from
  • The kdelibs repo has branches 'master' and 'X.Y' version number branches
    • These branches can not be force pushed
  • All other branches *can* be force pushed by default
    • This is to encourage pushing of 'work in progress' at all. If force pushing is not allowed or discouraged, it is a disincentive to put work branches on a public repo.
  • Branches whose name starts with "shared_" can't be force pushed.

--Tnyblom 11:18, 16 February 2011 (UTC) Better to use the namespace "shared/"

    • This is a way to ease collaboration by making it hard to accidentally force push a branch which many people are working on.
    • If possible the person who started the branch can force push it.
    • Another way of 'locking' branches like this may be better. I just assume there is a good way.
    • There would also need to be a convenient way to 'unlock' it
  • Merging and merge commits are rare and unnecessary for 'feature branches'/'topic branches'/'work branches' or any other name people might use for the same thing - work that is not yet in a branch where a release will be made from. This workflow advocates rebasing instead, even of public branches, at sensible times.
  • If force pushing is disallowed on the main repo, work branches can be put in a kdelibs-work.git repo instead.

Use case: Someone wants to use master for day-to-day use or testing.

git clone kde:kdelibs
git checkout master # This use case always uses master.
git pull --rebase   # Periodically. Really the --rebase isn't needed if this person never makes commits, but consistency is good in case they ever do


Use case: Someone wants to use stable for day-to-day use or testing.

git clone kde:kdelibs
git checkout 4.6 # This use case always uses the stable branch.
git pull --rebase   # Periodically.
# Event: KDE 4.7 released
git checkout 4.7 # This use case always uses the stable branch.
git pull --rebase   # Periodically.


Use case: An enthusiatic user wants to get started fixing some bugs

git clone kde:kdelibs
git checkout master # Or 4.6 depending on the personal preference and the bug.
# Fix bug
git commit
# Test
git pull --rebase # get commits that have been made in the mean-time ...
git push          # ... and put my commit in there too.
                  # My commit goes in *on top* No need to introduce the merging
                  # concept or a merge commit
git pull --rebase # Periodically

Use case: Someone wants to work on a feature that takes longer than half a day and should therefore be in an archived branch.

# Day 0:
git clone kde:kdelibs
git checkout master
# Start feature
git checkout -b new_proxy_model
git commit
git commit
git commit
git push origin new_proxy_model # Send the new_proxy_model branch and commits
                                # to the kdelibs repo
# The next (and Nth) day
git checkout new_proxy_model # If not already on the branch.
git commit
# Discover bug needing fixing in master
git checkout master
# fix bug
git commit
git pull --rebase
git push origin           # Put the bug fix on the public repo (official kdelibs)
git checkout new_proxy_model
git rebase master         # Put my work 'on top' of the latest in master, which includes
                          # the bug fix.
# Continue working on feature
git commit
git commit
git push -f origin new_proxy_model   # Put my now rebased work into the repo
# Do the same thing for as many days as it takes until the feature is done.
# On the day the feature is done:
git checkout master
git pull --rebase            # make sure I have the most recent work from the master branch
git checkout new_proxy_model
git rebase master            # put my work on top of the most recent work from the master branch
git checkout master
git rebase new_proxy_model   # Update master to include my work
git push origin              # Update master on the official repo. Now anyone who pulls master from git
                             # will get my work.
git branch -d new_proxy_model  # remove the old branch name locally.
git push -f origin :new_proxy_model # remove the old branch name on the remote repo.


Use case: Two or more developers want to collaborate on a feature.

# The same as above, except that all interested developers have an agreement that
# the branch will not be rebased. This could be enforced by a naming convention
# eg, "stable_" and a server side hook preventing forced pushes on those branches.
# eg: Alice works on the feature:
alice@box$ git commit
alice@box$ git commit
alice@box$ git push 
# Bob gets alices work
bob@laptop$ git pull
# Bob does work of his own
bob@laptop$ git commit
bob@laptop$ git push             # Alice can now get bobs work
# Bob fixes a bug in master as above, and pushes that to the public repo
# Bob then brings the bug fix into the feature branch he and Alice are working on
git checkout collaborative_feature
git merge master
git push origin collaborative_feature   # Anyone who pulls the branch gets the bug fix.
# Repeat until the feature is done.
# The day it is done:
git checkout collaborative_feature
# Optionally create a 'clean' stream of commits on top of the current latest in the official master.
git rebase master
# Either push it to the repo again for review or include it in master now.
git checkout master
git rebase collaborative_feature
git push                # The new feature is now in the official master.
git branch -d collaborative_feature
git push -f origin :collaborative_feature

To keep the branch up to date with master Alice and Bob merge master into their branch whenever they want. They might also decide that they will rebase on every Sunday (or whatever). This is just an agreement between the two of them. Charlie knows that kdelibs branches can be force pushed by default, so he doesn't base any work on the collaborative_feature without letting Alice and Bob know that he wants to be a collaborator.

The rebasing of this long lived feature branch at the end is optional but encouraged.