git init
Git provides a clone
subcommand that copies the whole history of a repository locally
git clone URI destination
creates the folder destination
and clones the repository found at URI
destination
is not empty, failsdestination
is omitted, a folder with the same namen of the last segment of URI
is createdURI
can be remote or local, Git supports the file://
, https://
, and ssh
protocols
ssh
recommended when availableclone
subcommand checks out the remote branch where the HEAD
is attached (default branch)Examples:
git clone /some/repository/on/my/file/system destination
destination
and copies the repository from the local directorygit clone https://somewebsite.com/someRepository.git myfolder
myfolder
and copies the repository located at the specified URL
git clone user@sshserver.com:SomePath/SomeRepo.git
SomeRepo
and copies the repository located at the specified URL
init
, no remote is known.clone
, a remote called origin
is created automaticallyNon-local branches can be referenced as remoteName/branchName
The remote
subcommand is used to inspect and manage remotes:
git remote -v
lists the known remotes
git remote add a-remote URI
adds a new remote named a-remote
and pointing to URI
git remote show a-remote
displays extended information on a-remote
git remote remove a-remote
removes a-remote
(it does not delete information on the remote, it locally forgets that it exits)
Remote branches can be associated with local branches, with the intended meaning that the local and the remote branch are intended to be two copies of the same branch
git branch --set-upstream-to=remote/branchName
git branch --set-upstream-to=origin/develop
sets the current branch upstream to origin/develop
clone
, its default branch is checked out locally with the same name it has on the remote, and the remote branch is automatically set as upstreamgit clone git@somesite.com/repo.git
git@somesite.com/repo.git
is saved as origin
HEAD
is attached, in our case master
) on origin
gets checked out locally with the same namemaster
is set up to track origin/master
as upstreamgit branch -a
git log --oneline --graph --all
git branch
(or git checkout -b
) can checkout remote branches locally once they have been fetched.
➡️ git checkout -b imported-feat origin/feat/serverless
➡️
⬇️ git checkout -b imported-feat origin/feat/serverless
⬇️
imported-feat
is created locally, and origin/feat/serverless
is set as its upstreamgit checkout -b feat/new-client origin/feat/new-client
git checkout feat/new-client
feat/new-client
with the upstream branch set to origin/feat/new-client
if:
feat/new-client
➡️ Next: git clone git@somesite.com/repo.git
➡️
⬇️ git clone git@somesite.com/repo.git
⬇️
➡️ Next: git checkout -b feat/serverless origin/feat/serverless
➡️
⬇️ git checkout -b feat/serverless origin/feat/serverless
⬇️
➡️ Next: git remote add other git@somewhereelse.org/repo.git
➡️
⬇️ git remote add other git@somewhereelse.org/repo.git
⬇️
➡️ Next: git checkout -b other-master other/master
➡️
⬇️ git checkout -b other-master other/master
⬇️
You can operate with multiple remotes! Just remember: branch names must be unique for every repository
origin/master
and anotherRemote/master
, you need two local branches with diverse namesTo check if a remote has any update available, git provides th git fetch
subcommand.
git fetch a-remote
checks if a-remote
has any new information. If so, it downloads it.
git fetch
without a remote:
HEAD
is attached and the current branch has an upstream, then the remote that is hosting the upstream branch is fetchedorigin
is fetched, if presentmerge
The new information fetched includes new commits, branches, and tags.
After a fetch
, the status of the remote repositories is updated, and can be inspected using:
git branch -a
for branches (to discover, e.g., new branches)git log --oneline --graph --all
to visualize the history of all the known clones of the repository➡️ Next: Changes happen on somesite.com/repo.git
and on our repository concurrently ➡️
⬇️ Changes happen on somesite.com/repo.git
and on our repository concurrently ⬇️
➡️ git fetch && git merge origin/master
(assuming no conflicts or conflicts resolved) ➡️
⬇️ git fetch && git merge origin/master
(assuming no conflicts or conflicts resolved) ⬇️
If there had been no updates locally, we would have experienced a fast-forward
git pull
Fetching the remote with the upstream branch and then merging is extremely common, so common that there is a special subcommand that operates.
git pull
is equivalent to git fetch && git merge FETCH_HEAD
git pull remote
is the same as git fetch remote && git merge FETCH_HEAD
git pull remote branch
is the same as git fetch remote && git merge remote/branch
git pull
is more commonly used than git fetch
+ git merge
,
still, it is important to understand that it is not a primitive operation
Git provides a way to send changes to a remote: git push remote branch
remote/branch
, and updates the remote HEAD
-u
or --set-upstream-to
git push -u myremote myremotebranch
sets the upstream branch of the current branch to myremote/myremotebranch
push
requires writing rights to the remote repositorypush
fails if the pushed branch is not a descendant of the destination branch, which means:
By default, git push
does not send tags
git push --tags
sends only the tagsgit push --follow-tags
sends commits and then tags➡️ Next: [some changes] git add . && git commit
➡️
⬇️ [some changes] git add . && git commit
⬇️
➡️ Next: git push
➡️
⬇️ git push
⬇️
origin/master
was a subset of master
HEAD
can be fast-forwarded➡️ Next: someone else pushes a change ➡️
⬇️ someone else pushes a change ⬇️
➡️ Next: [some changes] git add . && git commit
➡️
⬇️ [some changes] git add . && git commit
⬇️
➡️ Next: git push
➡️
⬇️ git push
⬇️
ERROR
To somesite.com/repo.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'somesite.com/repo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
master
is not a superset of origin/master
10
is in origin/master
but not in master
, preventing a remote fast-forward➡️ Next: git pull
➡️
⬇️ git pull
(assuming no merge conflicts, or after conflict resolution) ⬇️
master
is a superset of origin/master
! (all the commits in origin/master
, plus 11
and 12
)➡️ Next: git push
➡️
⬇️ git push
⬇️
The push suceeds now!
Several services allow the creation of shared repositories on the cloud. They enrich the base git model with services built around the tool:
repositories are uniquely identified by an owner and a repository name
owner/repo
is a name unique to every repositorysupports two kind of authentications:
repo
access scope at https://github.com/settings/tokens/newhttps://github.com/owner/repo.git
becomes: https://token@github.com/owner/repo.git
Disclaimer: this is a “quick and dirty” way of generating and using SSH keys.
You are warmly recommended to learn how it works and the best security practices.
ssh-keygen
cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3Nza<snip, a lot of seemingly random chars>PIl+qZfZ9+M= you@your_hostname
You are all set! Enjoy your secure authentication.