Overview
Teaching: 10 min
Exercises: 20 minQuestionsObjectives
- How to contribute to centralized Git repositories?
- Understand the difference between local branch, origin/branch, and remote branch.
In this exercise, we practice collaborative centralized workflow:
First, we all clone (make a local copy) and try to push (send code to) the main repository. We’ll see a small problem with that, and then make a pull request (sending code so that others can review and accept later). We’ll discuss how this leads to code review and discuss a number of typical pitfalls.
$ git clone git@github.com:comp-sci-tools/centralized-workflow-exercise.git centralized-workflow-exercise
Note: set up ssh keys:
This is a representation of what happens when you clone:
remote:
local:
git clone
creates pointers origin/master
and origin/experiment
.origin
refers to where we cloned from, try: git remote -v
.origin
is a shortcut for the full URL.origin/master
and origin/experiment
are read-only pointers.git pull
or git fetch
or git push
.git pull
or git fetch
or git push
require network.$ cd centralized-workflow-exercise
yourusername.txt
In this file share your favourite cooking recipe or haiku or Git trick or whatever.
$ git add yourusername.txt
$ git commit
remote:
local:
$ git push origin master
By “upstream” we mean here the repository which we have cloned. Imagine “upstream” being closer to the main development and your local clone to be “downstream”.
You probably see something like this:
$ git push
To https://github.com/user/repo.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/user/repo.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again. See the
'Note about fast-forwards' section of 'git push --help' for details.
The push only worked for one participant. Why?
remote:
local:
The natural reflex is now to git pull
first but
what happens if we git pull origin master
?
$ git pull origin master
remote:
local:
Ideas? What happened under the hood?
We did:
$ git pull origin master
which is equivalent to:
$ git fetch origin
$ git merge origin/master
git pull
consists of two operations: a git fetch
followed by a git merge
.git pull origin master
fetches master
from origin
and merges it.git merge
“hidden” in git pull
.git pull
, very careful people first git fetch
and inspect the commits before merging them.An alternative:
$ git pull --rebase origin master
would have produced:
remote:
local:
It will work for one more person.
yourname/somefeature
pointing at your commitFirst find out the hash of your commit. You can do this using git graph
or git log
:
$ git log yourusername.txt
Then create a branch “in the past” pointing to that hash:
$ git branch yourname/somefeature [hash]
The yourname/
prefix has no special meaning: it is just part of a
branch name to indicate who made it (we discussed branch naming before).
$ git push origin -u yourname/somefeature
Can we leave out the -u
(-u
is equivalent to --set-upstream
)?
Submit a pull request from your branch towards the master
branch.
Do this through the web interface.
Create a local branch somefeature
tracking origin/somefeature
:
$ git checkout -b somefeature origin/somefeature
If there is no local branch somefeature
and there is a remote branch origin/somefeature
, then this is enough:
$ git checkout somefeature
Once we track a remote branch, we can pull from it and push to it:
$ git pull origin somefeature
$ git push origin somefeature
We can also delete remote branches:
$ git push origin --delete somefeature
master
branch.Key Points
You communicate commits with
git fetch
/git pull
andgit push
(these are the only Git operations done online).
origin
refers to where you cloned from (but you can relocate it).
origin/foo
is a read-only pointer to branchfoo
on origin.
origin
pointers only move when yougit fetch
/git pull
orgit push
.