Skip to content

Using Git

Erik Massop edited this page Nov 4, 2017 · 1 revision

Other tutorials

You might want to check these as well, they are probably more useful than this document:

Grabbing the development tree

To clone a fresh copy of the development repository:

git clone git://git.xmms2.org/xmms2/xmms2-devel.git

This will create a new directory called "xmms2-devel" which contains the full code repository. It will have all files checked out and will also contain a ".git" subdirectory which contains the git metadata related to the repository.

Hacking

You started hacking away, and are satisfied with your changes and want to commit them! To show what files have been changed:

git status

To show the diff between the files in the repository and your modified files:

git diff

You can optionally add a filename after git diff to show the diff for a specific file.

If you notice that you have made any changes to a file that should not be part of the commit you can just remove the file and do:

git checkout path/to/the/file

To add new files to the repository:

git add file.foo

As a good engineer you should of course make sure that the code in the tree still compiles and works as it is supposed to, before continuing with the commit process.

When you've checked that everything is in order and you want to commit your work to a changeset:

git commit -a

Make sure you follow the changelog format. The first line will be used as a summary of the changeset and should be kept short and informative. The following lines will be a more verbose description of what changes the changeset brings.

Branches

As soon as you start doing more than the causal trivial fix once a month you probably want to start using branches. It is a good idea to start a new branch for each major change. Let's say, for example, you want to implement Collections in python. So you create a "pycoll" branch to work on.

git checkout -b pycoll origin

Hack away! Commit often! Commit early! You can either create lots of throwaway commits and clean up afterwards, when your changes are ready for inclusion, or you can use "git commit --amend" to merge more and more stuff into the the same commit.

Then, while working on your pycoll stuff you hear about a bug. Just switch another branch and reset it to whatever version the reporter used.

Now that you have lots of branches you probably want ways to list the changes..

git rev-list --pretty=oneline branch1..branch2

lists things that are in branch2 but not in branch1. Including merge changesets and stuff. If you only want to see the real changes use:

git cherry -v branch1 branch2

Remotes

BTW, here is how you easily can setup remotes for everyone's trees, so that you can "git fetch nano" and get a "nano" branch in your tree that is equivalent to nano's public tree. But that is probably a more interesting case for integrators..

for U in alex anders coledot danderson devel eleusis jlt juhovh nano puzzles rafl theefer tilman tru; do  echo -e "URL: git://git.xmms2.org/xmms2/xmms2-$U.git\nPull: +master:$U" >.git/remotes/$U done

Getting updates

To keep in sync with the latest version:

git pull git://git.xmms2.org/xmms2/xmms2-devel.git

Rebase

By using "git rebase" instead of "git pull" you will avoid creating merge changesets. Instead your local changes will be forwardported to the new devel.

If you based your changes on "E", and then some changes happened in devel like this:

                   A---B---C  you                   /              D---E---F---G  -devel

If you pull -devel a merge changeset M will be created, like this: (this will happen each time you pull and work has happened on -devel, so there might be quite a number of merge changesets after a while if your tree isn't integrated in -devel)

                   A---B---C---M  you                   /           /              D---E---F---G---/

If you instead use rebase your local changes will be forwardported like this:

                           A'--B'--C' you                           /              D---E---F---G 

Prerequisites:

cat .git/remotes/origin  URL: git://git.xmms2.org/xmms2/xmms2-devel.git Pull: refs/heads/master:refs/heads/origin

And then just

git fetch git rebase origin

Informal Rebase

This is the more troublesome way to get rid of the ugly 'Merge' changesets and duplicate changesets because of upstream has cherrypicked from your tree.

First create an upstream branch in your tree:

git pull git://git.xmms2.org/xmms2/xmms2-devel +:upstream

The + means that git should not try to merge or be smart or something.

Then you can list the changesets that are in your tree, but not upstream:

git-rev-list --pretty upstream..master

Or you can do:

git cherry -v upstream master

Which also lists the diffrence, but doesn't list cherrypicked changesets.

Now create a new branch:

git branch forupstream upstream

And make it the default branch:

git checkout forupstream

If all the changes you saw in git cherry earlier were good for upstream just put 'em all on this branch:

for cset in $(git cherry upstream master); do    git-cherry-pick -r $cset; done

There will be some warnings and stuff, but that is normal. It should say "Finished one cherry-pick." for each cset if everything applies cleanly.

This is a good time to make sure your tree still compiles :)

And if you are satisfied and want to make that your master again, then checkout master:

git checkout master

And go there:

git reset --hard forupstream 

There, now you're ready to push your changes to your public tree without an ugly merge changeset.

git push -f git.xmms2.org:/xmms2/xmms2-yourpublicrepository master

Clone this wiki locally