Code doesn't exist unless it's checked into a version control system. Use version control for everything you do. Any version control, SVN, Git, even CVS, master it and use it.
— svn - Why should I use version control? - Stack Overflow
Goals:
- Use a Git gepository with multiple users
- Apply the concept of Branching/Merging
- Avoid merge conflicts
- Work with Git in RStudio Terminal
Aka "a successful Git branching model" has been around since 2010 and is still widely used today. From its extensive concept about branching we focus on the two main branches:
The main branches
At the core, the development model is greatly inspired by existing models out there. The central repo holds two main branches with an infinite lifetime:
- master
- develop
The master branch at origin should be familiar to every Git user. Parallel to the master branch, another branch exists called develop. We consider origin/master to be the main branch where the source code of
HEAD
always reflects a production-ready state.
We consider origin/develop to be the main branch where the source code ofHEAD
always reflects a state with the latest delivered development changes for the next release. [...] When the source code in the develop branch reaches a stable point and is ready to be released, all of the changes should be merged back into master somehow [...].
— Vincent Driessen, Git flow
in short
HEAD
of origin/master = production-ready state- Changes merged into master = production release by definition
HEAD
of origin/develop = latest developments
in addition
- Only commit finished features, bugfixes, etc.
- Merge commits using the
--no-ff
flag
You can manage the groups and users and their access levels in all of your projects. You can also personalize the access level you give each user, per-project.
You should have Maintainer or Owner permissions to add or import a new user to your project. To view, edit, add, and remove project's members, go to your project's Settings > Members.
- Navigate to your project's Settings > Members.
- Select members to invite.
- Coose a role permission.
👉 See Project members permissions for more information. - Click "Add to project".
ℹ️ See also GitLab Help > Project > Members.
Users have different abilities depending on the access level they have in a particular group or project. If a user is both in a group's project and the project itself, the highest permission level is used.
On public and internal projects the Guest role is not enforced. All users will be able to create issues, leave comments, and clone or download the project code.
While Maintainer is the highest project-level role, some actions can only be performed by a personal namespace or group owner.
The following table depicts the various user permission levels for the most important actions in a project.
Action | Guest | Reporter | Developer | Maintainer | Owner |
---|---|---|---|---|---|
Download project | ✓ (1) | ✓ | ✓ | ✓ | ✓ |
Leave comments | ✓ (1) | ✓ | ✓ | ✓ | ✓ |
View project code | ✓ (1) | ✓ | ✓ | ✓ | ✓ |
Pull project code | ✓ (1) | ✓ | ✓ | ✓ | ✓ |
Create new issue | ✓ (1) | ✓ | ✓ | ✓ | ✓ |
Assign issues | ✓ | ✓ | ✓ | ✓ | |
Label issues | ✓ | ✓ | ✓ | ✓ | |
See a list of merge requests | ✓ | ✓ | ✓ | ✓ | |
Create new merge request | ✓ | ✓ | ✓ | ✓ | |
Create new branches | ✓ | ✓ | ✓ | ||
Push to non-protected branches | ✓ | ✓ | ✓ | ||
Force push to non-protected branches | ✓ | ✓ | ✓ | ||
Remove non-protected branches | ✓ | ✓ | ✓ | ||
Assign merge requests | ✓ | ✓ | ✓ | ||
Manage/Accept merge requests | ✓ | ✓ | ✓ | ||
Add new team members | ✓ | ✓ | |||
Enable/disable branch protection | ✓ | ✓ | |||
Push to protected branches | ✓ | ✓ | |||
Turn on/off protected branch push for devs | ✓ | ✓ | |||
Edit project | ✓ | ✓ | |||
Edit comments (posted by any user) | ✓ | ✓ | |||
Switch visibility level | ✓ | ||||
Transfer project to another namespace | ✓ | ||||
Remove project | ✓ | ||||
Delete issues | ✓ | ||||
Force push to protected branches (2) | |||||
Remove protected branches (2) |
- (1): Guest users are able to perform this action on public and internal projects, but not private projects.
- (2): Not allowed for Guest, Reporter, Developer, Maintainer, or Owner.
ℹ️ See GitLab Help > Projects > Protected Branches.
ℹ️ See also GitLab Help > User > Permissions.
The GitLab issue tracker is an advanced tool for collaboratively developing ideas, solving problems, and planning work.
Issues can allow you, your team, and your collaborators to share and discuss proposals before, and during, their implementation. However, they can be used for a variety of other purposes, customized to your needs and workflow.
Common use cases include:
- Discussing the implementation of a new idea
- Tracking tasks and work status
- Accepting feature proposals, questions, support requests, or bug reports
- Elaborating on new code implementations
ℹ️ See also GitLab Help > Project > Issues.
Labels allow you to categorize issues and merge requests using descriptive
titles like bug
, feature request
, or docs
. Each label also has a
customizable color. They allow you to quickly and dynamically filter and manage
issues and merge requests you care about, and are visible throughout GitLab in
most places where issues and merge requests are located.
ℹ️ See also GitLab Help > Project > Labels.
To create a default set of labels for your project and add default lists to the Issue Board:
- Navigate to your project's Issues > Labels.
Click "Generate a default set of labels". - Navigate to your project's Issues > Boards.
Click "Add default lists".
See Use cases > Single user, shared.
👉 Using RStudio Terminal.
See Use cases > Multiple users.
- List existing branches:
git branch
- Switch branch, if necessary:
git checkout <branch>
- Pull changes from origin (GitLab):
git pull
- Modify files in your working directory.
- Add files to the staging area:
❗ Everything not intentionally specified in a ".gitignore" file to be untracked (ignored) will be added to the staging area.
git add .
- Commit changes to the local repository:
git commit
git commit
opens an editor to edit the commit log message and creates a new commit containing the current contents of the staging area. - Push branch to origin (GitLab):
git push
- Develop your code on branch develop.
- Switch to branch develop:
git checkout develop
- Modify files in your working directory.
- Add files to the staging area:
git add .
- Commit changes to the local repository:
git commit
- Push branch develop to origin (GitLab):
git push
- Switch to branch develop:
- Publish your code on branch master.
- Switch to branch master:
git checkout master
- Merge branch develop with it:
git merge --no-ff develop
- Push branch master to origin (GitLab):
git push
- Switch back to branch develop:
git checkout develop
- Switch to branch master:
Level "Developer" (or higher)
- Develop your code on a <separate branch>:
- Create <separate branch> from branch develop:
git checkout develop git pull git checkout -b <separate branch>
- Modify files in your working directory.
- Add files to the staging area:
git add .
- Commit changes to the local repository:
git commit
- Create <separate branch> from branch develop:
- Prepare for merge request:
- Checkout target branch (develop) and pull latest changes:
git checkout develop git pull
- Checkout <separate branch> and merge develop with it:
git checkout <separate branch> git merge --no-ff develop
- Resolve any merge conflicts on the <separate branch>.
git diff ... git add . git merge --continue
- Push <separate branch> to origin (GitLab):
git push
- Checkout target branch (develop) and pull latest changes:
- Ask "Maintainer" (or higher) to merge.
Level "Maintainer" (or higher)
- Merge <separate branch> into branch develop
- Checkout <separate branch> and pull latest changes:
git checkout <separate branch> git pull
- Checkout branch develop and merge <separate branch> with it:
git checkout develop git merge --no-ff <separate branch>
- Push branch develop to origin (GitLab):
git push
- Checkout <separate branch> and pull latest changes:
Given an existing commit on one branch, apply the change to another branch:
- Checkout the <one branch> with the existing commit and pull the latest
changes:
git checkout <one branch> git pull
- Get the desired commit SHA from GitLab or going through
git log
:git log --abbrev-commit --abbrev=8
- Get the desired commit SHA from GitLab or going through
- Checkout <another branch> and pull the latest changes:
git checkout <another branch> git pull
- Cherry pick the commit using the SHA obtained earlier:
git cherry-pick <commit>
- Push <another branch> to origin (GitLab):
git push
Like most VCSs, Git has the ability to tag specific points in a repository’s history as being important. Typically, people use this functionality to mark release points (
v1.0
,v2.0
and so on).
To create a new tag execute the following command:
git tag <tagname>Replace
<tagname>
with a semantic identifier to the state of the repository at the time the tag is being created.[...]
Sharing tags is similar to pushing branches. By default,
git push
will not push tags. Tags have to be explicitly passed togit push
, e.g.:git push origin v1.0To push multiple tags simultaneously pass the
--tags
option togit push
command:git push --tagsWhen another user clones or pulls a repo they will receive the new tags.
— Atlassian Git Tutorial - git tag
ℹ️ See Git - Tagging and Atlassian Git Tutorial - git tag for more information on annotated tags, lightweight tags, tagging old commits, deleting tags, etc.
Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate.
To add a new submodule you use the git submodule add
command with the absolute
or relative repository URL of the project you would like to start tracking:
git submodule add <repository>
ℹ️ By default, Git checks out the default branch (master)
Also by default, submodules will add the subproject into a directory named the same as the repository. You can add a different path at the end of the command if you want it to go elsewhere.
You should notice two things:
- The new
.gitmodules
file. This is a configuration file that stores the mapping between the project’s URL and the local subdirectory you have pulled it into. - The subproject's folder entry. Git sees it as a submodule and does not track its contents when you are not in that directory. Instead, Git sees it as a particular commit from that repository.
When you clone such a project, by default you get the directories that contain submodules, but none of the files within them yet.
You must run the two following commands to initialize your local configuration file, fetch all the data from that submodule and check out the appropriate commit listed in your project:
git submodule init
git submodule update
The simplest model of using submodules in a project would be if you were simply consuming and wanted to get updates from it from time to time but were not actually modifying anything in your checkout.
If you run git submodule update --remote
, Git will go into your submodules and
fetch and update for you. This command will by default assume that you want to
update the checkout to the master branch of the submodule repository.
— According to Git - Submodules
ℹ️ Check Git - Submodules for more information about "Working on a Project with Submodules", "Submodule Tips" and "Issues with Submodules".
git merge --no-ff <branch>
incorporates changes from the named<branch>
into the current (checked out) branch.
👉git merge
is used bygit pull
to incorporate changes from another repository (default: origin).
The
--no-ff
flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a [...] branch and groups together all commits [...]. Compare:
— Vincent Driessen, Git flow
git branch
without any arguments lists existing branches; the current branch will be highlighted in green and marked with an asterisk.git stash
saves your local modifications away and reverts the working directory to match theHEAD
commit.
👉 Callinggit stash
without any arguments is equivalent togit stash push
.git stash pop
applies the stashed (saved) state on top of the current working directory state, i.e. does the inverse operation ofgit stash push
.
Pulling into a dirty tree
When you are in the middle of something, you learn that there are upstream changes that are possibly relevant to what you are doing. When your local changes do not conflict with the changes in the upstream, a simplegit pull
will let you move forward.However, there are cases in which your local changes do conflict with the upstream changes, and
git pull
refuses to overwrite your changes. In such a case, you can stash your changes away, perform a pull, and then unstash, like this:$ git pull ... file foobar not up to date, cannot merge. $ git stash $ git pull $ git stash pop
— Git - git-stash Documentation > Examples
If you already have pushed to a remote repository:
git revert <commit> ...
is used to make a new commit to reverse the effect of some earlier commits (often only a faulty one).
👉 This requires your working directory to be clean (no modifications from theHEAD
commit).
If you only have committed to the local repository:
-
git reset --hard
resets the staging area and working directory. Any changes to tracked files in the working directory since theHEAD
commit are discarded.
ℹ️git reset --hard
is a synonym forgit reset --hard HEAD
. -
git reset --hard HEAD^
resets the staging area and working directory to the state of the second to last commit (i.e. the commit before theHEAD
commit). -
git reset --hard origin/<branch>
resets the staging area and working directory and makes the local branch exactly the same origin/<branch>.❗
git reset
is of destructive nature as it deletes files as well as commits.
There are two commands with similar names:
git revert
andgit reset
.
git revert
is about making a new commit that reverts the changes made by other commits.
git reset
is about updating your branch, moving the tip in order to add or remove commits from the branch. This operation changes the commit history.
git reset
can also be used to restore the staging area.
— Adapted from Git - git Documentation > Git commands > Reset, restore and revert
With GitLab Groups, you can:
- Assemble related projects together.
- Grant members access to several projects at once.
Find your groups by clicking Groups > Your Groups in the top navigation.
The Groups page displays:
- All groups you are a member of, when Your groups is selected.
- A list of public groups, when Explore public groups is selected.
Each group on the Groups page is listed with:
- How many subgroups it has.
- How many projects it contains.
- How many members the group has, not including members inherited from parent groups.
- The group's visibility.
- A link to the group's settings, if you have sufficient permissions.
- A link to leave the group, if you are a member.
You can create groups for numerous reasons. To name a couple:
- Grant access to multiple projects and multiple team members in fewer steps by organizing related projects under the same namespace and adding members to the top-level group.
- Make it easier to
@mention
all of your team at once in issues and merge requests by creating a group and including the appropriate members.
ℹ️ See also GitLab Help > Groups.
Subgroups, also known as nested groups or hierarchical groups, allow you to have up to 20 levels of groups.
By using subgroups you can do the following:
- Separate internal organizations. Since every group can have its own visibility level, you are able to host groups for different purposes under the same umbrella.
- Organize large projects. For large projects, subgroups makes it potentially easier to separate permissions on parts of the source code.
- Make it easier to manage people and control visibility. Give people different permissions depending on their group membership.
ℹ️ See also GitLab Help > Groups > Subgroups.
git reset
is of destructive nature as it deletes files as
well as commits.
Did it happen during the last commit? Just throw it away:
git reset --hard HEAD^
Did it happen some commits ago? Reset to an older commit:
git reset <commit>
ℹ️ Get the desired commit SHA from GitLab or going through
git log
.
See Git - git reset Documentation
for other modes than --hard
.
As long as you are working as single user, private or single user, shared you are fine. Just use one of the commands above and force push to the remote repository:
git push --force
ℹ️ If you intend to force push to either branch master or develop you must unprotect it first. See GitLab Help > Projects > Protected Branches.
If you are working on a project with
multiple users, force pushing might cause
your collaborators major pain, because you are changing history.
👉 Send them a note and inform about what you are going to do.
See also Git pretty on how to escape a Git mess, step-by-step.
Follow the instructions on GitLab Help > Projects > Settings > Exporting a project and its data.
ℹ️ You find "Export project" in Settings > General > Advanced.
You may import the project back into GitLab at any time. If you are only interested in the Git repository itself, follow the instructions below.
GitLab exports a .tar.gz file which contains a file called "project.bundle". You can convert this file into a normal Git repository using RStudio Terminal.
First, upload the .tar.gz file to a temporary folder in RStudio (e.g.
~/temp
).
Extract the project.bundle file
cd ~/temp
tar xvfz <gitlab-export>
Restore the bundle to a Git repository
mkdir ~/projects/<repository-name>
git clone --bare project.bundle ~/projects/<repository-name>/.git
cd ~/projects/<repository-name>
git init
git checkout master
Change origin to a repository on GitLab
git remote set-url origin [email protected]:<user>/<project-name>.git
git push -u origin master
👉 <user>
and <repository-name>
depend on your setup.
Repeat
git checkout <branch>
git push -u origin <branch>
for every branches you intend to push to GitLab.
Delete temporary folder
rm -r ~/temp
— Adapted version of Converting a gitlab export to simple git repo
References
- Git flow: https://nvie.com/posts/a-successful-git-branching-model/
👉 Also available at references/a-successful-git-branching-model.html in RStudio. - Git Reference: https://git-scm.com/docs
- Escape a Git mess, step-by-step: http://justinhileman.info/article/git-pretty/full/
👉 Open figures/git-pretty.png to access the file locally.
- Escape a Git mess, step-by-step: http://justinhileman.info/article/git-pretty/full/
Cheat sheets
- GitLab cheat sheet: cheat-sheets/git-cheat-sheet.pdf
- GitHub cheat sheet: cheat-sheets/git-cheat-sheet-education.pdf
- Visual Git cheat sheet: https://ndpsoftware.com/git-cheatsheet.html
👉 Open cheat-sheets/git-cheatsheet.html in RStudio to access the web page locally.