Git

From Pitivi wiki
Jump to: navigation, search

Git is the most popular distributed revision control system used by the kernel, X, GStreamer, GNOME, etc... Git allows you to get a checkout (with full history) of the Pitivi code, create your own branches, publish those, etc... without the need for access to the central repository.

Indeed, one of the very big strengths of a decentralized (a.k.a. distributed) system is that it is truly open and meritocratic: it allows you to do whatever changes you want to your repository, request feedback/reviews and then request that others pull your changes into the main repository on which others base their work upon. See http://youtube.com/watch?v=4XpnKHJAok8#t=18m05s for an explanation of this phenomenon.

This page is not meant to be a general tutorial for Git; for that, see the GNOME Git page, the official Git tutorial/documentation page and git ready. In this page, we will cover some more advanced usage and the specifics of how we use Git in the Pitivi project. This is aimed at people coming from Bazaar or Subversion.

Contents

First steps: checking out the main repository

git clone git://git.gnome.org/pitivi  # do the initial repository checkout

You should now have a directory called pitivi with the latest version of the files checked out. You are in the master branch (see also: Building with GES).

Note: unlike in Bazaar or other DVCSes, in git you only do this once; the "remotes" and branches in are all self-contained in the repository. In other words, you only do one checkout and do everything inside it using branches and remotes.

Dealing with remotes and branches

You can see all local branches by using the git branch command. The branch you are working in is marked with an asterisk (*). You can view all branches, including the remote ones, by doing:

git branch -a

You'll notice that it shows you all the branches available from the http://git.gnome.org/pitivi repository.

Let's say we add multiple people's remote repositories inside your local repository (see Git repositories for the list of our known remotes):

git remote add nekohayo https://github.com/nekohayo/pitivi.git
git remote add thiblahute https://github.com/thiblahute/pitivi.git

To update the remotes:

git remote update

And now you would be able to do stuff like:

git checkout thiblahute/somebranch

Or, to create a new local branch based on that branch:

git checkout -b mynewbranch thiblahute/somebranch

"git remote update" does not update your local branches, only the remotes. For example, if you have a local branch called "titles" based on "nekohayo/titles" (remote branch) and the "titles" branch on the "nekohayo" remote changed, you will have to checkout your local "titles" branch and update it to reflect the changes (with git pull --rebase, or a git reset --hard, depending on whether or not you want to keep your local changes).

When the remote party has deleted some branches, you're still left with local copies of those remote branches... eventually you can clean it up with:

git remote prune REMOTE_NAME

I like to think of "git checkout" like "svn switch": it allows you to move between branches (among other things). So, to go back to the main branch, you do "git checkout master".

Creating a work branch

It is good practice never to do work on the master branch (more details in the next section). Therefore you need to create a work branch :

 git branch work master

If you use git branch you will now see your new branch... but you are still in master.

To switch to your work branch you need to check it out using:

 git checkout work

And it tells you it has successfully switched to the work branch.

Tip: you can branch and checkout in one step using the -b <new_branch> option of git checkout Therefore the two steps above become:

 git checkout -b work master

Pitivi-specific gotcha: don't use git pull

Typically, in Pitivi we use rebase and reset more often than "git merge" when merging your changes. This means two things:

Really, in the Pitivi context you don't want to use "git pull" (this creates merge commits and becomes quite messy over time). However, the general rules of thumb regarding rebasing are:

Publishing your work / adding your own remote to push to

Several free git hosting services exist out there where you can create very quickly some repositories and publish your branch there. These websites will contain information on how to add your publishing remote URL. Here's an example of how you can add your remote git repository where you'll push your changes, with github (notice that I named the remote "github" instead of "origin", since origin is git.gnome.org):

git remote add github git@github.com:my_user/pitivi.git 

Let's say you created a working branch locally (called mytest) and that you named your remote repository myremote, and you want to publish it so people can see what you have done, try it out, etc. The first time you will have to tell git where you want to push that branch:

 git push myremote mytest

This will automatically:

The next time you want to push your work remotely, you just to be within that branch and do:

 git push

To delete a branch (or tag) on the remote repository:

git push REMOTENAME :BRANCHNAME

This command may look strange, but it is literally telling git push, onto REMOTENAME, "nothing" into BRANCHNAME.

Once that's done, others will be able to do a "git remote prune" to see those changes on their end.

Not going insane

You are very quickly going to have a lot of branches. There are graphical tools to view what you have locally and make some changes/actions without needing to rely on the command line (unless you prefer the command line interface). We recommend gitg (tailored for GNOME, with a really nice interface), though there are others like giggle or gitk.

Other very useful tools are:

Nice Git features to learn about:

Tips and tricks/gotchas for Bazaar/Subversion users

Git's syntax can arguably be quite arcane. Take a look at the ~/.gitconfig file: you can add an [alias] section to create command aliases. This is nekohayo's gitconfig:

[alias]
   diffstat = diff --stat
   staged = diff --cached
   unstaged = diff
   both = diff HEAD
   oneline = log --pretty=oneline --abbrev-commit
   
   newbranch = checkout -b # destination source, not the other way around
   deletebranch = branch -D
   switch = checkout
   uncommit = reset HEAD~1
   nukefromorbit = clean -fxd # use with extreme caution.
   up = pull --rebase
   patch = am
   
   meld = difftool --dir-diff -t meld
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox