Clone, push, pull and fetch
30 min · Beginner
Need help? Ask a tutor on WhatsApp (opens in a new tab)Showing steps for Windows. They are marked “On Windows” below.
When two people work on one GitHub repository, each laptop has its own copy. Clone gets the copy, push sends your commits up, fetch checks what is new on GitHub, and pull brings it into your work.
Clone: get the project on another laptop
Cloning means making a full copy of a remote repository on your computer with git clone: every file, every commit and every branch, with origin already set to the address you cloned from.
Priya adds her friend Rahul to shop-bill (repository Settings → Collaborators → Add people). On his own laptop, Rahul runs git clone with the address from the green Code button.
Example 1 · Rahul clones the repository
Runs in: Your terminal
PS C:\Users\Rahul> git clone https://github.com/priya-dev/shop-bill.gitCloning into 'shop-bill'... remote: Enumerating objects: 6, done. remote: Counting objects: 100% (6/6), done. remote: Compressing objects: 100% (4/4), done. remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) Receiving objects: 100% (6/6), done.
What this code does
git clonemade a new foldershop-billinC:\Users\Rahuland downloaded both of Priya's commits, not just the files.- It also saved the address as
origin, so Rahul can push and pull at once. Next he runscd shop-bill. - Download ZIP on the same Code menu gives only the files: no history and no
origin. To work with Git, clone.
origin/main: your laptop's memory of GitHub
An upstream branch, also called a tracking branch, is the remote branch your local branch is linked to, such as origin/main for main. git status compares your branch with it, and a plain git push or git pull uses it.
After a clone or a first push, your laptop keeps origin/main: a saved copy of where main was on GitHub. It moves only when you push, fetch or pull. git status compares your main with it.
On Windows
Rahul adds a ruler line to bill.txt, commits it and checks the status before he pushes:
PS C:\Users\Rahul\shop-bill> git commit -am "Add ruler to the bill"PS C:\Users\Rahul\shop-bill> git statusPS C:\Users\Rahul\shop-bill> git pushOutput[main 7f68bfe] Add ruler to the bill 1 file changed, 2 insertions(+), 1 deletion(-) On branch main Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working tree clean Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 12 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 370 bytes | 12.00 KiB/s, done. Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0) To https://github.com/priya-dev/shop-bill.git 8e83356..7f68bfe main -> main
git commit -amadds and commits every file Git already tracks, in one step.ahead of 'origin/main' by 1 commit: the commit is only on Rahul's laptop, so Git reminds him to push.8e83356..7f68bfe main -> main: GitHub'smainmoved from the old commit to Rahul's new one.
Fetch: see what is new
Fetch means downloading new commits from a remote without changing your own branches or files. git fetch only moves the remote-tracking branches, such as origin/main, so you can look before you merge.
Priya's origin/main is from before Rahul's push, so her git status still says "up to date". git fetch updates origin/main; then git status tells the truth.
Example 2 · git status is old news until you fetch
Runs in: Your terminal
PS C:\Users\Priya\shop-bill> git statusPS C:\Users\Priya\shop-bill> git fetchPS C:\Users\Priya\shop-bill> git statusOutputOn branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean remote: Enumerating objects: 5, done. remote: Counting objects: 100% (5/5), done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0) From https://github.com/priya-dev/shop-bill 8e83356..7f68bfe main -> origin/main On branch main Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch) nothing to commit, working tree clean
What this code does
- The first
git statussays "up to date" because it compared with theorigin/mainsaved before Rahul pushed. git fetchmovedorigin/mainfrom8e83356to7f68bfe. Priya'smainand her files did not change.behind ... by 1 commit, and can be fast-forwarded: one new commit is waiting to be pulled.
Pull = fetch + merge
Pull means fetching new commits from the remote and merging them into your current branch in one step. git pull is git fetch followed by a merge of the upstream branch, such as origin/main.
Fetch only looks. To bring Rahul's commit into her main and her files, Priya runs git pull, then prints the file to check it.
On Windows
In PowerShell, in her shop-bill folder:
PS C:\Users\Priya\shop-bill> git pullPS C:\Users\Priya\shop-bill> cat bill.txtOutputUpdating 8e83356..7f68bfe Fast-forward bill.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) Notebook x 2: Rs. 30 Pen x 3: Rs. 36 Ruler x 1: Rs. 20 Total to pay: Rs. 86
Fast-forward: Priya had no new commits of her own, so Git just movedmainforward to Rahul's commit. No merge commit was needed.bill.txt | 3 ++-is the changed file: 2 lines added, 1 removed.- The file now has Rahul's ruler line: her files match GitHub.
As in Merging branches (opens in a new tab), a pull fast-forwards when only GitHub moved, and makes a merge commit when both sides have new commits. Pull before you start work each day.
Rejected push: pull first
While Priya changed the total line, Rahul pushed a README. GitHub now has a commit Priya does not have, so it refuses her push instead of losing his work.
On Windows
Priya commits "Say total to pay" and pushes:
PS C:\Users\Priya\shop-bill> git pushTo https://github.com/priya-dev/shop-bill.git ! [rejected] main -> main (fetch first) error: failed to push some refs to 'https://github.com/priya-dev/shop-bill.git' hint: Updates were rejected because the remote contains work that you do not hint: have locally. This is usually caused by another repository pushing to hint: the same ref. If you want to integrate the remote changes, use hint: 'git pull' before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
! [rejected] ... (fetch first): GitHub has work that Priya does not have yet.- Nothing is lost: her commit is safe on her laptop, and Rahul's is safe on GitHub.
Example 3 · A rejected push, fixed with pull
Runs in: Your terminal
PS C:\Users\Priya\shop-bill> git pullPS C:\Users\Priya\shop-bill> git pushOutputremote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) From https://github.com/priya-dev/shop-bill 7f68bfe..a5899b1 main -> origin/main Merge made by the 'ort' strategy. README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md Enumerating objects: 9, done. Counting objects: 100% (8/8), done. Delta compression using up to 12 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 626 bytes | 313.00 KiB/s, done. Total 5 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0) To https://github.com/priya-dev/shop-bill.git a5899b1..cd41cfd main -> main
What this code does
git pullfetched Rahul's README commit and merged it with Priya's commit (Merge made by the 'ort' strategy). A text editor opens for the merge message first: keep it, save and close.- Git for Windows already chose "merge" as the way
git pulljoins two histories, so there is no question to answer. - Now GitHub has every commit Priya has, so
git pushis accepted.
If both changed the same lines, the pull stops with a merge conflict: fix it as in Merge conflicts (opens in a new tab), then git add, git commit and git push. Never fix a rejected push with git push --force: it replaces GitHub's branch with yours and deletes your teammate's commits.
Next step
Check your understanding
9 quick questions