Source code management

From FreeCAD Documentation
Revision as of 01:08, 24 July 2019 by Vocx (talk | contribs) (Moved section)

The main source code management tool for the FreeCAD project is Git, which can be easily installed in most operating systems from a package manager or directly from Git's website. You are advised to become familiar with Git before working with the FreeCAD source code directly. Visit the Git documentation page for the reference manual as well as tutorials to learn to use the system. The present article explains how to use Git with FreeCAD.

While Git is primarily a terminal application, there are many graphical clients for it which facilitate working with branches, applying patches, and submitting pull requests to a master branch. Examples include git-cola, gitg, and GitKraken. Please see Developing FreeCAD with GitKraken for a cursory introduction to this tool.

Source code access

Everybody can access and get a copy of the FreeCAD source code, but only the FreeCAD project managers have write access to it. You can get a copy of the code, study it and modify it as you wish. If you want your changes to be included in the official source code, you need to perform a pull request against the master repository so that your modifications can be reviewed by one of the managers.

If your source code changes are significant, you are advised to explain them in the pull request section of the FreeCAD forum.

Official GitHub repository

The FreeCAD source code is hosted in Github, https://github.com/FreeCAD/FreeCAD

In order to contribute code, you need to have a GitHub account.

Setting your git username

Developers should commit code to their personal repository using their GitHub username. If that is not already set globally, you can set it locally for the current Git repository like this:

git config user.name "YOUR_NAME"
git config user.email GITHUB_USERNAME@users.noreply.github.com

Where "YOUR_NAME" represents your full name or nickname, used to identify the author of a particular commit, and GITHUB_USERNAME indicates your GitHub username.

You can now use some combination of git add and git commit to create one or more commits in your local repository.

Remote repositories

Please read What is the difference between origin and upstream on GitHub? (Stackoverflow) to help you understand the difference between origin and upstream in the context of Git. This section explains how to set the correct repositories for development. Essentially:

  • origin is your personal fork of the official FreeCAD repository, that is, https://github.com/GITHUB_USERNAME/FreeCAD
  • upstream is the official FreeCAD repository, that is, https://github.com/FreeCAD/FreeCAD

This distinction is important, as you should push code to your own copy of the repository first, before pushing those changes to the official repository. If you clone from the upstream repository, the origin remote repository will point to the official repository. If you accidentally did this, you can use git remote rename to change the name of this remote to upstream.

git remote rename origin upstream

Based on the above, there are two ways to setup your Git development environment:

We recommend the 1st method because it's one step faster.

1st Method: Fork on GitHub and clone your fork locally

First you will fork the FreeCAD repository in GitHub, then clone this personal fork to your computer, and finally set the upstream repository.

  • Log in to your GitHub account.
  • Go to the official FreeCAD repository: https://github.com/FreeCAD/FreeCAD
  • In the top right of the page press the "Fork" button. This will create a personal copy of the FreeCAD repository under your GitHub username: https://github.com/GITHUB_USERNAME/FreeCAD
  • On your machine, clone your newly created FreeCAD fork. It will be created inside a directory freecad-source.
git clone https://github.com/GITHUB_USERNAME/FreeCAD.git freecad-source
  • Once the download is complete, enter the new source directory and set the upstream repository.
cd  freecad-source
git remote add upstream https://github.com/FreeCAD/FreeCAD.git
  • Confirm your remote repositories with git remote -v; the output should be similar to this
origin	https://github.com/GITHUB_USERNAME/FreeCAD.git (fetch)
origin	https://github.com/GITHUB_USERNAME/FreeCAD.git (push)
upstream	https://github.com/FreeCAD/FreeCAD.git (fetch)
upstream	https://github.com/FreeCAD/FreeCAD.git (push)

2nd Method: Clone FreeCAD directly to your local machine

First you will fork the FreeCAD repository in GitHub, however, you will clone the original FreeCAD repository to your local machine, and then alter your remotes via the terminal.

  • Log in to your GitHub account.
  • Go to the official FreeCAD repository: https://github.com/FreeCAD/FreeCAD
  • In the top right of the page press the "Fork" button. This will create a personal copy of the FreeCAD repository under your GitHub username: https://github.com/GITHUB_USERNAME/FreeCAD
  • Clone the original FreeCAD repository. It will be created inside a directory freecad-source.
