Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
Git cheat sheet¶
Cloning a repository¶
When you clone a repository from GitLab or GitHub, the git clone
command
adds a remote named “origin”, pulls down all Git data, creates a pointer named
origin/master to the remote’s master branch, and a pointer master to your
own local master branch, starting at the same place as origin’s master branch.
For some repositories you must replace “master” by “main” in above paragraph. See Rename “master” to “main” in our repositories.
Branching¶
My summary after reading the Branching chapter of Scott Chacon’s Pro Git book:
master : the default branch that will be selected after cloning your repo. The name is purely conventional and has no special meaning for Git itself. In 2021 it was changed to “main”.
HEAD : pointer to the “current branch” (the one that is checked out).
Create a new branch called “20141022”:
git branch 20141022
Select a branch :
git checkout 20141022
Shortcut to create and select :
git checkout -b 20141022
Starting and selecting a branch will not modify your local modifications.
List all branches:
git branch
See which branches are already merged into HEAD :
git branch --merged
See all the branches that contain work you haven’t yet merged :
git branch --merged
Merge a branch into current branch:
git merge 20141022
In case of a merge conflict, start reading at Basic Merge Conflicts
Delete a branch:
git branch -d 20141022
Common names for long-term branches: develop, proposed, next.
Remote branches¶
When you want to share a branch with the world, you need to push it to a remote to which you have write access. For example:
$ git checkout -b myfeature # create a local branch
$ git push origin myfeature # make it public
$ # ... add files and commit changes
Remote branches :
(remote)/(branch)
Pull vs fetch
When pulling such a remote branch, keep in mind the subtle difference between
git pull
and git fetch
, where the following command:
$ git pull origin myfeature
will pull the content of the remote branch and merge it with the current local branch. On the other hand, the following command:
$ git fetch origin myfeature
will pull the content of the remote branch but will NOT merge it with the current branch. In such a case it is safer to use the later command.
Later the user can safely checkout the content of the fetched branch by using the following command:
$ git checkout myfeature
TODO: Continue to read https://git-scm.com/book/en/Git-Branching-Remote-Branches
Multiple remotes¶
A use case for multiple remotes may arise in scenarios such as when a user needs to manage a personal copy of some repository or where the user does not have write access to the original repository.
In such a case the user may make a fork of the original repository using the git hosted frontend.
Let’s take our lino repository as an example where I as user on gitlab having the username 8lurry shell make a fork and will modify the code base for my personal use case while keeping my fork up-to-date with the original repository from lino-framework.
I make a fork of the repository lino from the webinterface https://gitlab.com/lino-framework/lino (remote name: upstream), where the forked repository is pointed to by https://gitlab.com/8lurry/lino (remote name: origin).
In the following section I will show how I keep my remote origin up-to-date with the remote upstream while having my personal modification on it as well and for simplicity we assume that we only work on branches from different ref pointer named only master.
I open up a terminal window on my personal computer and do the following:
Clone my remote origin repository:
$ git clone git@gitlab.com:8lurry/lino.git
Any further instructions below will be done within the lino directory. So, I cd into lino:
$ cd lino
I set the remote upstream to my local repository:
$ git remote add upstream git@gitlab.com:lino-framework/lino.git
From time to time when I need to update my local repository from the upstream I do:
$ git pull upstream master
See pull vs fetch to understand what the above command does. Also while the above command gets the changes from the upstream it still keeps my personal modifications intact.
In case of a merge conflict arise I refer to resolve guide
To make the updates available at my remote origin I do:
$ git push
Git basics
When I do some modifications to my local repository I add the changes to the git HEAD by calling:
$ git add -u
After reviewing more I confirm my changes while giving it my_message about the changes:
$ git commit -m "my_message"
I publish my changes to the remote origin by calling:
$ git push
In case (somebody from the so called upstream remote asks you to or) you by yourself need to make your changes contained in the remote origin available to the remote upstream (while you don’t have write permission to the upstream) you can make a pull request by following the instructions given here
Make a pull request¶
Contributing pull requests to foreign projects¶
Most projects don’t use the “shared repository model” (several users writing to a repo) but the “fork & pull” model as explained in Using pull requests).
Example: I have a fork of Ahmet’s ablog project. Ahmet made changes in ablog and asked me to test them. So I need to merge his changes into the local copy of my fork.
So if I want to contribute to Ahmet’s ablog project, I need to fork the project on GitHub (using their web interface) and then get a clone of this fork:
$ git clone git@github.com:lsaffre/ablog.git
Now I make my changes:
$ e ablog/__init__.py
When I decided that I want to share my local changes, I create a branch, commit it and push it to my repo:
$ git checkout -b feed_encoding
$ git add -u
$ git commit -m "Added encoding utf-8 to file atom.xml"
$ git push origin feed_encoding
Now their web interface sees my branch and allows me to turn it into a pull request.
Merge from upstream¶
Every local project repository has a set of tracked repositories, also called “remotes”. The default remote (the place from where my local repo has been taken) is called origin.
List all remotes:
$ git remote -v
origin git@github.com:lsaffre/ablog.git (fetch)
origin git@github.com:lsaffre/ablog.git (push)
First I must add Ahmet’s repo as a new remote, which is usually called upstream:
$ git remote add upstream git@github.com:abakan/ablog.git
My local repo now has two remotes:
$ git remote -v
origin git@github.com:lsaffre/ablog.git (fetch)
origin git@github.com:lsaffre/ablog.git (push)
upstream git@github.com:abakan/ablog.git (fetch)
upstream git@github.com:abakan/ablog.git (push)
Now I can fetch all changes from the upstream repository:
$ git fetch upstream
Before continuing, make sure where you want the changes from upstream to go. Usually you want them to go to master, so you must select this branch:
$ git checkout master
And finally I can merge them into my local repo:
$ git merge upstream/master
fetch upstream looks up the specified remote, fetches any data from
it that you don’t yet have, and updates your local database, moving
your upstream/master
pointer to its new position.
How to update the most recent commit message¶
You can rewrite the most recent commit message with amend
:
$ git commit --amend -m "new commit message"
This will change the commit id, i.e. actually you are creating a new commit that replaces the old one.
TODO:
How to return back to my local changes?
What was this?
$ git pull upstream master
Merge from upstream while local branch active¶
I had started a branch in my local copy of ablog:
$ git status
On branch trans_estonian
nothing to commit, working directory clean
$ git push origin trans_estonian
Everything up-to-date
Accept a pull request¶
Example: cuchac posted a pull request for a branch which he named
export_excel_datetime
(on his fork of project lino).
Check that there are no local changes in my repo:
$ go lino
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
Check out his branch into a new branch inbox
in order to test the
changes:
$ git checkout -b inbox master
$ git pull git@github.com:cuchac/lino.git export_excel_datetime
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 4), reused 5 (delta 3)
Unpacking objects: 100% (6/6), done.
From github.com:cuchac/lino
* branch export_excel_datetime -> FETCH_HEAD
Merge made by the 'recursive' strategy.
lino/modlib/export_excel/models.py | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
Test the changes:
$ inv test
[localhost] local: python setup.py -q test
...........................................
----------------------------------------------------------------------
Ran 43 tests in 36.290s
OK
Done.
Reactivate master and merge the changes:
$ git checkout master
M docs/tutorials/pisa/pisa.Person-1.pdf
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git merge --no-ff inbox
Merge made by the 'recursive' strategy.
lino/modlib/export_excel/models.py | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
Note: is the --no-ff
option necessary?
Push everything to the master:
$ git push origin master
Counting objects: 43, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 1.39 KiB | 0 bytes/s, done.
Total 11 (delta 8), reused 0 (delta 0)
To git@github.com:lsaffre/lino.git
988adf9..55961b9 master -> master
And finally delete the inbox
branch:
$ git branch -v --merged
inbox bfd3f39 Merge branch 'export_excel_datetime' of github.com:cuchac/lino into inbox
* master 55961b9 Merge branch 'inbox'
$ git branch -d inbox
Deleted branch inbox (was bfd3f39).
How to fetch a remote pull request¶
git fetch origin pull/999/head:my-branch
git checkout my-branch
Where 999
is the number of the pull request and my-branch
the name of
the branch.