Skip to content

Git Usage

Blender source code, add-ons and translations are hosted in Git repositories on projects.blender.org.

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 macOS, you may already have Git installed.

Repository Download

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 https://projects.blender.org/blender/blender.git
cd blender
make update

Repository Update

It is strongly recommended to update the repository with these commands, both for read-only and writable checkouts:

git pull --rebase
make update
For developers: why this is important

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

Warning/Important

However, do not use --rebase option after a merge! This applies when working on non-main 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 projects.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 protected]"

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 <[email protected]>"

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, ...):

git mergetool

Commit Access

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 https:// 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 protected]:blender/blender.git
git submodule sync

The submodule sync command automatically changes all submodules like add-ons as well. It's also possible to set the appropriate remote URLs for these manually.

SSH Keys

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, macOS, and in Git Bash on Windows:

ssh-keygen

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 projects.blender.org, after clicking "Add Key". Any name for the SSH key is ok.

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/main..main
# 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

https://projects.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 Blender 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-main 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/main
git push

And this is how you would do this while keeping your local main up to date:

git checkout main
git pull --rebase
git checkout mybranch
git merge main
git push

Tips

  • 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 ci to do git commit, git ci to do git commit and 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.
  • Ignore cleanup commits from the results of git blame (D9234): The uninteresting commits listed in the file blender/.git-blame-ignore-revs can be ignored by git 2.23+ after running the following in blender folder:

    git config blame.ignoreRevsFile .git-blame-ignore-revs
    
  • Get history of specific lines/function changes (similar to a recursive git blame):

    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 command line tool into the main folder of the blender sources.

    git worktree add -B blender-v3.3-release ../blender-v3.3-release
    cd ../blender-v3.3-release
    make update
    

Now you can use the new folder just like you use the main repository (git pull, git push, git add, ...)

Complex Merges

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:

  1. Reset your local copy of the branch to the origin state: git reset --hard origin/<thebranch>
  2. Update the branch the usual way.
  3. 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:

  1. Do your merge, fix the conflicts and do any other required change.
  2. BEFORE validating the changes (with git add path/to/changed/code), save them in a temp diff file: git diff > path/to/temp.diff
  3. Reset to origin (git reset --hard origin/<thebranch>), update the branch.
  4. Merge again, ReReRe should fix all the conflicts for you.
  5. 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.

Further Reading

All the following are good resources to learn Git:

  • 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.