git initGit 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 URLgit clone user@sshserver.com:SomePath/SomeRepo.git
SomeRepo and copies the repository located at the specified URLinit, 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/developclone, 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.gitgit@somesite.com/repo.git is saved as originHEAD 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 -agit log --oneline --graph --allgit 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-clientgit checkout feat/new-clientfeat/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 presentmergeThe 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 pullFetching 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_HEADgit pull remote branch is the same as git fetch remote && git merge remote/branchgit 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/myremotebranchpush 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 masterHEAD 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.gitDisclaimer: 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-keygencat ~/.ssh/id_rsa.pub
cat cat ~/.ssh/id_ed25519.pubssh-rsa AAAAB3Nza<snip, a lot of seemingly random chars>PIl+qZfZ9+M= you@your_hostname
You are all set! Enjoy your secure authentication.