Dev:Doc/Tools/Git

提供: wiki
移動先: 案内検索

Git Usage

Blender source code, addons and translations are hosted in Git repositories.

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.


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 git://git.blender.org/blender.git
cd blender
git submodule update --init --recursive
git submodule foreach --recursive git checkout master
git submodule foreach --recursive 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!


Repository Update

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

git pull --rebase
git submodule foreach --recursive git pull --rebase origin master

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


Exclamation mark.png

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 "your_name@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 <author@example.com>"

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 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 git@git.blender.org: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 git@git.blender.org:blender-addons.git
cd ../addons_contrib
git remote set-url origin git@git.blender.org:blender-addons-contrib.git
Note
Failing to do this will give an error when pushing, for example:
fatal: remote error: access denied or repository not exported: /blender-addons.git


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, OS X, 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 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...

Exclamation mark.png

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

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
  • You probably want to enable ReReRe (automatic recording and replaying how you solved a given conflict if you encounter it again) by:
git config --global rerere.enabled true
  • 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.
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 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 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, ...)

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.
  • And of course: IRC - Freenode #git