Git cheatsheet
As a developer, you might want to learn a lot of different coding languages. However, something you have to learn before anything if you are working with a team is how to use a version control system. The most used is git. In this cheatsheet I will share with you an overview of all the basics command you need for day to day tasks using git.
Initialize a new project
When you create a new project, you need to initialize it to be able to push it remotely on github or gitlab. Here are the steps you need to follow.
Create the repository on github/gitlab
The first option is to start by creating your repository online on github or gitlab. To do so, you need to have an account on the platform and create a new repository. You can choose the privacy level of it etc…
You can create a folder with the name of your project. For me it will be git-presentation. Then insite your folder you can run these commands to link your folder to github.
echo "# git-presentation" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M master
git remote add origin git@github.com:sounissi/git-presentation.git
git push -u origin master
Import an existing repository
If you already have a project on your machine, and you want to push it on git start by creating a new project on github or gitlab with the same name as your project. Then run these commands :
git remote add origin git@github.com:sounissi/git-presentation.git
git branch -M master
git push -u origin master
Now you have initialized your project with a master branch. You can start working on it alone or with a team.
Clone a project
Most of the time when you arive in a new team, you have to clone many existing git repository on your machine. To do so, you need to get the git url. Most of the time you have two options to clone : either use SSH link or the HTTPS link. It depends on the configuration you setup with your github accout.
HTTPS
git clone https://github.com/sounissi/git-presentation.git
SSH
git clone git@github.com:sounissi/git-presentation.git
Handle branches
Once you start working on a repository, the best thing is always to create a new branch. Avoid working directly on the master branch!!
Here are the commands to create a new branch and to push it.
git checkout -b first-branch
git push --set-upstream origin first-branch
You may also want to remove a branch. If it is a local branch then run :
git checkout master
git brand -D first-branch
If you also want to remove the distant branch you have to do this instead :
git push origin --delete first-branch
Push your work
Now that you are on a branch you can start working on your feature or fix. Be sure to divide your work methodically to be able to push each feature or fix in a single commit. Commits have to be small and easy to read. Imagine a colleague reviewing your code commit by commit, so be sure to make it easy for him to understand your work.
To see the list of files you modified you can run :
git status
Then you can add the files to stage them. The files added will be the pushed, the one that you don’t add will stay localy on your machine. There are different options to add your files :
git add -A
git add .
git add path/file
The two first commands will add all the files modified. And with the third command you can specify the files you want to stage.
Now that your files are ready, you can commit. A commit needs a message. Your message needs to be short and clear. If it is too long, it might be because you have too many modifications inside one single commit. It’s a hint to reorganize your work into smaller pieces. Also, check if your team uses some lint rules on the commits to help uniformize them.
git commit -m "first commit"
A vim editor will open up and display the commit message. If everything looks good for you you can save and quit (:wq)
Time to push you commit to the remote repository and share it with your team.
git push
Note : before pushing, make sure no one pushed a commit on the branch you are working on before you.
Pull the distant modifications
Working with git means that other people might also be working at the same time on the same project. You will have to stay up to date and pull the modifications of your colleagues regularly. Here is how to get the lastest version of master for exemple.
git checkout master
git pull
Rebase your branch on master
Imagine you are working on your branch first-branch, and you pushed some commits. However, the master branch is evolving at the same time and contains changes that you want to pull to stay up to date on your branch. Your git tree will look like this :
A—B—C first-branch
/
D—E—F—G—H master
And what you want to have is this git tree where your branch moved on top of the latest changes of master.
A’- -B’- -C’ first-branch
/
D- -E- -F- -G- -H master
And what you want to have is this git tree where your branch moved on top of the latest changes of master.
Initiate the rebase
First, you need to be sure you have the latest version of master on your machine. So you start to checkout master and pull it.
git checkout master
git pull
Now that your master is up-to-date, you can go back to your branch and rebase on master.
git checkout first-branch
git rebase master
Now the result depends on the modifications that happened on the master branch. Either everything will go well, and the rebase will succeed from the first try. Or you will have some conflicts, and you will need to resolve them before being able to push everything.
Best case scenario
The rebase has no conflicts, you can push force and your rebase is done. You have to use push force because you are rewriting your git history, so a classic push won’t work in this situation.
git push -f
Worst case scenario
You have some conflicts. Take the time to resolve the conflicts in your IDE. Once it’s done, you can continue to rebase and push.
git rebase --continue
git push -f
Push force with security
Git push force is needed in many situations where you re-write the git history. However, it can be dangerous if you didn’t check if any of your colleagues pushed something on your current branch in the meantime. The result with a git push –force is that your changes on your branch will be pushed and will erase any current version that is different from yours.
Hopefully, there is an option to use to avoid these kinds of problems. I wish I knew that a few years ago when a senior dev colleague yelled at me because I pushed forced on top of his latest commit.
The command to use is the following :
git push --force-with-lease
This command will push force if no one pushed something in between. But if it sees any new commits, it will display a warning message and abort the push. Be sure to use this if you are working on the same branch with other colleagues to avoid any unnecessary accidents.
Amend a commit
If you forgot to add something on your lastest commit you have the option to change it. The command to use is git amend. You can stage new files with git add and one you get to the commit stage here is what you can do instead of creating a new commit message.
git commit --amend
With this command, the editor vim will open up and display the name of your latest commit message. You can modify it or leave it as it is and quit. If you don’t want to modify the message, you can use this command to avoid this step.
git commit --amend --no-edit
Now you can push your modified commit using git push force.
git push -f
Merge your branch on master
When you work on your branch, the purpose is to then merge your content in the master branch. So your git tree would look like that.
A—B—C first-branch
/
D—E—F—G—H master
After a merge it would look like this.
A- -B- -C first-branch
/ \
D- – E- -F- -G master
This is how to merge your branch in the master branch.
git checkout master
git merge first-branch
The merge will create a commit with the names of the two parent commits and a log from the user.
If no conflicts occurs then you can push the merge.
git push
However, if there are some conflicts you have to solve them and continue :
git merge --continue
Or you can abort the merge :
git merge --abort
Interactive rebase
The interactive rebase is very useful when you want to go through old commits and apply changes. It allows you to do many things. I am not comfortable with all of them, so I will only talk about the things I use at work.
When you start an interactive rebase you have to decide how many commits you want to display. For our example we will chose to display the 4 latest commits.
git rebase -i HEAD~4
Now the vim editor will open up with your list of four commits looking like this.
pick c78fde8 first commit
pick 3044c00 second commit
pick 49f13d0 third commit
pick a1bf1c0 fourth commit
Let us see what we can do with this interactive rebase.
Change the order of commits
You can change the order of the commits by simply changing them in the vim window. If you want to put the third commit before the second you can.
Changing the order of commits can be useful for the fusion of commits because you can fusion a commit with the one before. So you cant fusion commit 1 with commit 3, you have to move commit 3 under commit 1 to then fusion with it.
pick c78fde8 first commit
pick 49f13d0 third commit
pick 3044c00 second commit
pick a1bf1c0 fourth commit
Now save and quit. And push force to change your git history.
git push -f
Be careful when you change the order of commits. You can create conflicts if the modifications of the commits reordered touch the same files, for example.
Edit an old commit
You might want to edit a commit that is not the latest. Here you also need to go through the interactive rebase. Let us still use the list of four commits that we have as an base example.
Let us try to modify the second commit with the number 3044c00. As you can see there is a key word pick in front of every commit. If you want to edit a commit then change pick by edit and save.
pick c78fde8 first commit
edit 3044c00 second commit
pick 49f13d0 third commit
pick a1bf1c0 fourth commit
Now your repository is pointing on this commit. You can open your IDE and make all the changes you want. Once you did you can run :
git add .
git commit --amend
Change the name of the commit if you want, or keep it how it is and save. Then run :
git rebase --continue
git push -f
Fusion multiple commits
Another action that you might want to do is to fusion multiple commits together. To do so, you have two options: squash or fixup. If you use squash it with fusion the commit messages toghether, and with fixup it will keep the previous commit log’s message.
pick c78fde8 first commit
pick 3044c00 second commit
squash 49f13d0 third commit
pick a1bf1c0 fourth commit
A new window will open with the 2 messages of the commits you want to squash together. Change the name of the commit if you want one clean commit message and save. Then run :
git push -f
Automate the fusion
You might want to automate the fusion of your commits instead of having to go through the list of all the commits. There is a very useful option for that.
Isolate the id of the commit where you want to add your current modification. Then when you commit your modification, you can choose either the option squash or fixup with the id of the commit. Then run the rebase with the option autosquash for both squash or fixup. This will save you some time.
git commit --squash=idcommit
git commit --fixup=idcommit
git rebase -i HEAD~4 --autosquash
Find a bug with git bisect
Finding an old bug can be tricky and take some time. However the command git bisect can help you isolate the bad commit faster. You will need to give it the id of the commit where you know there is no bug. And then start it on the interval of this good commit and your HEAD with the commit.
git bisect start HEAD c78fde8
Here the bisect will cut the number of commits in two, and start on the second half. You will be able to test the current commit and then run either good if there is no bug :
git bisect good
Or bad if there is one.
git bisect bad
If you are not sure use :
git bisect skip
Depending on your answers good and bad, it will continue to roll a list of commits until it will give you the number of the first commit containing the bug. Nice right?!
If you want to quit the bisect you can use :
git bisect reset
BONUS : presentation of multi-gitter
Multi-gitter is a productivity and quality of life tool that ease interactions with a large pool of git repositories. This tool supports natively GitHub and GitLab.
My team and I were able to use it in two distinct ways:
- Code monitoring to parse and then centralize gathered information from many repositories.
- Code Maintenance to apply scripted code changes massively on 200+ repositories.
Project homepage: https://github.com/lindell/multi-gitter
Example
Bump to PHP 7.4 script in jq (script.sh)
#!/usr/bin/env zsh
function di() { detect-indent "$1" | wc -c | xargs }
jq --indent $(di composer.json) '.require.php = "=7.4"' composer.json | sponge composer.json
jq --indent $(di composer.json) '.require.composer = "2.2.*"' composer.json | sponge composer.json
jq --indent $(di composer.json) '.devDependencies.puppeteer = "^10.0.0"' package.json | sponge package.json
Config file (config.yaml)
GITHUB_TOKEN: "ghp_xxxxx"
GILAB_TOKEN: "xxxxx"
reviewer:
- "Organization/teamA"
assignee:
- "Organization/teamA"
branch: bump-php-7.4
concurrent: 5
draft: false
dry-run: false
pr-title: >-
feat: massive bump php 7.4
repo:
- Organization/client-3
- Organization/client-2
- Organization/client-1
Execution
multi-gitter run "zsh $PWD/script.sh" --config config.yml --token=ghp_xxxx
Hope I could help!
4 thoughts on “Git cheatsheet”
Comments are closed.