Skip to main content

Version control

What's version control ?#

Version control/source control is the practice of tracking changes to a code (might be a software or not), it gives the possibility of seeing the history of changes and writing or choosing the version to use when needed.

What's Git ?#

Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency

By distributed, it means that the complete history of a project can be replicated for all clients (unlike other systems like Svn), but it still needs a remote server though to allow actual collaborative work. There are many code hosting services based on Git, the most important ones are Github and Bitbucket which are the ones we use for our projects.

The minimum you need to know#

Here are the minimum commands/statement you should know, but we highly encourage you to go the furthest you can as:

  • the basic tool you will use every day (and doesn't seem to change for a very long time in the near future).
  • one of the highest return on learning investment ever as a developer.
  • going deeper into it will make you always gain in productivity, effectiveness and team cohesiveness.
  • one of the most perfect and well thought software ever.

clone a repo to your machine: git clone#

Make sure to create an SSH key in Github so that you can use SSH mode (otherwise if you use HTTP you will be required everytime to enter your Github/Bitbucket credentials).

example:

To clone the Obytes Handbook Github repo:

git clone [email protected]:obytes/ob-handbook.git

Get the latest version: git pull#

In order to get the latest version of a project you need to run git pull

Branches: git checkout#

A branch is a potential new version to the project, except the master branch which contains the project source of truth in terms of code version. For you as a developer to work on a project you need always to create a new branch using:

git checkout -b NEW_BRANCH_NAME where NEW_BRANCH_NAME ideally should be meaningful and/or contains a ref to a ticket (either in Github/Bitbucket or any other system: Linear...)

To switch you code to a given branch you just use the above Git statement without -b.

.gitignore#

.gitignore is a hidden file that contains regexes for files that you don't want to track in Git (idea files, pyc files...)

Collaborate: git status git add git commit git push#

After making your changes a code you need to send it in order for the team to be able to see it, discuss and either approve or request other changes. To do that you need:

  • git status shows you the changes that are ready for committing (pre-sending), if a file doesn't show in the unstated changes you can use git add YOUR_FILES where YOUR_FILES is the list of files, you can also use git add . to add all.
  • git commit YOUR_FILES (you can use -a instead of providing), you will be asked to provide a short description as a commit message, once you have committed a changes you can see that a new entry is added to history of the project (i.e: a commit correspond to a version of the code) git log
  • git push sends the commit(s) to the server.

Pull requests:#

Once you have pushed the changes to your branches, you need to submit those changes for review, for this you create a pull request (PR), you need to provide a description of what your code does, why you did it and references to docs or original tickets.

For this you need to go to Pull requests section in Github/Bitbucket to create a new one based on your branch.

Once your changes get approved you will need to merge your PR (by the click of a button), otherwise when asked to make new changes you just commit and push the new changes (they will automatically be added to your PR)

Frequent issues and cases you will encounter#

Branching-off#

Usually you should create your branches based on master branch (you create your branches while HEAD is on master) but if you made the mistake of:

  • if you branched-off from an old master: just run git fetch; git merge orign/master or git fetch; git rebase orign/master
  • if you branched-of from another branch containing changes that :
     - if you haven't committed your changes yet: stash them `git stash` and `git fetch; git reset --hard orign/master` then `git pop` - if you have committed already then: run `git log` and copy your commits ids, then go to master, pull the latest version and create a nez branch, then `git cherry-pick` you commits

Can't push#

Usually when you cannot pull or push it can be one of:

  • you were removed from the repo: ask your admin to re-add you again
  • no write access: ask admin to grant you write access
  • protected branches: you are trying to push to master branch, create a new branch and push.
  • outage: could be a Github/Bitbucket outage: check respective status pages to make sure.

Who did this: git blame#

In order to author of a line or commit, it's useful in order to know the right person to ask about codebase.

git stash / git pop#

Sometimes you need to save current changes without committing them (in case you need to switch quickly to work on something else): use git stash to "hide them" and git pop to bring them back.

git cherry-pick#

To cherry-pick a commit is to choose a commit from one branch and apply it onto another.

Stall changes/code conflict#

Sometimes, when you make change to some code (files), someone else could change the same code (files) in this case if he merges first, you will get a message asking you to resolve conflicts, in some cases if it's simple it will resolve automatically by the click of a button, but sometimes you need to pull code and resolve manually.

So, in order to avoid your code being stall, ask quickly for a code review and address any requests as quick as you can.

History change#

Please don't use the following when others are working on the same branch as it means you would cancel each others changes to the branches.

git reset#

Your code versioning should be thought of as a history of commits linked one to other (like a tree) anything you are committing or merging you are adding new commits to the commits history without changing the existing history of commits:

this is an example of the commits (sub)tree of Obytes hanbook:

$ git log --graph --oneline --all* 3ace6a3 (HEAD -> be-mou55, origin/be-mou55) BE: version control (wip)* 7cacaf7 cleanup* f3990a1 BE skeleton| * b53b0c2 (origin/feat/nextjs) Adding NextJS section in docs/front-end/getting-started/create-react-app.md|/  *   5d78098 (origin/master, origin/HEAD, master) Merge pull request #20 from obytes/lemaadi/heroku-handbook-update|\  | * ebcf033 (origin/lemaadi/heroku-handbook-update) fix build| * c31938f Add Heroku Exec - SSH Tunneling|/  *   5729c6d Merge pull request #19 from obytes/mobile-update-2|\  | * dfbab98 (origin/mobile-update-2) fix typos| * 4ebd106 fix App build guide| * da23c61 add Template to get started guide| * 86dbb00 add project Structure Guide| * d54570c fix auth code source| * dd01de5 add guide for using env vars| * 652cf8f more RN  resources|/  *   eaaa134 Merge pull request #18 from obytes/mobile_update|\  | * 47c26f5 fix home page broken link| * 7b0e7a4 Add handling forms guide| * 17453c7 add handling Error guide...

you can see that HEAD is pointing to 3ace6a3 commit, if you need to change that pointer you can use 'git reset', but it's highly not recommended to do it when others work on the same branch.

git push -f#

If you change the commits tree (either by git reset or rebase...) you cannot push directly unless you force it.

git rebase#

Rebasing is the process of moving or combining a sequence of commits to a new base commit

This can be useful for example instead of merging changes to master over and over to make it up to date as you can get a lot of merge commits in the hitsory of your PR you can chose to rebase your branch on master which means put your commits on top of master branch commits tree. Also it's the preferable merging method (squash and rebase) since it's the most elegant.

git revert#

you can revert a commit using git revert COMMIT_ID

Keeping repo clean#

  • Use comprehensive commit messages
  • Make small PRs as possible as you can, because easier to review and revert
  • changes should be consistent (consider making more than one PR otherwise)
  • Describe well your PRs
  • Quickly (as possible as you can) respond to PR reviews request/answers and merge.
  • Privilege "squash and merge" merge method

Documentation#

Last updated on by Moussa IDARDAR