Git Branches

From WineHQ Wiki
Jump to: navigation, search

Maintaining feature branches

Where you are doing work that may take a long time to get into WineHQ, or which is not expected to ever get into WineHQ, you may find it convenient to maintain a feature branch. Feature branches can be more easily published and shared so that others can benefit from the branch, and history will go with the branch, which helps with merges.

Create the feature branch

First you need to create the branch and check it out. Git makes this a one-step operation using git-checkout

git-checkout -b cool-feature-name origin

This creates a branch directly of the WineHQ code so that others can share the branch without having to get any of your other features. It then changes the working copy to reflect that branch.

Make your changes, and commit them

After you are happy with your new feature, check it in to your branch.

git-update-index [changed-files]
git-update-index --add [new-files]
git-commit

Go back to your master branch, and merge the feature branch in

Next you can go back to your master branch and merge this feature in.

git-checkout master
git-pull . cool-feature-name

When you need to modify the feature

When you need to update the feature, you should do it on the branch, but you should update the branch to the current WineHQ version.

git-checkout cool-feature-name 
git-pull . origin

This may involve having to fix up merge conflicts as discussed above. Once you have finished making your changes, use git-update-index and git-commit to commit it back to the branch, then go back to your master branch and merge the feature in again.

When you need to update somebody else's feature

Sometimes somebody else will write a feature but not keep it up to date. No problem, with GIT you can do it yourself with:

git-fetch other-repository-url cool-feature-name:cool-feature-name
git-checkout cool-feature-name

You now can bring the feature up to date yourself. When you have finished making your changes, commit them to the branch and merge the branch back into your master branch just as you would if you had originally created the branch.

Publishing your branches

Basic branch publication

The easiest way to publish your branches is to publish them on a web server. GIT needs to be installed on that server.

First you will need an empty GIT repository that is accessible on that web server and mark its post-update script executable

GIT_DIR=~/public_html/wine-branch git-init-db
chmod +x ~/public_html/wine-branch/hooks/post-update

Then you can publish your master branch to that directory:

git push server.example.com:/home/me/public_html master:master

(note that this approach of directly publishing your master branch is not recommended by the GIT people, but if you are only developing on one system it works well enough).

You can publish feature branches the same way:

git push server.example.com:/home/me/public_html cool-feature-name:cool-feature-name

Somebody else can merge in your feature branch as follows:

git checkout master
git pull http://server.example.com/~me/wine-branch cool-feature-name:master

Or they can obtain a copy of your master branch to work with locally:

git fetch http://server.example.com/~me/wine-branch master:me-master

Simplifying branch publication

Establishing the simplified environment

You can simplify branch publication with a few scripts. First, copy your master branch to a staging branch:

git-fetch . master:staging

Next you will need to create two files, .git/remotes/local-publish and .git/remotes/remote-publish

.git/remotes/local-publish:

URL: .
Push: master:staging
Pull: staging:master

.git/remotes/remote-publish:

URL: url-of-your-published-branches
Push: staging:master
Pull: master:staging

And then you will need three shell scripts:

git-sync:

#!/bin/sh
git pull remote-publish && git pull origin && git-push local-publish && git-push remote-publish

git-fetch-branch:

#!/bin/sh
case $# in
2)
	git-fetch "$1" "$2:$2"
	;;

1)
	[ -f .git/remotes/remote-publish ] || {
		echo "no remotes specification for remote-publish" >&2
		exit 1
	}
	git-fetch `grep -i '^URL:' ".git/remotes/remote-publish" | sed -e 's/^URL: *//'` "$1:$1"
	;;

*)
	echo "Usage: git-publish [url] branch" >&2
	exit 1
esac

git-publish:

#!/bin/sh
case $# in
0)
	git-push local-publish && git-push remote-publish
	;;

1)
	[ -f .git/remotes/remote-publish ] || {
		echo "no remotes specification for remote-publish" >&2
		exit 1
	}
	git-push `grep -i '^URL:' ".git/remotes/remote-publish" | sed -e 's/^URL: *//'` "$1:$1"
	;;

*)
	echo "Usage: git-publish [branch]" >&2
	exit 1
esac

Using the simplified environment

To update your current HEAD branch to incorporate the latest changes in both your published repository and the WineHQ tree, and then republish the merged result:

git-sync

To publish your updated master branch:

git-publish

To publish a feature branch:

git-publish cool-feature-name

If you use tags, you can publish the tag to the repository with:

git-publish refs/tags/tag-name

To fetch or update one of your own feature branches from your published repository (this only makes sense if you do development on multiple systems):

git-fetch-branch cool-feature-name

To fetch somebody else's feature branch:

git-fetch-branch url cool-feature-name