git clone https://github.com/FreeCAD/FreeCAD.git freecad-source
  • Once the download is complete, enter the new source directory and set the origin repository.
cd freecad-source
git remote add origin https://github.com/GITHUB_USERNAME/FreeCAD.git
  • Then set up the upstream repository.
git remote add upstream https://github.com/FreeCAD/FreeCAD.git
  • Confirm your remote repositories with git remote -v; the output should be similar to this
origin	https://github.com/GITHUB_USERNAME/FreeCAD.git (fetch)
origin	https://github.com/GITHUB_USERNAME/FreeCAD.git (push)
upstream	https://github.com/FreeCAD/FreeCAD.git (fetch)
upstream	https://github.com/FreeCAD/FreeCAD.git (push)

Git Development Process

Never develop on the master branch. Instead, create a branch for development, and then merge this branch to the master branch. Please read Git Branching to learn more.

Branching

Best practices recommend creating a new branch whenever you want to work on a new feature. Creating a new branch is done in two steps, first your create the branch, and then you switch to it:

git branch myNewBranch
git checkout myNewBranch

Alternatively, use a single instruction:

git checkout -b myNewBranch

To see the branches in your project and the current branch you are using type

git branch

Committing

Once you are inside a new branch, edit the source files that you want. When you are ready to commit the changes issue

git commit -a

Unlike SVN, you need to specifically tell which files to commit; use the -a option to commit changes in all files that were changed. Your text editor will open to allow you to write a commit message.

Writing good commit messages

You should try to work in small chunks. If you cannot summarize your changes in one sentence, then it has probably been too long since you have made a commit.

For big changes, it is important that you have helpful and useful descriptions of your work. FreeCAD has adopted a format mentioned in book Pro Git.

Short (50 chars or less) summary of changes
 
 More detailed explanatory text, if necessary.  Wrap it to about 72
 characters or so.  In some contexts, the first line is treated as the
 subject of an email and the rest of the text as the body.  The blank
 line separating the summary from the body is critical (unless you omit
 the body entirely); tools like rebase can get confused if you run the
 two together.
 
 Further paragraphs come after blank lines. 
 
  - Bullet points are okay, too
 
  - Typically a hyphen or asterisk is used for the bullet, preceded by a
    single space, with blank lines in between, but conventions vary here

If you are doing a lot of related work in a branch, you should make as many commits as it makes sense (see a forum post). When you want to merge those changes into the master branch, you should issue

git log master..myNewBranch

to see the individual commit messages. Then you can write a high quality message for the merge message.

When you merge to master use the --squash option and commit with your quality commit message. This will allow you to be very liberal with your commits and help to provide a good level of detail in commit messages without so many distinct descriptions.

Pushing your work to your GitHub repository

After you've correctly committed modifications to your local branch in your computer, you can push this branch to your remote git server, that is, https://github.com/GITHUB_USERNAME/FreeCAD. This opens your branch to the public online, and allows other developers to review and integrate this branch into the official FreeCAD master branch.

git push origin myNewBranch

Please read Pushing commits to a remote repository for more information.

Advanced git operations

Check out GitHub requests locally

Checkout GitHub pull requests locally

Resolving merge conflicts

Applying patches via git

Git can merge patches or diffs. To know more about this process read Applying patches with Git.

git apply myCode.patch

You can use curl to download a patch, and apply it locally.

curl -O https://some/website.org/myCode.patch
git apply myCode.patch

Add .diff or .patch at the end of the URL of a GitHub commit, pull request, or compare view so that the website shows you the plain text view of that page.

You can point curl to a particular commit patch in the online Git repository, and pipe it to git apply to patch directly your local code.

curl https://github.com/FreeCAD/FreeCAD/commit/c476589652a0f67b544735740e20ff702e8d0621.patch | git apply -

Reversing a patch in git

When you apply a patch you modify some files. However, these modifications aren't permanent until you commit the changes. Therefore, if you want to revert a patch use the following instructions.

This will revert the changes applied, if you still have access to the patch file.

git apply -R myCode.patch

