-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Quick Start
- Obtain Git repository
- Status
- New feature branch
- Switching branches
- Other branches
- diff/log
- Revert last commit
- Comparing Branches
- Branch completion
This guide gives a quick introduction to using Git with CGAL.
Beyond, it is valuable to read more "Getting Started" information available on Git's website such as the Git tutorial. There is also plenty of nice documentation on the web, e.g. the Git community Book. Some fundamental concepts are nicely explained here, and, about Git and Tortoise Git there (nice course notes, in french).
In the following commands of the command-line client of Git (git
on
Linux/macOS, git.exe
on Windows Cygwin) are given. They naturally
translate to GUI-guided actions. Intuitive GUIs exists. For instance,
for Windows (TortoiseGit, which is similar to TortoiseSVN, or
Git Extensions, that integrate
into Visual Studio) and macOS (Sourcetree) or both (SmartGit)
and many others. Feel free to explore the web and choose a GUI to your
preference and wallet (or stay with the command-line client). Cloning,
branching, committing, merging is equivalent (or even simpler) in GUIs.
Please refer to tutorials on the web how to install them (e.g. for
TortoiseGit).
See also our FAQ.
Beyond the following, and for reference reasons, check the Git Cheat Sheet.
Jenny has Git installed. Next Jenny needs to set once some basic variables. She uses the following commands (while replacing personal information!):
# required variables
> git config --global user.name "Jenny Doe"
> git config --global user.email "jenny.doe@example.com"
# useful variables
## pretty
> git config --global color.branch auto
> git config --global color.diff auto
> git config --global color.interactive auto
> git config --global color.status auto
## religious statement about editor preference
> git config --global core.editor "emacs"
git config --global
stores the values for these variables in a Jenny's
.gitconfig
file.
Now Jenny is ready to get her own local repository by cloning the remote repository on our server:
> git clone -o cgal-public-dev git@github.com:CGAL/cgal-public-dev.git my_cgal_folder # If you are a CGAL student
Master and release branches are not writable by regular developers. Jenny needs to add another remote and add a local master branch:
> cd my_cgal_folder
> git remote add cgal git@github.com:CGAL/cgal.git
> git fetch --all
> git checkout -b master cgal/master
The local repository is a full clone of the remote repository which includes all branches and tags, and is stored in very efficient compressed fashion. Its size is about 850 MB. Cloning also checks out the integration branch.
At this point we also strongly recommend to run
> cd my_cgal_folder
> ./Scripts/developer_scripts/cgal_git_update_hooks_for_client
which installs a pre-commit hook to Jenny's local repository (Windows users: there is a git-bash in the context menu of Git in which you can run the script). The hook gives you early alerts for commit that will be rejected by the central repository when you try to push your changes to it.
With:
> git branch
* master # the star marks the current branch
integration
Jenny sees on which branch she is currently working on. Here she is
working on the local master
:
> ls
AABB_tree
Algebraic_foundations
Algebraic_kernel_d
...
iostream
kdtree
wininst
You can add another remote like this:
# go into your cgal git repository folder and then
> git remote add cgal-public-dev git@github.com:CGAL/cgal-public-dev.git
# After that
> git fetch cgal-public-dev
# brings in all branches from the cgal-public-dev repository.
> git branch -a
# will show the branches:
remotes/cgal-public-dev/hooks-for-clients
remotes/cgal-public-dev/hooks-on-server
remotes/cgal-public-dev/gsoc2013-XXXX-student
# Starting to work on such a branch works as for branches on "cgal-public-dev" - see the guidelines
git push cgal-public-dev gsoc2017-XXXX-student
To check the status of the current branch she uses
> git status
# On branch master
nothing to commit (working directory clean)
git status
also shows the status of all files (modified, staged,
deleted, etc) in the repository - no matter whether Jenny is the root
level of the repository or in a subdirectory.
In order to start a feature development she comes up with a name for a
branch following our naming conventions,
here Mesh_9-jenny
, and then uses
> git checkout -b Mesh_9-jenny --no-track cgal/master
Switched to a new branch 'Mesh_9-jenny'
> git branch
master
* Mesh_9-jenny
This command creates a local branch Mesh_9-jenny
from the master
branch and checks it out. It is shorthand for:
> git checkout master
> git branch Mesh_9-jenny
> git checkout Mesh_9-jenny
Next, Jenny can alter files and commit changes and check the status
again with git status
. Before committing, she uses
> git add [myfiles.hpp]
> git commit
[Mesh_9-jenny 6341737c37db] Message
1 file changed, 1 insertion(+)
git add
to add a file to the index (list of files scheduled for next
commit), while commit
really executes the commitment (of all indexed
files - in the version they have been added to the index!)
Remarks:
- Note that every "commit" is only done to the local repository. It stores all previous and new commit information.
- Each commit gets assigned a SHA-1 hash (a cryptographically
tamper-proof signature of your file contents), here
6341737c37dbcd932e6646eac2347d9402f12b07
. For convenience these hashes can be abbreviated with the first chars only (seven is usually sufficient to uniquely identify a commit). It is also mentioned to which branch Jenny has committed (here "Mesh_9-jenny"). * In case you want to abort the commit, you simply do not write any commit message!
The next step is synchronize the local changes with the remote location.
In order to avoid wrong pushes to master
, Jenny adds this to her
configuration
> git config --add push.default simple
# In even older Git version (<1.7.11) 'simple' must be replaced with 'current' or 'tracking' (for even older versions)
This refuses a push if the local and remote branchnames do not match
(check whether other repositories also need this option - or whether you
want to add it to you global .gitconfig
- can be done by adding
--global
option). Though this should now happen if she initially
pushes with the -u
flag. Jenny sends the branch onto the remote
repository she cloned from ("cgal-public-dev"):
> git push -u cgal-public-dev Mesh_9-jenny
Let's explain this in more detail: The push
mirrors the local branch
Mesh_9-jenny
into the remote repository "cgal-public-dev". This way her
branch becomes available to everybody with access to the "cgal-public-dev"
repository - and her commits get also backup'ed in the remote location.
The -u
option not only publishes the branch on the remote, but also
sets it as a tracking branch of her local branch. Every future
> git push
will publish her local changes onto cgal-public-dev.
Jenny now has two local branches, she is in Mesh_9-jenny and she can switch back to master with
> git checkout master
By using
> git branch -a
* Mesh_9-jenny
master
remotes/cgal/master
remotes/cgal-public-dev/Mesh_9-jenny
remotes/cgal-public-dev/Kernel-rewrite_functors-adam
can see a list of all local branches and all branches on the configured remotes.
If Jenny wants to work on one of those remote branches she uses
> git checkout -b Kernel-rewrite_functors-adam cgal-public-dev/Kernel-rewrite_functors-adam
That command creates a local branch named
Kernel-rewrite_functors-adam
as a copy of the current state of the
remote branch cgal-public-dev/Kernel-rewrite_functors-adam
. Be careful that
the branch name appears twice: after -b
, and after cgal-public-dev/
. The
branch name after -b
is actually a free name you can choose, where as
cgal-public-dev/some_name
refers to an existing referenced branch on the
remote repository cgal-public-dev
.
Again she alters files:
> git add [otherfiles.hpp]
> git commit
And finally she pushes her changes back to the remote location.
As some Git versions (e.g. 1.7.9.5) set no default upstream branch for push, Jenny adds this to her configuration
> git config --add push.default simple
# In even older Git version 'simple' must be replaced with 'current' or 'tracking' (for even older versions)
If this is set (or the Git version is new enough) the following suffice
to push changes to cgal-public-dev
> git push
Note that here the tracking of the upstream branch
cgal-public-dev/Kernel-rewrite_functors-adam
is correct, thus a git push
suffices.
In order to update her branch from the remote repository, Jenny gets the changes into her local repository with:
> git fetch
> git merge
We refer Jenny for full details on how to work with branches to the section on how to use branching in Git for code development.
git log
is used to inspect the revision history of a file, repository
or branch.
> git log # plain log of current repository
> git log --follow -- filename # file history, including before renames
> git log -p # add diffs
> git log --since=2.weeks # commits of the last 2 weeks
git diff
is used to inspect the changes between commits
> git diff # the difference between the working copy and the index
> git diff --cached # the difference between the index and the last commit
> git diff HEAD HEAD^ --stat # the changed files between the last commit and the commit that came before
> git diff HEAD HEAD^ -- my_file.h # same as above, but just for my_file.h
> git diff master..my_branch # diff between master and my_branch
There are several scenarios: * the bad commit wasn't pushed yet * the bad commit was already pushed to a remote * the commit is not really that bad, wasn't pushed yet and can be fixed easily
In the first case, git reset --hard HEAD^
resets your repository to the
commit just before the last one. All changes in the last commit will be
lost.
In the second case, git revert commit_name
followed by a git push
is
one of the less intrusive options. It will create a new commit that
reverts the old one.
In the third option, git commit --amend
can be used to modify the
current HEAD commit. This is useful if something has been forgotten in
the last commit.
Sometimes it is useful to see if a branch is actually a subset of another, e.g. if all commits of a local branch have been pushed to the remote.
> git log cgal-public-dev/my_branch..my_branch
# if empty, everything is pushed
Similarly,
> git log --branches --not --remotes
will show all commits on local branches that are not present on remote
branches. The options --decorate --graph
can be added to decorate the
result of the git log
command with the name of the branches involved,
and the drawing (in ASCII) of the graph of commits.
The above commands are also useful to check if a release branch is a subset of an integration branch and which commits are still candidates to be picked.
The Bash completion system offers completion for branches and prompt modifications (to display current branch in prompt). Google is your friend.
General Information
- Information for New Developers
- Developing with Git
- Structure of a CGAL Package
- Building
- Concurrency in CGAL
- License
- Documentation Guidelines
- Reviewing Process
- Testing
- Miscellaneous
- Tools
- Scripts
- Libraries
- Infrastructure
- Releases
- Miscellaneous