Blender source code, addons and translations are hosted in Git repositories.
- git.blender.org hosts the repositories
- developer.blender.org/diffusion is used for browsing the repositories online
To access the repositories, you will need to download Git or one of the GUI clients for it. If you are using Linux or Xcode or Mac OS X, you may already have Git installed.
The first step is to clone the repositories to your local hard drive. These commands will clone the repository and update addon and translation submodules to their newest version.
git clone git://git.blender.org/blender.git cd blender git submodule update --init --recursive git submodule foreach git checkout master git submodule foreach git pull --rebase origin master
Alternatively, for cases where a firewall restricts access to certain ports you can use http:// instead of git:// in the URL.
Note: the git submodule command does not work with older git versions, we will update the documentation for older git versions later!
It is strongly recommended to update the repository with these commands, both for read-only and writable checkouts:
git pull --rebase git submodule foreach git pull --rebase origin master
Now, a bit of theoretical information. Command "git pull" is a shortcut for
git fetch git merge FETCH_HEAD
First command downloads all the updates from the server, second command merges the changes made in remote repository to your local checkout. This means that if you've got any uncommited changes or local commits which you didn't push to the repository yet, git will create a special merge type of commit. The history will look like this:
commits from server / \ old commits - o merge commit \ your local commits /
The policy is to keep history as linear as possible, and that's where --rebase argument becomes handy. If you use this argument, git pull --rebase will strand to:
git fetch git rebase FETCH_HEAD
Rebase means that git will first stash all uncommited changed and commits which are not pushed to the repository, then it'll apply all the new commits from repository and then will apply changes from stash on top of all this commits. History in this case will look like:
old commits - commits from server- your local commits
However, do not use
--rebase option after a merge! This applies when working on non-master public branches, leading to a rewrite (rebase…) of that branch's history, instead of proper merge. See also #How to push changes.
Making Local Changes
With Git, you can commit changes or create branches in your local repository, before pushing them to the official repository or submitting them for code review. However, before you can do this you need to set up your full name and email address, so that Git can label your commits with them.
If you have an account at developer.blender.org, you will want to use at least the same full name or email address as the account, so that commits can be linked to it.
git config --global user.name "Your Full Name" git config --global user.email "email@example.com"
If you commit on someone else's behalf, supply the information via the --author parameter to the commit command instead of mentioning it somewhere in the log message.
git commit --author "A U Thor <firstname.lastname@example.org>"
There's a nice Git Cheat Sheet which briefly covers git workflow and is nice helper for the young players. See also the Further Reading section.
Conflicts on Update
If you have committed local changes, it is possible that pulling updates from the remote repository will lead to rebase conflicts. Note that git is rather smart at avoiding conflicts, and you'll have to edit the same lines as upstream to get a conflict, and git sometimes can detect if the change is the same locally and upstream.
If you still run into conflicts, you need to solve them manually by editing the sources:
# see list of conflicted files git status # all the files marked as "both modified" are in conflict state and need to be solved # as soon as you solved conflict in file, you need to do: git add file/which/was/in/conflict # once all the files are solved, do: git rebase --continue
Alternatively, you can use mergetool and configure it with your preferred conflict resolution tool (gvimdiff, meld, ...):
For developers with commit access to the main repository, some setup is needed to push changes.
Checkout with write access
The repository must be accessed with the git@ protocol instead of git:// or http:// to work over SSH. If there's already checkout, it is possible to switch it to the SSH protocol (no redownload needed):
git remote set-url origin email@example.com:blender.git
For the addon repositories in release/scripts/addons and release/scripts/addons_contrib you need to run a similar command. The easiest approach is:
cd release/scripts/addons git remote set-url origin firstname.lastname@example.org:blender-addons.git cd ../addons_contrib git remote set-url origin email@example.com:blender-addons-contrib.git
Failing to do this will give an error when pushing, for example:
fatal: remote error: access denied or repository not exported: /blender-addons.git
The SSH protocol with RSA public key authentication is used for push access to the repository. If you don't already have the file ~/.ssh/id_rsa.pub, there's a simple command to generate such keys which works on Linux, OS X, and in Git Bash on Windows:
This command will generate a private key id_rsa and a public key id_rsa.pub in ~/.ssh. The private key must never be shown or sent to anyone else to avoid compromising your account, but the public key is safe to share.
The contents of ~/.ssh/id_rsa.pub can be copied and pasted into the account settings on developer.blender.org, after clicking "Add New Public Key". Any name for the SSH key is ok.
It maybe take about 10 minutes to sync to the Git server before you can commit.
How to push changes
The first thing to check is that your commit has a good commit message and that it contains no accidental changes. You can do this with these commands:
# see which commits you are about to push git log origin/master..master # see the commit message and diff of the newest commit git show HEAD
We want to preserve a linear history of changes where possible. For this reason you should always pull and rebase the latest changes right before pushing to the repository. This ensures Git can always do a so called Fast Forward and not change any history or add merge commits. The correct sequence to publish local commits is:
git pull --rebase git push
Please read the extended information in the Repository Update section for details.
Note: git.blender.org will give error messages if you attempt to push merge commits, or do a force push. If you need to do this for some reason, contact the git.blender.org administrators.
Working with remote branches
You always can create personal local branches. However you also can push local branches to the repository for example when you know that you will be working for a long time on a new development. However...
Important: Once you have pushed a local branch to the repository do not use pull --rebase to update your local branch!
The reason things change once you have pushed is that somebody may merge your branch into theirs, and if you rebase you screw things up for them. This applies when working on non-master public branches, leading to a rewrite (rebase…) of that branch's history, instead of proper merge. See also #How to push changes.
Here is how you would safely push your local changes to your remote branch:
git checkout mybranch git merge origin/master git push
And this is how you would do this while keeping your local master up to date:
git checkout master git pull --rebase git checkout mybranch git merge master git push
- Git comes with nice built-in terminal coloring for diff, status etc. To switch on the default colors do:
git config --global color.ui auto
- If you want to have aliases like
git cito do
git cito do
git commitand so on, you can do:
git config --global alias.st status git config --global alias.co checkout git config --global alias.ci commit git config --global alias.di diff
Of course, you can add more or remove some. Note that git aliases are far more powerful than that, check
git help config
- Show branch in bash prompt: If you are working on the command line, it can be easy to forget which branch you have checkout out, and accidentally commit to the wrong branch.
- Here's how to setup command prompt in Debian Linux. For other distros simply adding $(__bashrc_git_ps1) to the PS1 in ~/.bashrc will do the trick.
- Get history of specific lines/function changes (similar to a recursive
git log -L <start_line>,<end_line>:<file> # History of specified set of lines. git log -L :<func_name>:<file> # History of a whole function.
- Checkout multiple branches from one repository:
When you want to checkout 2 Blender versions in parallel, you can use git worktree. Here is an example for how to setup a worktree for another branch (blender2.8 in this case). We assume you have already cloned the repository and you have moved your commandline tool into the main folder of the blender sources.
git worktree add -B blender2.8 ../blender2.8 cd ../blender2.8 git submodule update --init --recursive
Now you can use the new folder just like you use the main repository (git pull, git push, git add, ...)
Often merging some conflicting changes into a very active branch is a pain, because by the time you resolve the conflicts more commits have been added. YOU DO NOT WANT TO GIT PULL REBASE again in that situation, since it would rebase the whole merge, generating a lot of commit noise (all commits since lats merge would then be 'made real, as if done on top of latest branch's commit.
To avoid this, you have to:
- Reset your local copy of the branch to the origin state:
git reset --hard origin/<thebranch>
- Update the branch the usual way.
- Do the merge again!
Point 3 can become horribly time-consuming. Git provides a helper here, ReReRe, which automatically records and replays how you solved a given conflict if you encounter it again. You can enable it by:
git config --global rerere.enabled true
Be careful! If you record a wrong merge that way, it will replay it too!
But ReReRe only records conflicts fixing, it does not record any other change you may have had to do in the branch to "fix" it after the merge (e.g. if the merge changes the signature of a function that is used in new places in the branch...).
You can work around that issue (and save a fair amount of time) by recording yourself those changes:
- Do your merge, fix the conflicts and do any other required change.
- BEFORE validating the changes (with ), save them in a temp diff file:
git add path/to/changed/code
git diff > path/to/temp.diff
- Reset to origin (), update the branch.
git reset --hard origin/<thebranch>
- Merge again, ReReRe should fix all the conflicts for you.
- Apply your temp patch ().
git apply path/to/temp.diff
This whole process usually only takes a few seconds and fully redoes your merge, then you can check-compile, commit the merge and push it to the origin repo.
All the following are good resources to learn Git:
- Git Reference: despite its name it is more of a user guide.
- "Pro Git" Book: by a core developer, also a thorough user guide.
- Git Documentation: the official reference (also accessible with
git help command)
- Think Like a Git: a course for "advanced beginners" that know basic committing but want to make sense of the Git model. Especially useful if you come from SVN to really clear misconceptions about git.
- Git Concepts Simplified: Similar to the previous link, but less in-depth and more straightforward.
- Git Immersion: learn Git by using it on carefully crafted examples of increasing complexity.
- Git from the bottom up: A book to learn git by first understanding the simplicity and beauty of its internals.
- Git Magic: complete opposite of "Git from the bottom up" in that it treats Git as a magical gizmo you'll learn to use without drowning into the underlying storage and history model.
- Git questions on StackOverflow: comprehensive coverage of advanced matters
- Top 10 Git Tutorials for Beginners A list of tutorials and resources. Contains another list of far more than 10 sites at the end.
- And of course: IRC - Freenode #git