Alternatively, this will remove non-committed changes to the branch.

git checkout -f

Creating patches from git

There are times when it may be desirable to create a patch instead of submitting a pull request. The following workflow explains how to do this.

  • You should be developing your new code in a branch, and not in the master branch of your repository, so make sure you are in the correct branch.
git branch -v
git checkout myBranch
  • Now use git format-patch against the master branch, and use the --stdout option to redirect the result to standard output; then redirect the standard output to a patch file, which for convenience is located above the source code directory.
git format-patch master --stdout > ../myCode.patch
  • Another method is to use git format-patch HEAD^ or git format-patch HEAD~1. The ^ symbol or the number 1 indicate the number of commits that should be considered, that is, ^^^ or ~3 create a patch for three revisions.
git format-patch HEAD^

It will create a patch or series of patches with file name format

XXXX-commit-message.patch

where XXXX is a number from 0000 to 9999. The commit message is integrated into the name, for example,

0001-fix-ViewProjMatrix-getProjectionMatrix.patch

Stashing git commits

Say you're working on a branch and you find yourself making some modification to the source that is out of the scope of your current branch in other words it would be better to add certain commits to a whole other branch and submit it instead of the current one. This is where the git stash command can be very useful. The git stash command can help you to (temporarily but safely) store your uncommitted local changes.

git stash

Then in the future when you want to use these commits you can

git stash apply 

or

git stash pop

pop will delete the stash If you have multiple stashes you can

git stash list

To read more about what other functions you can use checkout https://medium.freecodecamp.org/useful-tricks-you-might-not-know-about-git-stash-e8a9490f0a1a

FreeCAD revision number

In contrast to subversion, which uses a consecutive number for its revisions, Git produces SHA-1 hash values with every commit. A hash value is a long alphanumeric string that looks like this

9b3ffef570596e184006287434fba54a4b03ccc3
0d8388a47a4dad11c57164629fa53b8eed50756e
33f749c96ed6b681f061b29f0ab7d8e8beb8c1ec

Latest revision number

To find the latest revision number of a particular branch use the rev-list operation with the --count option.

git rev-list --count master
git rev-list --count HEAD
git rev-list --count origin

Or browse the repository on GitHub, and read the amount of commits reported in the particular branch.

Revision number of a specific commit hash

Since the hash is an alphanumeric string it is not very useful to decide if a certain commit is older or newer than another hash. To find the revision number of a particular hash, again use the rev-list operation; the input can be the full hash, or a partial hash that is unique, usually the first 7 digits are enough.

git rev-list --count ab1520b872821414c6ce4a15fb85d471ac2a2b03
git rev-list --count 9948ee4

Revision hash of a specific commit number

If we have the commit number, say, 15000, and we want to find the corresponding hash, we need to calculate the number of commits since this point until the last commit (HEAD). First, get the latest commit number.

git rev-list --count HEAD
17465

Then subtract the commit that we want.

17465 - 15000 = 2465

Then use the log operation to show all commits and hashes. The --skip option jumps the difference in commits that we calculated so that we go directly to the hash that we are looking for.

git log --skip=2465
commit 44c2f19e380e76b567d114a6360519d66f7a9e24

Confirm it's the right commit number.

git rev-list --count 44c2f19e38
15000

Revision number in FreeCAD's interface

The version number that appears in Help → About FreeCAD → Copy to clipboard is defined in src/Build/Version.h, which is created at compile time when the cmake tool is run. Read Extract version number from git source for more information.

See the compile on Unix page for the full information on compiling FreeCAD.

Alternative repositories

The beauty of git is that everybody can clone a project, and start modifying the code. Several frequent collaborators of the FreeCAD project have their own git repository, where they build up their work before it is ready to be included in the official source code, or simply where they experiment new ideas. In certain cases, you might want to clone your FreeCAD code from one of these, instead of the official repos, to benefit from the changes their users did.

Be warned, though, that this is at your own risk, and only the official repository above is fully guaranteed to work and contain clean code.

It is also possible to attach several remote repositories to a same local FreeCAD git code, using the "git remote" command. This is useful to keep in sync with the master code branch, but keep an eye on the work of different developers.

Further reading