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.
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.
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:
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).
- https://docs.github.com/en/[email protected]/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
To clone the Obytes Handbook Github repo:
git clone [email protected]:obytes/ob-handbook.git
Get the latest version:
In order to get the latest version of a project you need to run
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
.gitignore is a hidden file that contains regexes for files that you don't want to track in Git (idea files, pyc files...)
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 statusshows 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_FILESwhere YOUR_FILES is the list of files, you can also use
git add .to add all.
git commit YOUR_FILES(you can use
-ainstead 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 pushsends the commit(s) to the server.
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)
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/masteror
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
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:
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 /
Sometimes you need to save current changes without committing them (in case you need to switch quickly to work on something else):
git stash to "hide them" and
git pop to bring them back.
To cherry-pick a commit is to choose a commit from one branch and apply it onto another.
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.
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.
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.
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.
you can revert a commit using
git revert COMMIT_ID
- 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
- To really go in depth check:
"Git Plumbing (and Porcelain) commands